[jboss-cvs] JBossAS SVN: r78884 - in trunk/tomcat/src/main/org/jboss/web/tomcat: security and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Sep 26 06:29:57 EDT 2008


Author: remy.maucherat at jboss.com
Date: 2008-09-26 06:29:56 -0400 (Fri, 26 Sep 2008)
New Revision: 78884

Modified:
   trunk/tomcat/src/main/org/jboss/web/tomcat/filters/SemaphoreValve.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/security/JaccContextValve.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityAssociationValve.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityContextEstablishmentValve.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/jca/CachedConnectionValve.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java
Log:
- Add the security and clustering stuff to events (might be useless
  often, but I don't see a way to take a good guess).
- Remove semaphore valve, the one from JBoss Web should now work.

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/filters/SemaphoreValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/filters/SemaphoreValve.java	2008-09-26 03:33:33 UTC (rev 78883)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/filters/SemaphoreValve.java	2008-09-26 10:29:56 UTC (rev 78884)
@@ -1,213 +1,34 @@
 /*
- * Copyright 1999-2001,2005 The Apache Software Foundation.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
 package org.jboss.web.tomcat.filters;
 
 
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.catalina.util.StringManager;
-import org.apache.catalina.valves.ValveBase;
-
-import EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
-import EDU.oswego.cs.dl.util.concurrent.Sync;
-
 /**
- * <p>Implementation of a Valve that limits concurrency.</p>
- *
- * <p>This Valve may be attached to any Container, depending on the granularity
- * of the concurrency control you wish to perform.  This is a Java 1.4 port
- * of the SemaphoreValve class that Remy implemented.</p>
+ * <p>Empty class, for compatibility.</p>
  * 
- * @author Remy Maucherat, Scott Marlow
  * @version $Revision$ $Date$
+ * @deprecated
  */
 
 public class SemaphoreValve
-    extends ValveBase
-    implements Lifecycle {
-
-
-    // ----------------------------------------------------- Instance Variables
-
-
-    /**
-     * The descriptive information related to this implementation.
-     */
-    private static final String info =
-        "org.jboss.web.tomcat.filters.SemaphoreValve/1.0";
-
-
-    /**
-     * Semaphore.
-     */
-    protected Sync semaphore = null;
-    
-
-    /**
-     * The lifecycle event support for this component.
-     */
-    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
-
-
-    /**
-     * Has this component been started yet?
-     */
-    private boolean started = false;
-
-
-    // ------------------------------------------------------------- Properties
-
-    
-    /**
-     * Concurrency level of the semaphore.
-     */
-    protected int concurrency = 10;
-    public int getConcurrency() { return concurrency; }
-    public void setConcurrency(int concurrency) { this.concurrency = concurrency; }
-    
-
-    // ------------------------------------------------------ Lifecycle Methods
-
-
-    /**
-     * Add a lifecycle event listener to this component.
-     *
-     * @param listener The listener to add
-     */
-    public void addLifecycleListener(LifecycleListener listener) {
-
-        lifecycle.addLifecycleListener(listener);
-
-    }
-
-
-    /**
-     * Get the lifecycle listeners associated with this lifecycle. If this
-     * Lifecycle has no listeners registered, a zero-length array is returned.
-     */
-    public LifecycleListener[] findLifecycleListeners() {
-
-        return lifecycle.findLifecycleListeners();
-
-    }
-
-
-    /**
-     * Remove a lifecycle event listener from this component.
-     *
-     * @param listener The listener to add
-     */
-    public void removeLifecycleListener(LifecycleListener listener) {
-
-        lifecycle.removeLifecycleListener(listener);
-
-    }
-
-
-    /**
-     * Prepare for the beginning of active use of the public methods of this
-     * component.  This method should be called after <code>configure()</code>,
-     * and before any of the public methods of the component are utilized.
-     *
-     * @exception LifecycleException if this component detects a fatal error
-     *  that prevents this component from being used
-     */
-    public void start() throws LifecycleException {
-
-        // Validate and update our current component state
-        if (started)
-            throw new LifecycleException
-                ("Semaphore valve already started");
-        lifecycle.fireLifecycleEvent(START_EVENT, null);
-        started = true;
-
-        semaphore = new FIFOSemaphore(concurrency);
-
-    }
-
-
-    /**
-     * Gracefully terminate the active use of the public methods of this
-     * component.  This method should be the last one called on a given
-     * instance of this component.
-     *
-     * @exception LifecycleException if this component detects a fatal error
-     *  that needs to be reported
-     */
-    public void stop() throws LifecycleException {
-
-        // Validate and update our current component state
-        if (!started)
-            throw new LifecycleException
-                ("Semaphore valve not started");
-        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
-        started = false;
-
-        semaphore = null;
-
-    }
-
-    
-    // --------------------------------------------------------- Public Methods
-
-
-    /**
-     * Return descriptive information about this Valve implementation.
-     */
-    public String getInfo() {
-        return (info);
-    }
-
-
-    /**
-     * Do concurrency control on the request using the semaphore.
-     *
-     * @param request The servlet request to be processed
-     * @param response The servlet response to be created
-     *
-     * @exception IOException if an input/output error occurs
-     * @exception ServletException if a servlet error occurs
-     */
-    public void invoke(Request request, Response response)
-        throws IOException, ServletException {
-
-	boolean shouldRelease = false;
-        try {
-            semaphore.acquire();
-            shouldRelease = true;
-            // Perform the request
-            getNext().invoke(request, response);
-        } catch( java.lang.InterruptedException e)  {
-            container.getLogger().error(e.getMessage(), e);
-        } finally {
-            if (shouldRelease)
-                semaphore.release();
-        }
-
-    }
-
-
+    extends org.apache.catalina.valves.SemaphoreValve {
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/security/JaccContextValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/security/JaccContextValve.java	2008-09-26 03:33:33 UTC (rev 78883)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/security/JaccContextValve.java	2008-09-26 10:29:56 UTC (rev 78884)
@@ -36,6 +36,7 @@
 import org.jboss.logging.Logger;
 import org.jboss.metadata.web.jboss.JBossWebMetaData;
 import org.jboss.security.SecurityRolesAssociation;
+import org.jboss.servlet.http.HttpEvent;
 
 /**
  * A Valve that sets the JACC context id and HttpServletRequest policy
@@ -99,5 +100,41 @@
          SecurityRolesAssociation.setSecurityRoles(null);
          HttpServletRequestPolicyContextHandler.setRequest(null); 
       }
-   } 
+   }
+
+   public void event(Request request, Response response, HttpEvent event)
+      throws IOException, ServletException
+   {
+      SecurityAssociationValve.activeWebMetaData.set(metaData);
+      activeCS.set(warCS);
+      HttpServletRequest httpRequest = (HttpServletRequest) request.getRequest();
+
+      //Set the customized rolename-principalset mapping in jboss-app.xml
+      Map<String, Set<String>> principalToRoleSetMap = metaData.getPrincipalVersusRolesMap();
+      SecurityRolesAssociation.setSecurityRoles(principalToRoleSetMap);
+      if(trace)
+         log.trace("MetaData:"+metaData+":principalToRoleSetMap"+principalToRoleSetMap);  
+      
+      try
+      {
+         // Set the JACC context id
+         PolicyContext.setContextID(contextID);
+         // Set the JACC HttpServletRequest PolicyContextHandler data
+         HttpServletRequestPolicyContextHandler.setRequest(httpRequest);
+         if(SecurityAssociationValve.activeRequest.get() == null)
+            SecurityAssociationValve.activeRequest.set(request);
+         // Perform the request
+         getNext().event(request, response, event);
+      }
+      finally
+      {
+         SecurityAssociationValve.activeWebMetaData.set(null);
+         SecurityAssociationValve.activeRequest.set(null);
+         SecurityAssociationActions.clear();
+         activeCS.set(null);
+         SecurityRolesAssociation.setSecurityRoles(null);
+         HttpServletRequestPolicyContextHandler.setRequest(null); 
+      }
+   }
+   
 }
\ No newline at end of file

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityAssociationValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityAssociationValve.java	2008-09-26 03:33:33 UTC (rev 78883)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityAssociationValve.java	2008-09-26 10:29:56 UTC (rev 78884)
@@ -42,6 +42,7 @@
 import org.jboss.security.AuthenticationManager;
 import org.jboss.security.RunAsIdentity;
 import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
+import org.jboss.servlet.http.HttpEvent;
 
 /**
  * A Valve that sets/clears the SecurityAssociation information associated with
@@ -244,5 +245,145 @@
          // Apparently there is no security context?
       }
       return securityCtx;
-   } 
+   }
+
+   public void event(Request request, Response response, HttpEvent event)
+      throws IOException, ServletException
+   {
+      Session session = null;
+      // Get the request caller which could be set due to SSO 
+      Principal caller = request.getPrincipal();
+      // The cached web container principal
+      JBossGenericPrincipal principal = null;
+      HttpSession hsession = request.getSession(false);
+      
+      if( trace )
+         log.trace("Begin invoke, caller="+caller);
+      // Set the active meta data
+      activeWebMetaData.set(metaData); 
+      //Set the active request and response objects
+      activeRequest.set(request);
+      activeResponse.set(response);
+      
+      try
+      {
+         Wrapper servlet = null;
+         try
+         {
+            servlet = request.getWrapper();
+            if (servlet != null)
+            {
+               String name = servlet.getName();
+               RunAsIdentityMetaData identity = metaData.getRunAsIdentity(name);
+               RunAsIdentity runAsIdentity = null;
+               if(identity != null)
+               {
+                  if (trace)
+                     log.trace(name + ", runAs: " + identity);
+                  runAsIdentity = new RunAsIdentity(identity.getRoleName(),
+                        identity.getPrincipalName(), identity.getRunAsRoles());
+               }
+               SecurityAssociationActions.pushRunAsIdentity(runAsIdentity); 
+            }
+            userPrincipal.set(caller);
+            
+            // If there is a session, get the tomcat session for the principal
+            Manager manager = container.getManager();
+            if (manager != null && hsession != null)
+            {
+               try
+               {
+                  session = manager.findSession(hsession.getId());
+               }
+               catch (IOException ignore)
+               {
+               }
+            }
+            
+            if (caller == null || (caller instanceof JBossGenericPrincipal) == false)
+            {
+               // Look to the session for the active caller security context
+               if (session != null)
+               {
+                  principal =
+                     (JBossGenericPrincipal) session.getPrincipal();
+               }
+            }
+            else
+            {
+               // Use the request principal as the caller identity
+               principal = (JBossGenericPrincipal) caller;
+            }
+            
+            // If there is a caller use this as the identity to propagate
+            if (principal != null)
+            {
+               if (trace)
+                  log.trace("Restoring principal info from cache");
+               SecurityAssociationActions.setPrincipalInfo(principal.getAuthPrincipal(),
+                     principal.getCredentials(), principal.getSubject());  
+            }
+            // Put the authenticated subject in the session if requested
+            if (subjectAttributeName != null)
+            {
+               javax.naming.Context securityNamingCtx = getSecurityNamingContext();
+               if (securityNamingCtx != null)
+               {
+                  // Get the JBoss security manager from the ENC context
+                  AuthenticationManager securityMgr = (AuthenticationManager) securityNamingCtx.lookup("securityMgr");
+                  Subject subject = securityMgr.getActiveSubject();
+                  request.getRequest().setAttribute(subjectAttributeName, subject);
+               }
+            }
+         }
+         catch (Throwable e)
+         {
+            log.debug("Failed to determine servlet", e);
+         }
+         
+         // Perform the request
+         getNext().event(request, response, event);
+         if(servlet != null)
+         { 
+            SecurityAssociationActions.popRunAsIdentity();
+         }
+         
+         /* If the security domain cache is to be kept in synch with the
+    session then flush the cache if the session has been invalidated.
+          */
+         if( secMgrService != null &&
+               session != null && session.isValid() == false &&
+               metaData.isFlushOnSessionInvalidation() == true )
+         {
+            if( principal != null )
+            {
+               String securityDomain = metaData.getSecurityDomain();
+               if (trace)
+               {
+                  log.trace("Session is invalid, security domain: "+securityDomain
+                        +", user="+principal);
+               }
+               try
+               {
+                  Principal authPrincipal = principal.getAuthPrincipal();
+                  secMgrService.flushAuthenticationCache(securityDomain, authPrincipal);
+               }
+               catch(Exception e)
+               {
+                  log.debug("Failed to flush auth cache", e);
+               }
+            }
+         } 
+      }
+      finally
+      {
+         if( trace )
+            log.trace("End invoke, caller="+caller);
+         activeWebMetaData.set(null);
+         userPrincipal.set(null);
+         activeRequest.set(null);
+         activeResponse.set(null);
+      }
+   }
+      
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityContextEstablishmentValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityContextEstablishmentValve.java	2008-09-26 03:33:33 UTC (rev 78883)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/security/SecurityContextEstablishmentValve.java	2008-09-26 10:29:56 UTC (rev 78884)
@@ -33,6 +33,7 @@
 import org.jboss.security.SecurityContext;
 import org.jboss.security.SecurityRolesAssociation;
 import org.jboss.security.SecurityUtil;
+import org.jboss.servlet.http.HttpEvent;
 
 
 /**
@@ -120,4 +121,46 @@
       securityContext.setSecurityManagement(securityManagement);
       return securityContext; 
    }
+
+   @Override
+   public void event(Request request, Response response, HttpEvent event)
+      throws IOException, ServletException
+   {
+      SecurityContext cachedContext = null;
+      
+      boolean createdSecurityContext = false;
+      //Set the security context if one is unavailable
+      SecurityContext sc = SecurityAssociationActions.getSecurityContext();
+      if(sc != null && 
+            sc.getSecurityDomain().equals(configuredSecurityDomainName) == false)
+      {
+         cachedContext = sc;
+         SecurityContext newSC = createSecurityContext();
+         SecurityAssociationActions.setSecurityContext(newSC);
+         createdSecurityContext = true;
+      }
+      
+      if(sc == null)
+      {
+         sc = createSecurityContext();
+         SecurityAssociationActions.setSecurityContext(sc);
+         createdSecurityContext = true;
+      }
+      
+      try
+      { 
+         // Perform the request
+         getNext().event(request, response, event);
+      }
+      finally
+      { 
+         SecurityRolesAssociation.setSecurityRoles(null); 
+         if(createdSecurityContext)
+         {
+            SecurityAssociationActions.clearSecurityContext();
+         }
+         if(cachedContext != null)
+            SecurityAssociationActions.setSecurityContext(cachedContext);
+      }
+   }
 }
\ No newline at end of file

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/jca/CachedConnectionValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/jca/CachedConnectionValve.java	2008-09-26 03:33:33 UTC (rev 78883)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/jca/CachedConnectionValve.java	2008-09-26 10:29:56 UTC (rev 78884)
@@ -45,6 +45,7 @@
 import org.jboss.logging.Logger;
 import org.jboss.mx.util.MBeanServerLocator;
 import org.jboss.resource.connectionmanager.CachedConnectionManager;
+import org.jboss.servlet.http.HttpEvent;
 
 /**
  * This valve checks for unclosed connections on a servlet request
@@ -174,6 +175,34 @@
       }
    }
 
+   public void event(Request request, Response response, HttpEvent event)
+      throws IOException, ServletException
+   {
+      try
+      {
+         ccm.pushMetaAwareObject(this, unsharableResources);
+         try
+         {
+            getNext().event(request, response, event);
+         }
+         finally
+         {
+            try
+            {
+               ccm.popMetaAwareObject(unsharableResources);
+            }
+            finally
+            {
+               checkTransactionComplete(request);
+            }
+         }
+      }
+      catch (ResourceException e)
+      {
+         throw new ServletException("Error invoking cached connection manager", e);
+      }
+   }
+
    // Lifecycle-interface
    public void addLifecycleListener(LifecycleListener listener)
    {
@@ -296,4 +325,5 @@
          }
       }
    }
+
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java	2008-09-26 03:33:33 UTC (rev 78883)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java	2008-09-26 10:29:56 UTC (rev 78884)
@@ -35,6 +35,7 @@
 import org.apache.catalina.connector.Response;
 import org.apache.catalina.util.LifecycleSupport;
 import org.apache.catalina.valves.ValveBase;
+import org.jboss.servlet.http.HttpEvent;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
 
 /**
@@ -146,6 +147,73 @@
       }
    }
 
+   /**
+    * Valve-chain handler method.
+    * This method gets called when the request goes through the Valve-chain. Our session replication mechanism replicates the
+    * session after request got through the servlet code.
+    *
+    * @param request  The request object associated with this request.
+    * @param response The response object associated with this request.
+    */
+   public void event(Request request, Response response, HttpEvent event) throws IOException, ServletException
+   {
+      // Initialize the context and store the request and response objects 
+      // for any clustering code that has no direct access to these objects
+      SessionReplicationContext.enterWebapp(request, response, true);
+      
+      boolean startedBatch = startBatchTransaction();
+      try
+      {  
+         // Workaround to JBAS-5735. Ensure we get the session from the manager
+         // rather than a cached ref from the Request.
+         String requestedId = request.getRequestedSessionId();
+         if (requestedId != null)
+         {
+            manager.findSession(requestedId);
+         }
+         
+         
+         // let the servlet invocation go through
+         getNext().event(request, response, event);
+      }
+      finally // We replicate no matter what
+      {
+         // --> We are now after the servlet invocation
+         try
+         {
+            SessionReplicationContext ctx = SessionReplicationContext.exitWebapp();
+            
+            if (ctx.getSoleSnapshotManager() != null)
+            {
+               ctx.getSoleSnapshotManager().snapshot(ctx.getSoleSession());
+            }
+            else
+            {
+               // Cross-context request touched multiple sesssions;
+               // need to replicate them all
+               Map sessions = ctx.getCrossContextSessions();
+               if (sessions != null && sessions.size() > 0)
+               {
+                  for (Iterator iter = sessions.entrySet().iterator(); iter.hasNext();)
+                  {
+                     Map.Entry entry = (Map.Entry) iter.next();               
+                     ((SnapshotManager) entry.getValue()).snapshot((ClusteredSession) entry.getKey());
+                  }
+               }
+            }
+         }
+         finally
+         {
+            SessionReplicationContext.finishCacheActivity();
+            if (startedBatch)
+            {
+               tm.endBatch();
+            }
+         }
+         
+      }
+   }
+
    // Lifecylce-interface
    public void addLifecycleListener(LifecycleListener listener)
    {




More information about the jboss-cvs-commits mailing list