Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » web » tomcat » security » [javadoc | source]
    1   /*
    2   * JBoss, Home of Professional Open Source
    3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
    4   * by the @authors tag. See the copyright.txt in the distribution for a
    5   * full listing of individual contributors.
    6   *
    7   * This is free software; you can redistribute it and/or modify it
    8   * under the terms of the GNU Lesser General Public License as
    9   * published by the Free Software Foundation; either version 2.1 of
   10   * the License, or (at your option) any later version.
   11   *
   12   * This software is distributed in the hope that it will be useful,
   13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15   * Lesser General Public License for more details.
   16   *
   17   * You should have received a copy of the GNU Lesser General Public
   18   * License along with this software; if not, write to the Free
   19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21   */
   22   package org.jboss.web.tomcat.security;
   23   
   24   import java.io.IOException;
   25   import java.security.Principal;
   26   
   27   import javax.naming.InitialContext;
   28   import javax.naming.NamingException;
   29   import javax.security.auth.Subject;
   30   import javax.servlet.ServletException;
   31   import javax.servlet.http.HttpSession;
   32   
   33   import org.apache.catalina.Manager;
   34   import org.apache.catalina.Session;
   35   import org.apache.catalina.Wrapper;
   36   import org.apache.catalina.connector.Request;
   37   import org.apache.catalina.connector.Response;
   38   import org.apache.catalina.valves.ValveBase;
   39   import org.jboss.logging.Logger;
   40   import org.jboss.metadata.javaee.jboss.RunAsIdentityMetaData;
   41   import org.jboss.metadata.web.jboss.JBossWebMetaData;
   42   import org.jboss.security.AuthenticationManager;
   43   import org.jboss.security.RunAsIdentity;
   44   import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
   45   
   46   /**
   47    * A Valve that sets/clears the SecurityAssociation information associated with
   48    * the request thread for identity propagation.
   49    *
   50    * @author Scott.Stark@jboss.org
   51    * @author Thomas.Diesler@jboss.org
   52    * @author Anil.Saldhana@jboss.org
   53    * @version $Revision: 67525 $
   54    */
   55   public class SecurityAssociationValve extends ValveBase
   56   {
   57      private static Logger log = Logger.getLogger(SecurityAssociationValve.class);
   58      public static ThreadLocal<Principal> userPrincipal = new ThreadLocal<Principal>();
   59      /** Maintain the active WebMetaData for request security checks */
   60      public static ThreadLocal<JBossWebMetaData> activeWebMetaData = new ThreadLocal<JBossWebMetaData>();
   61      /** Maintain the Catalina Request for programmatic web login */
   62      public static ThreadLocal<Request> activeRequest = new ThreadLocal<Request>();
   63      /** Maintain the Catalina Response for programmatic web login */
   64      public static ThreadLocal activeResponse = new ThreadLocal();
   65      
   66      /** The web app metadata */
   67      private JBossWebMetaData metaData;
   68      /** The name in the session under which the Subject is stored */
   69      private String subjectAttributeName = null;
   70      /** The service used to flush authentication cache on session invalidation. */
   71      private JaasSecurityManagerServiceMBean secMgrService;
   72      private boolean trace;  
   73   
   74      public SecurityAssociationValve(JBossWebMetaData metaData,
   75         JaasSecurityManagerServiceMBean secMgrService)
   76      {
   77         this.metaData = metaData;
   78         this.secMgrService = secMgrService;
   79         this.trace = log.isTraceEnabled();
   80      }
   81   
   82      /**
   83       * The name of the request attribute under with the authenticated JAAS
   84       * Subject is stored on successful authentication. If null or empty then
   85       * the Subject will not be stored.
   86       */
   87      public void setSubjectAttributeName(String subjectAttributeName)
   88      {
   89         this.subjectAttributeName = subjectAttributeName;
   90         if (subjectAttributeName != null && subjectAttributeName.length() == 0)
   91            this.subjectAttributeName = null;
   92      }
   93   
   94      public void invoke(Request request, Response response)
   95              throws IOException, ServletException
   96      {
   97         Session session = null;
   98         // Get the request caller which could be set due to SSO 
   99         Principal caller = request.getPrincipal();
  100         // The cached web container principal
  101         JBossGenericPrincipal principal = null;
  102         HttpSession hsession = request.getSession(false);
  103   
  104         if( trace )
  105            log.trace("Begin invoke, caller"+caller);
  106         // Set the active meta data
  107         activeWebMetaData.set(metaData); 
  108         //Set the active request and response objects
  109         activeRequest.set(request);
  110         activeResponse.set(response);
  111         
  112         try
  113         {
  114            Wrapper servlet = null;
  115            try
  116            {
  117               servlet = request.getWrapper();
  118               if (servlet != null)
  119               {
  120                  String name = servlet.getName();
  121                  RunAsIdentityMetaData identity = metaData.getRunAsIdentity(name);
  122                  RunAsIdentity runAsIdentity = null;
  123                  if(identity != null)
  124                  {
  125                     if (trace)
  126                        log.trace(name + ", runAs: " + identity);
  127                     runAsIdentity = new RunAsIdentity(identity.getRoleName(),
  128                           identity.getPrincipalName(), identity.getRunAsRoles());
  129                  }
  130                  SecurityAssociationActions.pushRunAsIdentity(runAsIdentity); 
  131               }
  132               userPrincipal.set(caller);
  133   
  134               // If there is a session, get the tomcat session for the principal
  135               Manager manager = container.getManager();
  136               if (manager != null && hsession != null)
  137               {
  138                  try
  139                  {
  140                     session = manager.findSession(hsession.getId());
  141                  }
  142                  catch (IOException ignore)
  143                  {
  144                  }
  145               }
  146   
  147               if (caller == null || (caller instanceof JBossGenericPrincipal) == false)
  148               {
  149                  // Look to the session for the active caller security context
  150                  if (session != null)
  151                  {
  152                     principal =
  153                        (JBossGenericPrincipal) session.getPrincipal();
  154                  }
  155               }
  156               else
  157               {
  158                  // Use the request principal as the caller identity
  159                  principal = (JBossGenericPrincipal) caller;
  160               }
  161   
  162               // If there is a caller use this as the identity to propagate
  163               if (principal != null)
  164               {
  165                  if (trace)
  166                     log.trace("Restoring principal info from cache");
  167                  SecurityAssociationActions.setPrincipalInfo(principal.getAuthPrincipal(),
  168                     principal.getCredentials(), principal.getSubject());  
  169               }
  170               // Put the authenticated subject in the session if requested
  171               if (subjectAttributeName != null)
  172               {
  173                  javax.naming.Context securityNamingCtx = getSecurityNamingContext();
  174                  if (securityNamingCtx != null)
  175                  {
  176                     // Get the JBoss security manager from the ENC context
  177                     AuthenticationManager securityMgr = (AuthenticationManager) securityNamingCtx.lookup("securityMgr");
  178                     Subject subject = securityMgr.getActiveSubject();
  179                     request.getRequest().setAttribute(subjectAttributeName, subject);
  180                  }
  181               }
  182            }
  183            catch (Throwable e)
  184            {
  185               log.debug("Failed to determine servlet", e);
  186            }
  187            
  188            // Perform the request
  189            getNext().invoke(request, response);
  190            if(servlet != null)
  191            { 
  192               SecurityAssociationActions.popRunAsIdentity();
  193            }
  194   
  195            /* If the security domain cache is to be kept in synch with the
  196            session then flush the cache if the session has been invalidated.
  197            */
  198            if( secMgrService != null &&
  199               session != null && session.isValid() == false &&
  200               metaData.isFlushOnSessionInvalidation() == true )
  201            {
  202               if( principal != null )
  203               {
  204                  String securityDomain = metaData.getSecurityDomain();
  205                  if (trace)
  206                  {
  207                     log.trace("Session is invalid, security domain: "+securityDomain
  208                        +", user="+principal);
  209                  }
  210                  try
  211                  {
  212                     Principal authPrincipal = principal.getAuthPrincipal();
  213                     secMgrService.flushAuthenticationCache(securityDomain, authPrincipal);
  214                  }
  215                  catch(Exception e)
  216                  {
  217                     log.debug("Failed to flush auth cache", e);
  218                  }
  219               }
  220            } 
  221         }
  222         finally
  223         {
  224            if( trace )
  225               log.trace("End invoke, caller"+caller);
  226            activeWebMetaData.set(null);
  227            userPrincipal.set(null);
  228            activeRequest.set(null);
  229            activeResponse.set(null);
  230         }
  231      }
  232   
  233      private javax.naming.Context getSecurityNamingContext()
  234      {
  235         javax.naming.Context securityCtx = null;
  236         // Get the JBoss security manager from the ENC context
  237         try
  238         {
  239            InitialContext iniCtx = new InitialContext();
  240            securityCtx = (javax.naming.Context) iniCtx.lookup("java:comp/env/security");
  241         }
  242         catch (NamingException e)
  243         {
  244            // Apparently there is no security context?
  245         }
  246         return securityCtx;
  247      } 
  248   }

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