[jboss-svn-commits] JBL Code SVN: r23536 - in labs/jbossesb/branches/JBESB_4_4_GA_CP/product: install/conf and 5 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Oct 21 08:10:19 EDT 2008


Author: beve
Date: 2008-10-21 08:10:18 -0400 (Tue, 21 Oct 2008)
New Revision: 23536

Added:
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagator.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagator.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactory.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagatorUnitTest.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactoryUnitTest.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecurityContextPropagator.java
Modified:
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/docs/ServicesGuide.odt
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/docs/ServicesGuide.pdf
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/install/conf/jbossesb-properties.xml
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JaasSecurityService.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Configuration.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Environment.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/security-properties.xml
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/security-properties.xml
Log:
Work for https://jira.jboss.org/jira/browse/JBESB-2126 "JBoss security credentials not always initialised"
and https://jira.jboss.org/jira/browse/JBESB-2136 "Security context not passed to EJB in a way that EJB understands"
Both were related to the handling and propagation of the security context in JBossESB and other containers/systems.


Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/docs/ServicesGuide.odt
===================================================================
(Binary files differ)

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/docs/ServicesGuide.pdf
===================================================================
(Binary files differ)

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/install/conf/jbossesb-properties.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/install/conf/jbossesb-properties.xml	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/install/conf/jbossesb-properties.xml	2008-10-21 12:10:18 UTC (rev 23536)
@@ -47,6 +47,7 @@
     	
         <!-- Timeout in milliseconds. After which the context is considered invalid -->
     	<property name="org.jboss.soa.esb.services.security.contextTimeout" value="30000"/>
+    	<property name="org.jboss.soa.esb.services.security.contextPropagatorImplementationClass" value="org.jboss.internal.soa.esb.services.security.JBossASContextPropagator"/>
 
 		<!-- Public keystore configuration used to hold keys for encryption/decryption -->
     	<property name="org.jboss.soa.esb.services.security.publicKeystore" value="/publicKeyStore"/>

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagator.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagator.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagator.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors 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.internal.soa.esb.services.security;
+
+import java.security.Principal;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.security.RunAsIdentity;
+import org.jboss.security.SecurityAssociation;
+import org.jboss.soa.esb.services.security.SecurityConfig;
+import org.jboss.soa.esb.services.security.SecurityContext;
+import org.jboss.soa.esb.services.security.principals.User;
+
+/**
+ * JBoss Application Server(AS) specifiec security context propagator.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ */
+public final class JBossASContextPropagator implements SecurityContextPropagator
+{
+    /**
+     * Pushed the subject by calling {@link SecurityAssociation#pushSubjectContext(Subject, Principal, Object)}.
+     *
+     * @param context The SecurityContext holding the subject to push/propagate. May not be null.
+     * @param config The SecurityConfig which contains the information specified from the security configuration element. Can be null.
+     */
+    public void pushSecurityContext(final SecurityContext context, Set<?> authCredentials, final SecurityConfig config)
+    {
+        AssertArgument.isNotNull(context, "context");
+
+        final Subject subject = context.getSubject();
+        final Principal principal = getPrincipal(subject);
+
+        //  associate the subject with jboss security
+        Object credential = null;
+        if (authCredentials != null)
+        {
+            credential = authCredentials.iterator().next();
+        }
+        SecurityAssociation.pushSubjectContext(subject, principal, credential);
+
+
+        if (isRunAsSet(config))
+        {
+            //  associate the runAs role with jboss security
+            SecurityAssociation.pushRunAsIdentity(new RunAsIdentity(config.getRunAs(), principal.getName()));
+        }
+    }
+
+    /**
+     * Pops the subject by calling {@link SecurityAssociation#pushSubjectContext(Subject, Principal, Object)}.
+     *
+     * @param context The SecurityContext holding the subject to push/propagate. Can be null.
+     * @param config The SecurityConfig which contains the information specified from the security configuration element. Can be null.
+     */
+    public void popSecurityContext(final SecurityContext context, final SecurityConfig config)
+    {
+        //  diassociate the subject with jboss security
+        SecurityAssociation.popSubjectContext();
+
+        if (isRunAsSet(config))
+        {
+            //  associate the runAs role with jboss security
+            SecurityAssociation.popRunAsIdentity();
+        }
+    }
+
+    private Principal getPrincipal( final Subject subject)
+    {
+        for (Principal principal : subject.getPrincipals())
+        {
+            return principal;
+        }
+        return new User("NullPrincipal");
+    }
+
+    private boolean isRunAsSet(final SecurityConfig config)
+    {
+        return config != null && config.getRunAs() != null;
+    }
+
+}

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JaasSecurityService.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JaasSecurityService.java	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JaasSecurityService.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -29,8 +29,6 @@
 import javax.security.auth.login.LoginException;
 
 import org.jboss.internal.soa.esb.assertion.AssertArgument;
-import org.jboss.security.RunAsIdentity;
-import org.jboss.security.SecurityAssociation;
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.common.Configuration;
 import org.jboss.soa.esb.services.security.SecurityConfig;
@@ -81,7 +79,6 @@
 		AssertArgument.isNotNull(config, "config");
 
 		LoginContext loginContext;
-		final String runAs = config.getRunAs();
 		try
 		{
 			final EsbCallbackHandler callbackHandler = createCallbackHandler(config, authRequest);
@@ -93,23 +90,12 @@
 			{
     			loginContext = new LoginContext(config.getModuleName(), securityContext.getSubject());
 			}
+
     		loginContext.login();
 
-    		final Subject subject = securityContext.getSubject();
-
     		//	add a runAs group if specified
-    		addRunAs(runAs, subject);
+    		addRunAs(config.getRunAs(), securityContext.getSubject());
 
-    		final Principal principal = getPrincipal(subject);
-
-            //  associate the subject with jboss security
-            SecurityAssociation.pushSubjectContext(subject, principal, subject.getPublicCredentials());
-
-            if ( runAs != null )
-            {
-                //  associate the runAs role with jboss security
-                SecurityAssociation.pushRunAsIdentity(new RunAsIdentity(runAs, principal.getName()));
-            }
 		}
 		catch (final LoginException e)
 		{
@@ -171,15 +157,6 @@
         // NoOp
     }
 
-    private Principal getPrincipal( final Subject subject)
-	{
-		for (Principal principal : subject.getPrincipals())
-		{
-			return principal;
-		}
-		return null;
-	}
-
 	/**
 	 * Creates an instance of EsbCallbackHandler specified in either jboss-esb.xml:
 	 * <pre>

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagator.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagator.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagator.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors 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.internal.soa.esb.services.security;
+
+import java.util.Set;
+
+import org.jboss.soa.esb.services.security.SecurityConfig;
+import org.jboss.soa.esb.services.security.SecurityContext;
+
+/**
+ * A SecurityContextPropagator can push/propagate and pop/remove security context
+ * information to a specified targets security subsytem.
+ * </p>
+ * For example, a SecurityContextPropagator for JBossAS would propagate a security
+ * context so that it is made available to JBossAS Security subsystem.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ */
+public interface SecurityContextPropagator
+{
+    /**
+     * Push/Propagate the Security context information to the destined system.
+     *
+     * @param context The security context to be pushed(propagated)
+     * @param credentials The set of credentials that were provided for authentication.
+     * @param config The SecurityConfig which give access to the service's security configuration.
+     */
+    void pushSecurityContext(final SecurityContext context, final Set<?> credentials, final SecurityConfig config);
+
+    /**
+     * Pop/Remove the Security context information to the destined system.
+     *
+     * @param context The security context to be pushed(propagated)
+     * @param config The SecurityConfig which give access to the service's security configuration.
+     */
+    void popSecurityContext(final SecurityContext context, final SecurityConfig config);
+
+}

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactory.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactory.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactory.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors 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.internal.soa.esb.services.security;
+
+import org.jboss.soa.esb.common.Configuration;
+import org.jboss.soa.esb.services.security.SecurityServiceException;
+import org.jboss.soa.esb.util.ClassUtil;
+
+/**
+ * Factory for creating {@link SecurityContextPropagator} instances.
+ * Only contains factory methods.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public final class SecurityContextPropagatorFactory
+{
+    private SecurityContextPropagatorFactory() {}
+
+    public static SecurityContextPropagator createFromConfig() throws SecurityServiceException
+    {
+        return create(Configuration.getSecurityContextPropagatorImplementationClass());
+    }
+
+    /**
+     * Creates an instance of the specified className which must be an instance of {@link SecurityContextPropagator}.
+     *
+     * @param className The fully qualified name of the class to be used.
+     * @return SecurityContextPropagator An instance of the passed in className of if className of null is className was null.
+     * @throws SecurityServiceException If an exception occurs while trying to create the instance.
+     */
+    public static SecurityContextPropagator create(final String className) throws SecurityServiceException
+    {
+        if (className == null)
+        {
+            return null;
+        }
+        return createInstance(className);
+    }
+
+    private static SecurityContextPropagator createInstance(final String className) throws SecurityServiceException
+    {
+        try
+        {
+            final Class<?> propagator = ClassUtil.forName(className, SecurityContextPropagatorFactory.class);
+            Object newInstance = propagator.newInstance();
+            return (SecurityContextPropagator) newInstance;
+        }
+        catch (final ClassNotFoundException e)
+        {
+            throw new SecurityServiceException("SecurityContextPropagator implementation '" + className + "' not found", e);
+        }
+        catch (final InstantiationException e)
+        {
+            throw new SecurityServiceException("Instantiation Exception while trying to create a SecurityContextPropagator of type '" + className + "'", e);
+        }
+        catch (final IllegalAccessException e)
+        {
+            throw new SecurityServiceException("IllegalAccessException while trying to create a SecurityContextPropagator of type '" + className + "'", e);
+        }
+    }
+
+}

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Configuration.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Configuration.java	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Configuration.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -36,8 +36,6 @@
 import org.jboss.soa.esb.helpers.NamingContextException;
 import org.jboss.soa.esb.helpers.NamingContextPool;
 
-import com.arjuna.common.util.propertyservice.PropertyManager;
-
 public class Configuration
 {
     private static Logger _logger = Logger.getLogger(Configuration.class);
@@ -463,39 +461,6 @@
 	}
 
 	/*
-	 *  Private Keystore getters
-	 */
-	public static String getSecurityServicePrivateKeystore()
-	{
-		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperty(Environment.SECURITY_SERVICE_PRIVATE_KEYSTORE);
-	}
-
-	public static String getSecurityServicePrivateKeyAlias()
-	{
-		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperty(Environment.SECURITY_SERVICE_PRIVATE_KEY_ALIAS);
-	}
-
-	public static String getSecurityServicePrivateKeyPassword()
-	{
-		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperty(Environment.SECURITY_SERVICE_PRIVATE_KEY_PASS);
-	}
-
-	public static String getSecurityServicePrivateKeystorePassword()
-	{
-		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperty(Environment.SECURITY_SERVICE_PRIVATE_KEYSTORE_PASS);
-	}
-
-	public static String getSecurityServicePrivateKeystoreType()
-	{
-		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperty(Environment.SECURITY_SERVICE_PRIVATE_KEYSTORE_TYPE);
-	}
-
-    public static String getSecurityServicePrivateKeyTransformation()
-    {
-        return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperty(Environment.SECURITY_SERVICE_PRIVATE_KEY_TRANSFORMATION);
-    }
-
-	/*
 	 *  Public Keystore getters
 	 */
 
@@ -553,4 +518,14 @@
 	{
 		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperties();
 	}
+
+	/**
+	 * The SecurityContextPropagator implememtation class to use.
+	 *
+	 * @return String The fully qualified name of the SecurityContextPropagator implementation class
+	 */
+	public static String getSecurityContextPropagatorImplementationClass()
+	{
+		return ModulePropertyManager.getPropertyManager(ModulePropertyManager.SECURITY_MODULE).getProperty(Environment.SECURITY_SERVICE_CONTEXT_PROPAGATOR_CLASS);
+	}
 }

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Environment.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Environment.java	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/common/Environment.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -231,14 +231,8 @@
 	public static final String SECURITY_SERVICE_SEAL_ALGORITHM 			= "org.jboss.soa.esb.services.security.sealAlgorithm";
 	public static final String SECURITY_SERVICE_SEAL_KEYSIZE 			= "org.jboss.soa.esb.services.security.sealKeySize";
 	public static final String SECURITY_SERVICE_CONTEXT_TIMEOUT			= "org.jboss.soa.esb.services.security.contextTimeout";
+	public static final String SECURITY_SERVICE_CONTEXT_PROPAGATOR_CLASS= "org.jboss.soa.esb.services.security.contextPropagatorImplementationClass";
 
-	public static final String SECURITY_SERVICE_PRIVATE_KEYSTORE		= "org.jboss.soa.esb.services.security.privateKeystore";
-	public static final String SECURITY_SERVICE_PRIVATE_KEYSTORE_TYPE	= "org.jboss.soa.esb.services.security.privateKeystoreType";
-	public static final String SECURITY_SERVICE_PRIVATE_KEYSTORE_PASS	= "org.jboss.soa.esb.services.security.privateKeystorePassword";
-	public static final String SECURITY_SERVICE_PRIVATE_KEY_ALIAS	    = "org.jboss.soa.esb.services.security.privateKeyAlias";
-	public static final String SECURITY_SERVICE_PRIVATE_KEY_PASS	    = "org.jboss.soa.esb.services.security.privateKeyPassword";
-	public static final String SECURITY_SERVICE_PRIVATE_KEY_TRANSFORMATION = "org.jboss.soa.esb.services.security.privateKeyTransformation";
-
 	public static final String SECURITY_SERVICE_PUBLIC_KEYSTORE    		= "org.jboss.soa.esb.services.security.publicKeystore";
 	public static final String SECURITY_SERVICE_PUBLIC_KEYSTORE_TYPE	= "org.jboss.soa.esb.services.security.publicKeystoreType";
 	public static final String SECURITY_SERVICE_PUBLIC_KEYSTORE_PASS	= "org.jboss.soa.esb.services.security.publicKeystorePassword";

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -32,6 +32,8 @@
 import javax.xml.validation.Schema;
 
 import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.services.security.SecurityContextPropagator;
+import org.jboss.internal.soa.esb.services.security.SecurityContextPropagatorFactory;
 import org.jboss.internal.soa.esb.util.XMLHelper;
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.actions.ActionLifecycle;
@@ -83,8 +85,7 @@
 	/**
 	 * The logger instance.
 	 */
-	private final static Logger LOGGER = Logger
-			.getLogger(ActionProcessingPipeline.class);
+	private final static Logger LOGGER = Logger .getLogger(ActionProcessingPipeline.class);
 
 	/**
 	 * The processors.
@@ -120,9 +121,9 @@
 	 */
 	private final boolean oneWay ;
 
-        /**
-         * The flag indicating whether we are using implicit or explicit processing.
-         */
+    /**
+     * The flag indicating whether we are using implicit or explicit processing.
+     */
 	private final boolean defaultProcessing ;
 
 	/**
@@ -131,18 +132,24 @@
 	private SecurityConfig securityConf;
 
 	/**
+	 * The {@link SecurityContextPropagator} is use.
+	 * This can be configured either globally in jbossesb-properites.xml or
+	 * per-service in jboss-esb.xml.
+	 */
+    private SecurityContextPropagator securityContextPropagator;
+
+    private String serviceName;
+
+	/**
 	 * public constructor
 	 *
-	 * @param config
-	 *            The pipeline configuration.
+	 * @param config The pipeline configuration.
 	 */
-	public ActionProcessingPipeline(final ConfigTree config)
-			throws ConfigurationException
+	public ActionProcessingPipeline(final ConfigTree config) throws ConfigurationException
 	{
 		if (config == null)
 		{
-			throw new IllegalArgumentException(
-					"Configuration needed for action classes");
+			throw new IllegalArgumentException( "Configuration needed for action classes");
 		}
 
 		final String mep = config.getAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG) ;
@@ -271,9 +278,7 @@
 				{
 					if (LOGGER.isDebugEnabled())
 					{
-						LOGGER
-								.debug("Using normal action pipeline processor for "
-										+ actionClassTag);
+						LOGGER.debug("Using normal action pipeline processor for " + actionClassTag);
 					}
 					processor = currentProcessor;
 				}
@@ -282,9 +287,7 @@
 			{
 				if (LOGGER.isDebugEnabled())
 				{
-					LOGGER
-							.debug("Using overridden action lifecycle processor for "
-									+ actionClassTag);
+					LOGGER.debug("Using overridden action lifecycle processor for " + actionClassTag);
 				}
 				final ActionLifecycle currentLifecycle = (ActionLifecycle) ActionProcessorMethodInfo
 						.getActionClassInstance(actionConfig, actionClass);
@@ -293,27 +296,57 @@
 			}
 			else
 			{
-				LOGGER.warn("Action class " + actionClassTag
-						+ " does not implement the ActionLifecycle interface");
+				LOGGER.warn("Action class " + actionClassTag + " does not implement the ActionLifecycle interface");
 				if (LOGGER.isDebugEnabled())
 				{
-					LOGGER.debug("Using overridden actions processor for "
-							+ actionClassTag);
+					LOGGER.debug("Using overridden actions processor for " + actionClassTag);
 				}
-				processor = new OverriddenActionProcessor(actionConfig,
-						actionClass);
+				processor = new OverriddenActionProcessor(actionConfig, actionClass);
 			}
 			processorList.add(processor);
 		}
-		processors = processorList
-				.toArray(new ActionPipelineProcessor[processorList.size()]);
+		processors = processorList.toArray(new ActionPipelineProcessor[processorList.size()]);
 
 		ConfigTree[] securityConfigs = config.getChildren( ListenerTagNames.SECURITY_TAG );
+		String securityPropagatorClass = null;
 		if (securityConfigs.length > 0)
 		{
 			securityConf = SecurityConfigUtil.createSecurityConfig(securityConfigs[0]);
-			LOGGER.debug(securityConf);
+			//   Check if a security context propagator was specified in the security element.
+			securityPropagatorClass = securityConf.getProperties().get(Environment.SECURITY_SERVICE_CONTEXT_PROPAGATOR_CLASS);
 		}
+        serviceName = config.getAttribute(ListenerTagNames.SERVICE_NAME_TAG);
+
+		try
+        {
+            securityContextPropagator = securityPropagatorClass != null ?
+                    SecurityContextPropagatorFactory.create(securityPropagatorClass):
+                    SecurityContextPropagatorFactory.createFromConfig();
+        }
+		catch (final SecurityServiceException e)
+        {
+		    final String errorMsg;
+		    if (securityPropagatorClass != null )
+		    {
+		       errorMsg = "Could not create an instance of class '" + securityPropagatorClass + "' which was configured for service '" +
+		                   serviceName + "'. Please check the value of '" + Environment.SECURITY_SERVICE_CONTEXT_PROPAGATOR_CLASS + "'" +
+		                   " which is a property element of the security element declared in jboss-esb.xml.";
+		    }
+		    else
+		    {
+		       errorMsg = "Could not create an instance of class the security context propagator configured in jbossesb-properties.xml" +
+		                   ".Please check the value of '" + Environment.SECURITY_SERVICE_CONTEXT_PROPAGATOR_CLASS + "' in jbossesb-properties.xml";
+		    }
+		    throw new ConfigurationException(errorMsg, e);
+        }
+
+		if (LOGGER.isDebugEnabled())
+        {
+            if (securityContextPropagator != null)
+            {
+                LOGGER.debug("SecurityContextPropagator in use for service '" + serviceName + "' is '" + securityContextPropagator.getClass().getName() + "'" );
+            }
+        }
 	}
 
 	/**
@@ -396,22 +429,29 @@
 	 * If security has not been enabled this method will not perform any authentication but
 	 * it will pass through a pre-existing SecurityContext.
 	 * <p>
+	 *
 	 * <h1>SecurityContext</h1>
 	 * After the caller has been successfully authenticated a SecurityContext will be created.
-	 * This context is valid on the current ESB node(VM) only. When a SecurityContext is created
-	 * a timeout is specified. This value can either be the globally value specified in jbossesb-properties.xml
-	 * or it can be overridden per service by specifiying the same property in the security element in jboss-esb.xml:
+	 * This context is valid on the current ESB node(VM) only.
+	 * When a SecurityContext is created a timeout is specified. This value can either be the globally
+	 * value specified in jbossesb-properties.xml or it can be overridden per service by specifiying the
+	 * same property in the security element in jboss-esb.xml:
 	 * The value is specified in milliseconds.
 	 * <pre>
 	 *     <security module="someModuleName">
 	 *         <property name="org.jboss.soa.esb.services.security.contextTimeout" value="50000"/>
 	 *     </security>
 	 * </pre>
+	 *
 	 * <h1>AuthenticationRequest</h1>
-	 * If a call is routed to a different ESB node then that node will re-authenticate the call.
+	 * If a call is routed to a different ESB node then that node will re-authenticate the caller.
 	 * The node will descrypt the authentication request passed with the Message object
 	 * and try to authenticate the caller.
 	 *
+	 * <h1>SecurityContext Propagation</h1>
+	 * Regardless of whether the service has been configured with security or not, the security
+	 * context information might need to be propagated using the configured {@link SecurityContextPropagator}.
+	 *
 	 * @param message The ESB message object.
 	 * @param sealedSecurityContext The sealed SecurityContext which will exist if the caller has already been authenticated.
 	 * @return true If the action pipeline was processed successfully.
@@ -422,21 +462,31 @@
 
 		if (sealedSecurityContext != null )
         {
-    		// store the security context. Will be re-attached to outgoing messages regardless whether the service is secured or not.
+    		// Store the security context. Will be re-attached to outgoing messages regardless whether the service is secured or not.
             SecurityContext.setSecurityContext(sealedSecurityContext);
         }
 
+		AuthenticationRequest authRequest;
 		try
 		{
+		    /*
+		     * Get the authentication reqeust if one exists. Note that this is needed even if
+		     * the current service does not require authentication. A service later down the line might
+		     * need to access this information, it might call an EJB that is secured for example, and
+		     * this way pass it through.
+		     */
+    		authRequest = getAutenticationRequest(message);
+
 		    if (isServiceSecured())
 		    {
-		        try // to decrypt the security context.
+		        try
                 {
+		            // Try to decrypt the security context.
                     securityContext = SecurityContext.decryptContext(sealedSecurityContext);
                 }
                 catch (final SecurityServiceException ignored)
                 {
-                    LOGGER.debug("Could not decrypt the security context. Might have come from a different VM. Will re-authenticate if security is enabled for this service.", ignored);
+                    LOGGER.info("Could not decrypt the security context in Service '" + serviceName + "'. The call might have come from a different VM. Will re-authenticate if security is enabled for this service.", ignored);
                     securityContext = null;
                 }
 
@@ -458,24 +508,22 @@
 
 		        if (securityContext == null || !securityContext.isValid())
 		        {
-        			// get the encrypted AuthenticationRequest from the message
-            		final byte[] encryptedAuthRequest = getAutenticationRequest(message);
-            		final AuthenticationRequest authRequest = (AuthenticationRequest) PublicCryptoUtil.INSTANCE.decrypt(encryptedAuthRequest);
+		            if (authRequest == null)
+		            {
+		                throw new SecurityServiceException("Service '" + serviceName + "' has been configured for security but no AuthenticationRequest could be located in the Message Context. Cannot authenticate without an AuthenticationRequest.");
+		            }
 
-            		// store the encrypted auth request. Will be re-attached to outgoing messages.
-            		AuthenticationRequestImpl.setEncryptedAuthRequest(encryptedAuthRequest);
-
-		             // no existing security context exist or it had expired. Create a new one to drive the autentication.
+		             // No existing security context exist or it had expired. Create a new one to drive the autentication.
     		        securityContext = new SecurityContext(new Subject(), getSecurityContextTimeout(securityConf));
 
-            		// authenticate the caller
+            		// Authenticate the caller
         			securityService.authenticate(securityConf, securityContext, authRequest);
 
-            		// store the encrypted security context. Will be re-attached to outgoing messages.
+            		// Store the encrypted security context. Will be re-attached to outgoing messages.
         			SecurityContext.setSecurityContext(SecurityContext.encryptContext(securityContext));
 		        }
 
-		        // check that the caller is a member of atleast on of the declared roles.
+		        // Check that the caller is a member of atleast one of the declared roles.
         		if (!securityService.checkRolesAllowed(securityConf.getRolesAllowed(), securityContext))
         		{
         			throw new SecurityServiceException("Caller did not belong to any of the rolesAllowed " + securityConf.getRolesAllowed());
@@ -496,14 +544,30 @@
 		}
 		finally
 		{
-		    // always remove the security context
+		    // Always remove the security context.
     		message.getContext().removeContext(SecurityService.CONTEXT);
     		message.getContext().removeContext(SecurityService.AUTH_REQUEST);
 		}
 
 		if (securityContext != null)
 		{
-    		return (Boolean) Subject.doAsPrivileged(securityContext.getSubject(), getPrivilegedAction(message), null);
+		    try
+		    {
+    		    // Need to propagate the security context regardless if security was enabled for this service or not.
+		        propagateSecurityContext(message, securityContext, authRequest);
+
+        		return (Boolean) Subject.doAsPrivileged(securityContext.getSubject(), getPrivilegedAction(message), null);
+		    }
+    		catch (final SecurityServiceException e)
+    		{
+    			LOGGER.error( "SecurityService exception : ", e);
+    			faultTo(createCallDetails(message), Factory.createErrorMessage(Factory.UNEXPECTED_ERROR, message, e));
+    			return false;
+    		}
+		    finally
+		    {
+		        popSecurityContext(securityContext);
+		    }
 		}
 		else
 		{
@@ -875,14 +939,30 @@
         return securityConf != null;
     }
 
-    private byte[] getAutenticationRequest(final Message message) throws SecurityServiceException
+    /**
+     * Retrieves the authentication reqeust from the Message context using
+     * {@link SecurityService#AUTH_REQUEST} as the key.
+     * <p/>
+     * This location may contain an encrypted AuthenticationRequest and if one
+     * exists it will be decryped and return. If one does not exist this
+     * method will return null.
+     *
+     * @param message The ESB Message object.
+     * @return {@link AuthenticationRequest} The decrypted AuthenticationRequest or null if one did not exist.
+     *
+     * @throws SecurityServiceException If a problem occurs during decryption.
+     */
+    private AuthenticationRequest getAutenticationRequest(final Message message) throws SecurityServiceException
     {
         final byte[] encryptedAuthRequest = (byte[]) message.getContext().getContext(SecurityService.AUTH_REQUEST);
-        if (encryptedAuthRequest == null)
+        if (encryptedAuthRequest != null)
         {
-           throw new SecurityServiceException("Missing AuthenticationRequest. Cannot be authenticated.");
+    		// store the encrypted auth request. Will be re-attached to outgoing messages.
+            AuthenticationRequestImpl.setEncryptedAuthRequest(encryptedAuthRequest);
+
+            return (AuthenticationRequest) PublicCryptoUtil.INSTANCE.decrypt(encryptedAuthRequest);
         }
-        return encryptedAuthRequest;
+        return null;
     }
 
     private SealedObject getSecurityContext(final Message message)
@@ -920,7 +1000,7 @@
     }
 
     /**
-     * Checks if the security config as a property named 'org.jboss.soa.esb.services.security.contextTimeout'
+     * Checks if the security config has a property named 'org.jboss.soa.esb.services.security.contextTimeout'
      * specified. This will in that case be used as the SecurityContext timeout for this pipeline.
      * If not specified the value will fallback to the value specified in jbossesb-properties.xml
      *
@@ -945,4 +1025,50 @@
         }
         return SecurityContext.getConfigurationTimeout();
     }
+
+    /**
+     * Propagates the security context by delegating to the current {@link SecurityContextPropagator}.
+     * This method returns silently if a SecurityContextPropagator has not been configured to avoid
+     * the overhead of decrypting the AuthenticationRequest (is needed).
+     *
+     * @param message The ESB message object.
+     * @param context The SecurityContext.
+     * @param authRequest The {@link AuthenticationRequest}.
+     * @throws SecurityServiceException
+     */
+    private void propagateSecurityContext(final Message message, final SecurityContext context, final AuthenticationRequest authRequest) throws SecurityServiceException
+    {
+        if (securityContextPropagator == null)
+        {
+            // No need to do anything if a security context propagator was not configured.
+            return;
+        }
+
+        final AuthenticationRequest request;
+        if (authRequest == null)
+        {
+            final byte[] encryptedAuthRequest = (byte[]) message.getContext().getContext(SecurityService.AUTH_REQUEST);
+            if (encryptedAuthRequest == null)
+            {
+               // there might not be a authentication reqeust. Just return.
+               return;
+            }
+            request = (AuthenticationRequest) PublicCryptoUtil.INSTANCE.decrypt(encryptedAuthRequest);
+        }
+        else
+        {
+            // use the passed in authentication request.
+            request = authRequest;
+        }
+
+        securityContextPropagator.pushSecurityContext(context, request.getCredentials(), securityConf);
+    }
+
+    private void popSecurityContext(final SecurityContext securityContext)
+    {
+        if (securityContextPropagator != null)
+        {
+            securityContextPropagator.popSecurityContext(securityContext, securityConf);
+        }
+    }
 }

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagatorUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagatorUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JBossASContextPropagatorUnitTest.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -0,0 +1,104 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors 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.internal.soa.esb.services.security;
+
+import static org.junit.Assert.*;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.services.security.SecurityConfig;
+import org.jboss.soa.esb.services.security.SecurityConfigTestUtil;
+import org.jboss.soa.esb.services.security.SecurityConfigUtil;
+import org.jboss.soa.esb.services.security.SecurityContext;
+import org.jboss.soa.esb.services.security.principals.User;
+import org.junit.Test;
+
+import junit.framework.JUnit4TestAdapter;
+
+/**
+ * Unit test for {@link JBossASContextPropagator}.
+ * <p/>
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class JBossASContextPropagatorUnitTest
+{
+    private JBossASContextPropagator propagator = new JBossASContextPropagator();
+
+    @Test
+    public void pushAndPop()
+    {
+        final SecurityConfig securityConfig = getSecurityConfig();
+        final SecurityContext context = getSecurityContext();
+
+        propagator.pushSecurityContext(context, null, securityConfig);
+
+        Subject pushedSubject = SecurityAssociation.getSubject();
+        assertEquals(context.getSubject(), pushedSubject);
+
+        propagator.popSecurityContext(context, securityConfig);
+        pushedSubject = SecurityAssociation.getSubject();
+        assertNull(pushedSubject);
+    }
+
+    @Test
+    public void pushAndPopWithNullSecurityConfig()
+    {
+        final SecurityConfig securityConfig = getSecurityConfig();
+        final SecurityContext context = getSecurityContext();
+
+        propagator.pushSecurityContext(context, null, null);
+
+        Subject pushedSubject = SecurityAssociation.getSubject();
+        assertEquals(context.getSubject(), pushedSubject);
+
+        propagator.popSecurityContext(context, securityConfig);
+        pushedSubject = SecurityAssociation.getSubject();
+        assertNull(pushedSubject);
+    }
+
+    @Test
+    public void popWithNullSecurityConfig()
+    {
+        propagator.popSecurityContext(null, null);
+    }
+
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(JBossASContextPropagatorUnitTest.class);
+    }
+
+    private SecurityContext getSecurityContext()
+    {
+        Subject subject = new Subject();
+        subject.getPrincipals().add(new User("Mr.Poon"));
+        return new SecurityContext(subject, 5000l);
+    }
+
+    private SecurityConfig getSecurityConfig()
+    {
+        ConfigTree securityFragment = SecurityConfigTestUtil.createSecurityFragment("adminRole", null, "SuccessfulLogin");
+        return SecurityConfigUtil.createSecurityConfig(securityFragment);
+    }
+}

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactoryUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactoryUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/SecurityContextPropagatorFactoryUnitTest.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors 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.internal.soa.esb.services.security;
+
+import static org.junit.Assert.*;
+import java.net.URL;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.common.Environment;
+import org.jboss.soa.esb.services.security.SecurityServiceException;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import junit.framework.JUnit4TestAdapter;
+
+
+/**
+ * Unit test for {@link SecurityContextPropagatorFactory}.
+ * <p/>
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ */
+public class SecurityContextPropagatorFactoryUnitTest
+{
+    // only used to store and restore a previously set configuration file.
+    private String jbossEsbProperties;
+
+    @Test
+    public void create() throws SecurityServiceException
+    {
+        SecurityContextPropagator propagator = SecurityContextPropagatorFactory.create(JBossASContextPropagator.class.getName());
+        assertTrue(propagator instanceof JBossASContextPropagator);
+    }
+
+    @Test
+    public void createNullClassNameSpecified() throws SecurityServiceException
+    {
+        SecurityContextPropagator propagator = SecurityContextPropagatorFactory.create(null);
+        assertNull(propagator);
+    }
+
+    @Test
+    public void createFromConfig() throws SecurityServiceException
+    {
+        SecurityContextPropagator propagator = SecurityContextPropagatorFactory.createFromConfig();
+
+        // should match the class specified in security-properties.xml (in this classes directory.
+        assertTrue(propagator instanceof JBossASContextPropagator);
+    }
+
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(SecurityContextPropagatorFactoryUnitTest.class);
+    }
+
+    @Before
+    public void setup() throws ConfigurationException
+    {
+        // store jbossesb properties env variable value
+        jbossEsbProperties = System.getProperty(Environment.PROPERTIES_FILE);
+
+        URL resource = ClassUtil.getResource("security-properties.xml", getClass());
+        System.setProperty(Environment.PROPERTIES_FILE, "abs://" + resource.getFile());
+    }
+
+    @After
+    public void tearDown()
+    {
+        if ( jbossEsbProperties != null )
+        {
+            // restore jbossesb-properties variable
+            System.setProperty(Environment.PROPERTIES_FILE, jbossEsbProperties);
+        }
+    }
+
+}

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/security-properties.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/security-properties.xml	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/security-properties.xml	2008-10-21 12:10:18 UTC (rev 23536)
@@ -45,6 +45,7 @@
     	<property name="org.jboss.soa.esb.services.security.sealKeySize" value="168"/>
     	
     	<property name="org.jboss.soa.esb.services.security.contextTimeout" value="30000"/>
+    	<property name="org.jboss.soa.esb.services.security.contextPropagatorImplementationClass" value="org.jboss.internal.soa.esb.services.security.JBossASContextPropagator"/>
     	
     </properties>
     <properties name="registry">

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -32,10 +32,8 @@
 import junit.framework.TestCase;
 
 import org.jboss.internal.soa.esb.services.registry.MockRegistry;
-import org.jboss.internal.soa.esb.services.security.PrivateCryptoUtil;
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.common.Environment;
-import org.jboss.soa.esb.common.ModulePropertyManager;
 import org.jboss.soa.esb.helpers.ConfigTree;
 import org.jboss.soa.esb.lifecycle.LifecycleResourceManager;
 import org.jboss.soa.esb.listeners.ListenerTagNames;
@@ -46,7 +44,6 @@
 import org.jboss.soa.esb.services.security.SecurityConfigUtil;
 import org.jboss.soa.esb.services.security.SecurityContext;
 import org.jboss.soa.esb.services.security.SecurityService;
-import org.jboss.soa.esb.services.security.SecurityServiceException;
 import org.jboss.soa.esb.services.security.TestPrincipal;
 import org.jboss.soa.esb.services.security.auth.AuthenticationRequest;
 import org.jboss.soa.esb.services.security.auth.AuthenticationRequestImpl;
@@ -450,40 +447,28 @@
         }
     }
 
-    public void testSecuredServiceWithoutExistingSecurityContext() throws Exception
+    public void testSecuredWithoutExistingSecurityContextOrAuthenticationRequest() throws ConfigurationException
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
-        // added the security configuration
         addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null);
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG, ListenerTagNames.MEP_ONE_WAY) ;
-
         addAction(configTree, MockSecuredActionProcessor.class.getName(), "process", null, null) ;
 
-        final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
+        final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree);
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList()) ;
 
-        Message message = MessageFactory.getInstance().getMessage();
+        final boolean processingResult = pipeline.process(MessageFactory.getInstance().getMessage());
+        assertFalse("The Service was configured with security but neither a AuthenticationContext nor a SecurityContext is made available", processingResult);
 
-        //  create an AuthenticationRequest which is needed to authenticate if the security
-        AuthenticationRequest authRequest = new AuthenticationRequestImpl.Builder().build();
-        byte[] encryptedAuthRequest = PublicCryptoUtil.INSTANCE.encrypt((Serializable) authRequest);
-        message.getContext().setContext(SecurityService.AUTH_REQUEST, encryptedAuthRequest);
-
-        final boolean result = pipeline.process(message);
-        assertTrue(result);
-        assertEquals(new TestPrincipal("test").getName(), MockSecuredActionProcessor.getSubject().getPrincipals().iterator().next().getName());
-
-        assertEquals(encryptedAuthRequest, AuthenticationRequestImpl.getEncryptedAuthRequest());
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList()) ;
     }
 
-    public void testSecuredServiceWithoutAutenticationRequest() throws Exception
+    public void testSecuredAuthentication() throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
-
-        // added the security configuration
+        // Add the security configuration.
         addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null);
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG, ListenerTagNames.MEP_ONE_WAY) ;
 
@@ -493,22 +478,29 @@
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList()) ;
 
-        Message message = MessageFactory.getInstance().getMessage();
+        final Message message = MessageFactory.getInstance().getMessage();
 
-        try
-        {
-            pipeline.process(message);
-        }
-        catch(final Exception e)
-        {
-            assertTrue(e instanceof SecurityServiceException);
-        }
+        //  Create an AuthenticationRequest which is needed to authenticate if the security
+        final AuthenticationRequest authRequest = new AuthenticationRequestImpl.Builder().build();
+        final byte[] encryptedAuthRequest = PublicCryptoUtil.INSTANCE.encrypt((Serializable) authRequest);
+        message.getContext().setContext(SecurityService.AUTH_REQUEST, encryptedAuthRequest);
 
+        final boolean processingResult = pipeline.process(message);
+
+        assertTrue(processingResult);
+        assertEquals(new TestPrincipal("test").getName(), MockSecuredActionProcessor.getSubject().getPrincipals().iterator().next().getName());
+        assertEquals("The encrypted AuthenticationRequest should have been set as a thread local",
+                encryptedAuthRequest, AuthenticationRequestImpl.getEncryptedAuthRequest());
+        assertTrue("The SecurityContext should have been pushed", MockSecurityContextPropagator.wasPushCalled());
+        assertTrue("The SerirityContext should have been popped", MockSecurityContextPropagator.wasPopCalled());
+        assertNull("AuthenticationRequest should have been removed from the message context",
+                message.getContext().getContext(SecurityService.AUTH_REQUEST));
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList()) ;
     }
 
-    public void testSecuredServiceWithPreExistingSecurityContext() throws Exception
+    public void testSecuredWithPreExistingSecurityContext() throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null);
@@ -520,28 +512,20 @@
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList()) ;
 
-        Message message = MessageFactory.getInstance().getMessage();
-
-        Subject subject = new Subject();
-        //  add principal
-        User user = new User("AustinPowerwich");
+        final Subject subject = new Subject();
+        final User user = new User("AustinPowerwich");
+        final byte[] publicCred = "publicsecret".getBytes();
         subject.getPrincipals().add(user);
-        //  add public credentials
-        byte[] publicCred = "publicsecret".getBytes();
         subject.getPublicCredentials().add(publicCred);
-        //  add private credentials
-        byte[] privateCred = "privatesecret".getBytes();
-        subject.getPrivateCredentials().add(privateCred);
 
-        //  create and encrypt the security context. This simulates a call for a service
-        //  that has already been authentcated..
-        SecurityContext securityContext = new SecurityContext(subject, SecurityContext.getConfigurationTimeout());
-        SealedObject sealedObject = SecurityContext.encryptContext(securityContext);
+        //  Create and encrypt the security context. This simulates a call for a service that has already been authentcated.
+        final SecurityContext securityContext = new SecurityContext(subject, SecurityContext.getConfigurationTimeout());
+        final SealedObject sealedObject = SecurityContext.encryptContext(securityContext);
+        final Message message = MessageFactory.getInstance().getMessage();
         message.getContext().setContext(SecurityService.CONTEXT, sealedObject);
 
-        final boolean result = pipeline.process(message);
-
-        assertTrue(result);
+        final boolean processingResult = pipeline.process(message);
+        assertTrue(processingResult);
         assertEquals(user, MockSecuredActionProcessor.getSubject().getPrincipals().iterator().next());
 
         assertNull(message.getContext().getContext(SecurityService.CONTEXT));
@@ -550,7 +534,7 @@
         checkOrder(MockActionInfo.getDestroyList()) ;
     }
 
-    public void testSecuredWithExistingSecurityContextExpired() throws Exception
+    public void testSecuredWithExistingSecurityContextWhichHasExpired() throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null);
@@ -562,7 +546,6 @@
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList()) ;
 
-        Message message = MessageFactory.getInstance().getMessage();
 
         Subject subject = new Subject();
         //  add principal
@@ -571,21 +554,19 @@
         //  add public credentials
         byte[] publicCred = "publicsecret".getBytes();
         subject.getPublicCredentials().add(publicCred);
-        //  add private credentials
-        byte[] privateCred = "privatesecret".getBytes();
-        subject.getPrivateCredentials().add(privateCred);
 
-        //  create and encrypt the security context. This simulates a call for a service
+        //  Create and encrypt the security context. This simulates a call for a service
         //  that has already been authentcated...but with a very short timeout.
-        SecurityContext securityContext = new SecurityContext(subject, 10);
+        final SecurityContext securityContext = new SecurityContext(subject, 10);
 
         TimeUnit.SECONDS.sleep(1);
 
-        SealedObject sealedObject = SecurityContext.encryptContext(securityContext);
+        final SealedObject sealedObject = SecurityContext.encryptContext(securityContext);
+        final Message message = MessageFactory.getInstance().getMessage();
         message.getContext().setContext(SecurityService.CONTEXT, sealedObject);
 
-        boolean process = pipeline.process(message);
-        assertFalse(process);
+        final boolean processingResult = pipeline.process(message);
+        assertFalse("Processing should have failed as the SecurityContext was invalid(expired)", processingResult);
 
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList()) ;
@@ -597,43 +578,39 @@
 
         //  setup config tree
         final ConfigTree configTree = new ConfigTree("parent") ;
-        final ConfigTree securityConfigTree = addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null, timeout);
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG, ListenerTagNames.MEP_ONE_WAY) ;
+        final ConfigTree securityConfigTree = addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null, timeout);
         addAction(configTree, MockSecuredActionProcessor.class.getName(), "process", null, null) ;
 
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
-
         final SecurityConfig securityConfig = SecurityConfigUtil.createSecurityConfig(securityConfigTree);
 
         final long contextTimeout = pipeline.getSecurityContextTimeout(securityConfig);
 
-        assertEquals(timeout, contextTimeout);
+        assertEquals("Timeout should be equals to the one in securty element(jboss-esb.xml) and not the global timeout(jbossesb-properties.xml",
+                timeout, contextTimeout);
 
         pipeline.destroy() ;
     }
 
     public void testSecuredWithSecurityContextDefaultTimeout() throws Exception
     {
-        final long timeout = 30000;
-
-        //  setup config tree
         final ConfigTree configTree = new ConfigTree("parent") ;
-        final ConfigTree securityConfigTree = addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null);
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG, ListenerTagNames.MEP_ONE_WAY) ;
+        final ConfigTree securityConfigTree = addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", null);
         addAction(configTree, MockSecuredActionProcessor.class.getName(), "process", null, null) ;
 
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
 
         final SecurityConfig securityConfig = SecurityConfigUtil.createSecurityConfig(securityConfigTree);
-
         final long contextTimeout = pipeline.getSecurityContextTimeout(securityConfig);
 
-        assertEquals(timeout, contextTimeout);
+        assertEquals(30000, contextTimeout);
 
         pipeline.destroy() ;
     }
 
-    public void testSecuredWithSecurityContextRolesAllowedNegativeCheck() throws Exception
+    public void testSecuredWithSecurityContextAndInvalidRoles() throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG, ListenerTagNames.MEP_ONE_WAY) ;
@@ -645,28 +622,19 @@
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList()) ;
 
-        Message message = MessageFactory.getInstance().getMessage();
-
-        Subject subject = new Subject();
-        User user = new User("AustinPowerwich");
+        final Subject subject = new Subject();
+        final User user = new User("AustinPowerwich");
         subject.getPrincipals().add(user);
-        byte[] publicCred = "publicsecret".getBytes();
+        final byte[] publicCred = "publicsecret".getBytes();
         subject.getPublicCredentials().add(publicCred);
-        byte[] privateCred = "privatesecret".getBytes();
-        subject.getPrivateCredentials().add(privateCred);
-        SecurityContext securityContext = new SecurityContext(subject, SecurityContext.getConfigurationTimeout());
-        SealedObject sealedObject = SecurityContext.encryptContext(securityContext);
+
+        final SecurityContext securityContext = new SecurityContext(subject, SecurityContext.getConfigurationTimeout());
+        final SealedObject sealedObject = SecurityContext.encryptContext(securityContext);
+        final Message message = MessageFactory.getInstance().getMessage();
         message.getContext().setContext(SecurityService.CONTEXT, sealedObject);
 
-        try
-        {
-            pipeline.process(message);
-        }
-        catch(final Exception e)
-        {
-            e.printStackTrace();
-            assertTrue (e instanceof SecurityServiceException);
-        }
+        final boolean processingResult = pipeline.process(message);
+        assertFalse("Processing should have failed as the caller was not in any of the allowed roles", processingResult);
 
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList()) ;

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecurityContextPropagator.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecurityContextPropagator.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecurityContextPropagator.java	2008-10-21 12:10:18 UTC (rev 23536)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors 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.soa.esb.listeners.message;
+
+import java.util.Set;
+
+import org.jboss.internal.soa.esb.services.security.SecurityContextPropagator;
+import org.jboss.soa.esb.services.security.SecurityConfig;
+import org.jboss.soa.esb.services.security.SecurityContext;
+
+/**
+ * Mock SecurityContextPropagator used in unit tests.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ */
+public class MockSecurityContextPropagator implements SecurityContextPropagator
+{
+    private static boolean pushCalled;
+    private static SecurityContext pushSecurityContext;
+
+    private static boolean popCalled;
+    private static SecurityContext popSecurityContext;
+
+    public void popSecurityContext(final SecurityContext context, final SecurityConfig config)
+    {
+        popCalled = true;
+    }
+
+    public void pushSecurityContext(final SecurityContext context, final Set<?> creds, final SecurityConfig config)
+    {
+        pushCalled = true;
+    }
+
+    public static boolean wasPopCalled()
+    {
+        return popCalled;
+    }
+
+    public static boolean wasPushCalled()
+    {
+        return pushCalled;
+    }
+
+    public static SecurityContext getPopSecurityContext()
+    {
+        return popSecurityContext;
+    }
+
+    public static SecurityContext getPushSecurityContext()
+    {
+        return pushSecurityContext;
+    }
+
+}

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/security-properties.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/security-properties.xml	2008-10-21 06:48:18 UTC (rev 23535)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/security-properties.xml	2008-10-21 12:10:18 UTC (rev 23536)
@@ -45,6 +45,7 @@
     	<property name="org.jboss.soa.esb.services.security.sealKeySize" value="168"/>
     	
     	<property name="org.jboss.soa.esb.services.security.contextTimeout" value="30000"/>
+    	<property name="org.jboss.soa.esb.services.security.contextPropagatorImplementationClass" value="org.jboss.soa.esb.listeners.message.MockSecurityContextPropagator"/>
     	
     	<property name="org.jboss.soa.esb.services.security.publicKeystore" value="publicKeyStore"/>
     	<property name="org.jboss.soa.esb.services.security.publicKeystorePassword" value="testKeystorePassword"/>




More information about the jboss-svn-commits mailing list