Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » web » tomcat » tc4 » authenticator » [javadoc | source]
    1   /*
    2    * JBoss, the OpenSource WebOS
    3    *
    4    * Distributable under LGPL license.
    5    * See terms of license at gnu.org.
    6    *
    7    * This software is derived from works developed by the
    8    * Apache Software Foundation (http://www.apache.org/), and its
    9    * redistribution and use are further subject to the terms of the
   10    * Apache Software License (see below), which is herein incorporated
   11    * by reference.
   12    *
   13    * ====================================================================
   14    *
   15    * The Apache Software License, Version 1.1
   16    *
   17    * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   18    * reserved.
   19    *
   20    * Redistribution and use in source and binary forms, with or without
   21    * modification, are permitted provided that the following conditions
   22    * are met:
   23    *
   24    * 1. Redistributions of source code must retain the above copyright
   25    *    notice, this list of conditions and the following disclaimer.
   26    *
   27    * 2. Redistributions in binary form must reproduce the above copyright
   28    *    notice, this list of conditions and the following disclaimer in
   29    *    the documentation and/or other materials provided with the
   30    *    distribution.
   31    *
   32    * 3. The end-user documentation included with the redistribution, if
   33    *    any, must include the following acknowlegement:
   34    *       "This product includes software developed by the
   35    *        Apache Software Foundation (http://www.apache.org/)."
   36    *    Alternately, this acknowlegement may appear in the software itself,
   37    *    if and wherever such third-party acknowlegements normally appear.
   38    *
   39    * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   40    *    Foundation" must not be used to endorse or promote products derived
   41    *    from this software without prior written permission. For written
   42    *    permission, please contact apache@apache.org.
   43    *
   44    * 5. Products derived from this software may not be called "Apache"
   45    *    nor may "Apache" appear in their names without prior written
   46    *    permission of the Apache Group.
   47    *
   48    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   49    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   50    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   51    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   52    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   53    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   54    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   55    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   56    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   57    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   58    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   59    * SUCH DAMAGE.
   60    * ====================================================================
   61    *
   62    * This software consists of voluntary contributions made by many
   63    * individuals on behalf of the Apache Software Foundation.  For more
   64    * information on the Apache Software Foundation, please see
   65    * <http://www.apache.org/>.
   66    *
   67    * [Additional notices, if required by prior licensing conditions]
   68    *
   69    */
   70   package org.jboss.web.tomcat.tc4.authenticator;
   71   
   72   
   73   import java.lang.reflect.Method;
   74   import java.security.Principal;
   75   
   76   import javax.servlet.http.Cookie;
   77   import javax.servlet.http.HttpServletResponse;
   78   
   79   import org.apache.catalina.Container;
   80   import org.apache.catalina.HttpRequest;
   81   import org.apache.catalina.HttpResponse;
   82   import org.apache.catalina.LifecycleException;
   83   import org.apache.catalina.Pipeline;
   84   import org.apache.catalina.Realm;
   85   import org.apache.catalina.Session;
   86   import org.apache.catalina.Valve;
   87   import org.apache.catalina.authenticator.Constants;
   88   
   89   
   90   /**
   91    * Overrides the superclass version by using class
   92    * <code>org.jboss.web.tomcat.tc4.authenticator.SingleSignOn</code> instead
   93    * of <code>org.apache.catalina.authenticator.SingleSignOn</code> as its
   94    * method expected single sign-on valve.  This class also differs from
   95    * the standard Tomcat version in its implementation of method
   96    * {@link #register reqister}.
   97    * <p>
   98    * Basic implementation of the <b>Valve</b> interface that enforces the
   99    * <code>&lt;security-constraint&gt;</code> elements in the web application
  100    * deployment descriptor.  This functionality is implemented as a Valve
  101    * so that it can be ommitted in environments that do not require these
  102    * features.  Individual implementations of each supported authentication
  103    * method can subclass this base class as required.
  104    * <p>
  105    * <b>USAGE CONSTRAINT</b>:  When this class is utilized, the Context to
  106    * which it is attached (or a parent Container in a hierarchy) must have an
  107    * associated Realm that can be used for authenticating users and enumerating
  108    * the roles to which they have been assigned.
  109    * <p>
  110    * <b>USAGE CONSTRAINT</b>:  This Valve is only useful when processing HTTP
  111    * requests.  Requests of any other type will simply be passed through.
  112    *
  113    * @see #register
  114    * @see SingleSignOn
  115    * @see org.apache.catalina.authenticator.AuthenticatorBase
  116    *
  117    * @author B Stansberry, based on the work of Craig R. McClanahan
  118    * @version $Revision: 1.1.2.1 $ $Date: 2003/11/22 08:12:44 $
  119    */
  120   public abstract class AuthenticatorBase
  121         extends org.apache.catalina.authenticator.AuthenticatorBase
  122   {
  123   
  124   
  125      // ----------------------------------------------------- Instance Variables
  126   
  127   
  128      /**
  129       * Descriptive information about this implementation.
  130       */
  131      protected static final String info =
  132            AuthenticatorBase.class.getName() + "/1.0";
  133   
  134      /**
  135       * The SingleSignOn implementation in our request processing chain,
  136       * if there is one.
  137       * <p>
  138       * <b>NOTE:</b> This is an instance of
  139       * <code>org.jboss.web.tomcat.tc4.authenticator.SingleSignOn</code>,
  140       * not <code>org.apache.catalina.authenticator.SingleSignOn</code>.
  141       *
  142       */
  143      protected SingleSignOn ourSSO = null;
  144   
  145   
  146      // ------------------------------------------------------------- Properties
  147   
  148   
  149      // --------------------------------------------------------- Public Methods
  150   
  151   
  152      // ------------------------------------------------------ Protected Methods
  153   
  154   
  155   
  156      /**
  157       * Associate the specified single sign on identifier with the
  158       * specified Session.
  159       * <p>
  160       * <b>IMPLEMENTATION NOTE:</b> Overrides the superclass version solely by
  161       * using a <code>org.jboss.web.tomcat.tc4.authenticator.SingleSignOn</code>
  162       * instead of an <code>org.apache.catalina.authenticator.SingleSignOn</code>
  163       *
  164       * @param ssoId Single sign on identifier
  165       * @param session Session to be associated
  166       */
  167      protected void associate(String ssoId, Session session)
  168      {
  169   
  170         if (ourSSO == null)
  171            return;
  172         ourSSO.associate(ssoId, session);
  173   
  174      }
  175   
  176   
  177      /**
  178       * Attempts reauthentication to the <code>Realm</code> using
  179       * the credentials included in argument <code>entry</code>.
  180       *
  181       * @param ssoId identifier of SingleSignOn session with which the
  182       *              caller is associated
  183       * @param request   the request that needs to be authenticated
  184       */
  185      protected boolean reauthenticateFromSSO(String ssoId, HttpRequest request)
  186      {
  187   
  188         if (ourSSO == null || ssoId == null)
  189            return false;
  190   
  191         boolean reauthenticated = false;
  192   
  193         SingleSignOnEntry entry = ourSSO.lookup(ssoId);
  194         if (entry != null && entry.getCanReauthenticate())
  195         {
  196            Principal reauthPrincipal = null;
  197            Container parent = getContainer();
  198            if (parent != null)
  199            {
  200               Realm realm = getContainer().getRealm();
  201               String username = entry.getUsername();
  202               if (realm != null && username != null)
  203               {
  204                  reauthPrincipal =
  205                        realm.authenticate(username, entry.getPassword());
  206               }
  207            }
  208   
  209            if (reauthPrincipal != null)
  210            {
  211               associate(ssoId, getSession(request, true));
  212               request.setAuthType(entry.getAuthType());
  213               request.setUserPrincipal(reauthPrincipal);
  214   
  215               reauthenticated = true;
  216               if (debug >= 1)
  217               {
  218                  log(" Reauthenticated cached principal '" +
  219                      entry.getPrincipal().getName() + "' with auth type '" +
  220                      entry.getAuthType() + "'");
  221               }
  222            }
  223         }
  224   
  225         return reauthenticated;
  226      }
  227   
  228   
  229      /**
  230       * Register an authenticated Principal and authentication type in our
  231       * request, in the current session (if there is one), and with our
  232       * SingleSignOn valve, if there is one.  Set the appropriate cookie
  233       * to be returned.
  234       * <p>
  235       * <b>IMPLEMENTATION NOTE:</b> Differs from the standard Tomcat
  236       * implementation in checking if any <code>SingleSignOn</code> valve
  237       * has added a note to the request.  If it has, it does not call
  238       * <code>SingleSignOn.register</code>, instead calling
  239       * <code>SingleSignOn.update</code>.  This behavior supports
  240       * authenticators like <code>SSLAuthenticator</code> that may attempt
  241       * to re-register with every request.
  242       *
  243       * @param request The servlet request we are processing
  244       * @param response The servlet response we are generating
  245       * @param principal The authenticated Principal to be registered
  246       * @param authType The authentication type to be registered
  247       * @param username Username used to authenticate (if any)
  248       * @param password Password used to authenticate (if any)
  249       */
  250      protected void register(HttpRequest request, HttpResponse response,
  251                              Principal principal, String authType,
  252                              String username, String password)
  253      {
  254   
  255         if (debug >= 1)
  256            log("Authenticated '" + principal.getName() + "' with type '" +
  257                authType + "'");
  258   
  259         // Cache the authentication information in our request
  260         request.setAuthType(authType);
  261         request.setUserPrincipal(principal);
  262   
  263         Session session = getSession(request, false);
  264         // Cache the authentication information in our session, if any
  265         if (cache)
  266         {
  267            if (session != null)
  268            {
  269               session.setAuthType(authType);
  270               session.setPrincipal(principal);
  271               if (username != null)
  272                  session.setNote(Constants.SESS_USERNAME_NOTE, username);
  273               else
  274                  session.removeNote(Constants.SESS_USERNAME_NOTE);
  275               if (password != null)
  276                  session.setNote(Constants.SESS_PASSWORD_NOTE, password);
  277               else
  278                  session.removeNote(Constants.SESS_PASSWORD_NOTE);
  279            }
  280         }
  281   
  282         // Construct a cookie to be returned to the client
  283         if (ourSSO == null)
  284            return;
  285   
  286         // Only create a new SSO entry if the SSO did not already set a note
  287         // for an existing entry (as it would do with subsequent requests
  288         // for DIGEST and SSL authenticated contexts)
  289         String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
  290         if (ssoId == null)
  291         {
  292            // Construct a cookie to be returned to the client
  293            HttpServletResponse hres =
  294                  (HttpServletResponse) response.getResponse();
  295            ssoId = generateSessionId();
  296            Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE, ssoId);
  297            cookie.setMaxAge(-1);
  298            cookie.setPath("/");
  299            hres.addCookie(cookie);
  300   
  301            // Register this principal with our SSO valve
  302            ourSSO.register(ssoId, principal, authType, username, password);
  303            request.setNote(Constants.REQ_SSOID_NOTE, ssoId);
  304   
  305         }
  306         else
  307         {
  308            // Update the SSO session with the latest authentication data
  309            ourSSO.update(ssoId, principal, authType, username, password);
  310         }
  311   
  312         // Fix for Tomcat Bug 10040
  313         // Always associate a session with a new SSO reqistration.
  314         // SSO entries are only removed from the SSO registry map when
  315         // associated sessions are destroyed; if a new SSO entry is created
  316         // above for this request and the user never revisits the context, the
  317         // SSO entry will never be cleared if we don't associate the session
  318         if (session == null)
  319            session = getSession(request, true);
  320         ourSSO.associate(ssoId, session);
  321   
  322      }
  323   
  324   
  325      // ------------------------------------------------------ Lifecycle Methods
  326   
  327   
  328      /**
  329       * Prepare for the beginning of active use of the public methods of this
  330       * component.  This method should be called after <code>configure()</code>,
  331       * and before any of the public methods of the component are utilized.
  332       * <p>
  333       * <b>IMPLEMENTATION NOTE:</b> Overrides the superclass version solely by
  334       * using a <code>org.jboss.web.tomcat.tc4.authenticator.SingleSignOn</code>
  335       * instead of an <code>org.apache.catalina.authenticator.SingleSignOn</code>
  336       *
  337       *
  338       * @exception LifecycleException if this component detects a fatal error
  339       *  that prevents this component from being used
  340       */
  341      public void start() throws LifecycleException
  342      {
  343   
  344         // Validate and update our current component state
  345         if (started)
  346         {
  347            throw new LifecycleException
  348                  (sm.getString("authenticator.alreadyStarted"));
  349         }
  350         lifecycle.fireLifecycleEvent(START_EVENT, null);
  351         if ("org.apache.catalina.core.StandardContext".equals
  352               (context.getClass().getName()))
  353         {
  354            try
  355            {
  356               Class paramTypes[] = new Class[0];
  357               Object paramValues[] = new Object[0];
  358               Method method =
  359                     context.getClass().getMethod("getDebug", paramTypes);
  360               Integer result = (Integer) method.invoke(context, paramValues);
  361               setDebug(result.intValue());
  362            }
  363            catch (Exception e)
  364            {
  365               log("Exception getting debug value", e);
  366            }
  367         }
  368         started = true;
  369   
  370         // Look up the SingleSignOn implementation in our request processing
  371         // path, if there is one
  372         Container parent = context.getParent();
  373         while ((ourSSO == null) && (parent != null))
  374         {
  375            if (!(parent instanceof Pipeline))
  376            {
  377               parent = parent.getParent();
  378               continue;
  379            }
  380            Valve valves[] = ((Pipeline) parent).getValves();
  381            for (int i = 0; i < valves.length; i++)
  382            {
  383               if (valves[i] instanceof SingleSignOn)
  384               {
  385                  ourSSO = (SingleSignOn) valves[i];
  386                  break;
  387               }
  388            }
  389            if (ourSSO == null)
  390               parent = parent.getParent();
  391         }
  392         if (debug >= 1)
  393         {
  394            if (ourSSO != null)
  395            {
  396               log("Found SingleSignOn Valve at " + ourSSO);
  397            }
  398            else
  399            {
  400               log("No SingleSignOn Valve is present");
  401            }
  402         }
  403   
  404      }
  405   
  406   
  407      /**
  408       * Gracefully terminate the active use of the public methods of this
  409       * component.  This method should be the last one called on a given
  410       * instance of this component.
  411       * <p>
  412       * <b>IMPLEMENTATION NOTE:</b> Overrides the superclass version solely by
  413       * using a <code>org.jboss.web.tomcat.tc4.authenticator.SingleSignOn</code>
  414       * instead of an <code>org.apache.catalina.authenticator.SingleSignOn</code>
  415       *
  416       * @exception LifecycleException if this component detects a fatal error
  417       *  that needs to be reported
  418       */
  419      public void stop() throws LifecycleException
  420      {
  421   
  422         // Validate and update our current component state
  423         if (!started)
  424         {
  425            throw new LifecycleException
  426                  (sm.getString("authenticator.notStarted"));
  427         }
  428         lifecycle.fireLifecycleEvent(STOP_EVENT, null);
  429         started = false;
  430   
  431         ourSSO = null;
  432   
  433      }
  434   
  435   
  436   }

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » web » tomcat » tc4 » authenticator » [javadoc | source]