[jboss-svn-commits] JBL Code SVN: r23048 - in labs/jbossesb/branches/JBESB_4_4_GA_CP/product: rosetta/src/org/jboss/internal/soa/esb/services/security and 6 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Sep 24 10:06:28 EDT 2008


Author: beve
Date: 2008-09-24 10:06:27 -0400 (Wed, 24 Sep 2008)
New Revision: 23048

Added:
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecuredActionProcessor.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/privateKeyStore
   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/services/security/privateKeyStore
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/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/client/ServiceInvoker.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/src/org/jboss/soa/esb/services/security/SecurityContext.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityService.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JaasSecurityServiceUnitTest.java
   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/services/security/SecurityContextUnitTest.java
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/security-properties.xml
Log:
Work for https://jira.jboss.org/jira/browse/JBESB-2068 "Revisit core security integration"


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/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-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JaasSecurityService.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -33,6 +33,8 @@
 
 import org.apache.log4j.Logger;
 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.common.Environment;
@@ -109,7 +111,6 @@
 	 */
 	public void authenticate(final SecurityConfig config, SecurityContext securityContext, final AuthenticationRequest authRequest) throws SecurityServiceException
 	{
-		AssertArgument.isNotNull(securityContext, "securityContext");
 		AssertArgument.isNotNull(config, "config");
 
 		LoginContext loginContext;
@@ -136,16 +137,17 @@
     		//	add a runAs group if specified
     		addRunAs(runAs, subject);
 
-    		//  check that the caller belongs to one of the allowed roles
-    		List<String> rolesAllowed = config.getRolesAllowed();
-    		if (!rolesAllowed.isEmpty())
-    		{
-        		boolean checkRolesAllowed = checkRolesAllowed(config.getRolesAllowed(), securityContext);
-        		if (!checkRolesAllowed)
-        		{
-        			throw new SecurityServiceException("Caller did not belong to any of the rolesAllowed " + config.getRolesAllowed());
-        		}
-    		}
+    		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)
 		{
@@ -154,8 +156,13 @@
 
 	}
 
-	private boolean checkRolesAllowed(final List<String> rolesAllowed, SecurityContext securityContext)
+	public boolean checkRolesAllowed(final List<String> rolesAllowed, SecurityContext securityContext)
 	{
+	    if (rolesAllowed.isEmpty())
+	    {
+	        return true;
+	    }
+
 	    for (String roleName : rolesAllowed)
         {
 	        boolean isInRole = securityContext.isCallerInRole(roleName);

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java	2008-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -19,15 +19,18 @@
  */
 package org.jboss.soa.esb.client;
 
+import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
 import javax.crypto.SealedObject;
+import javax.security.auth.Subject;
 
 import org.apache.log4j.Logger;
 import org.jboss.internal.soa.esb.addressing.helpers.EPRHelper;
 import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.internal.soa.esb.services.security.PrivateCryptoUtil;
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.Service;
 import org.jboss.soa.esb.addressing.EPR;
@@ -60,6 +63,7 @@
 import org.jboss.soa.esb.services.registry.ServiceNotFoundException;
 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.util.ClassUtil;
 
 /**
@@ -319,11 +323,21 @@
             while ((epr = loadBalancer.chooseEPR(serviceClusterInfo)) != null) {
             	try
             	{
-            	    byte[] encrypted = SecurityContext.getContext();
-            	    if (encrypted != null)
+            	    final Subject subject = Subject.getSubject(AccessController.getContext());
+            	    if (subject != null)
             	    {
-                	    message.getProperties().setProperty(SecurityService.CONTEXT, encrypted);
+            	        logger.info("Subject in ServiceInvoker " + subject);
+                        try
+                        {
+                			byte[] encrypted = PrivateCryptoUtil.INSTANCE.encrypt(new SecurityContext(subject));
+                    	    message.getProperties().setProperty(SecurityService.CONTEXT, encrypted);
+                        }
+                        catch (final SecurityServiceException e)
+                        {
+                            logger.error("Could not encrypt the security conext. Will not be added to the outgoing message", e);
+                        }
             	    }
+
 	                replyMessage = eprInvoker.attemptDelivery(message, epr);
 	                if (replyMessage != null) {
                         if (Type.isFaultMessage(replyMessage)) {

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-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -22,6 +22,7 @@
 
 package org.jboss.soa.esb.listeners.message;
 
+import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -30,7 +31,6 @@
 import javax.xml.validation.Schema;
 
 import org.apache.log4j.Logger;
-import org.jboss.internal.soa.esb.services.security.PrivateCryptoUtil;
 import org.jboss.internal.soa.esb.util.XMLHelper;
 import org.jboss.soa.esb.ConfigurationException;
 import org.jboss.soa.esb.actions.ActionLifecycle;
@@ -121,6 +121,9 @@
          */
 	private final boolean defaultProcessing ;
 
+	/**
+	 * ESB Service Security configuration information.
+	 */
 	private SecurityConfig securityConf;
 
 	/**
@@ -305,7 +308,7 @@
 		if (securityConfigs.length > 0)
 		{
 			securityConf = SecurityConfigUtil.createSecurityConfig(securityConfigs[0]);
-			LOGGER.info(securityConf);
+			LOGGER.debug(securityConf);
 			final SecurityService securitySerivce = SecurityServiceFactory.getSecurityService();
 			securitySerivce.configure();
 			securitySerivce.refreshSecurityConfig();
@@ -368,9 +371,22 @@
 				LOGGER.debug("pipeline process for message: "+message.getHeader());
 			}
 
-			if (securityConf != null)
+			SecurityContext securityContext = null;
+			try
+            {
+			    // Check if a encrypted SecurityContext was passed with the Message to this service.
+                securityContext = SecurityContext.decryptContext((byte[])message.getProperties().getProperty(SecurityService.CONTEXT));
+            }
+			catch (final SecurityServiceException e)
+            {
+			    LOGGER.error("Security exception: ", e);
+			    // just make sure the securityContext is null. This will trigger a new auth if security is enabled.
+			    securityContext = null;
+            }
+
+			if (securityConf != null || securityContext != null)
 			{
-				return processPipelineSecured(message);
+				return processPipelineSecured(message, securityContext);
 			}
 			else
 			{
@@ -392,67 +408,61 @@
 		}
 	}
 
-	private boolean processPipelineSecured(final Message message)
+	private boolean processPipelineSecured(final Message message, SecurityContext securityContext)
 	{
 		final Call callDetails = new Call() ;
 		callDetails.copy(message.getHeader().getCall()) ;
 
-		SecurityContext securityContext = null;
 		try
 		{
-		    boolean authenticate = true;
-		    //  get the security context from the message is one exists, else create a new one.
-		    byte[] bytes = (byte[]) message.getProperties().getProperty(SecurityService.CONTEXT);
-		    if (bytes != null)
+		    // always perform authentication if the service is security enabled.
+		    if (securityConf != null )
 		    {
-		        try
+		        if (securityContext == null)
 		        {
-    		        //   try to decrypt the security context.
-                    securityContext = (SecurityContext) PrivateCryptoUtil.INSTANCE.decrypt(bytes);
-                    authenticate = false;
-		        }
-		        catch(final SecurityServiceException e)
-		        {
-		            LOGGER.warn("The security context was not sealed from this JVM. Will try to re-authenticate the user",e);
-		        }
-		    }
-		    else
-		    {
-                securityContext = new SecurityContext();
-		    }
+		            // no existing security context exist. Create one to drive the autentication.
+    		        securityContext = new SecurityContext();
 
-		    if (authenticate)
-		    {
-    			// 	get the authentication request if one exists.
-        		byte[] encrypted = (byte[]) message.getProperties().getProperty(SecurityService.AUTH_REQUEST);
-        		AuthenticationRequest authRequest = (AuthenticationRequest) PublicCryptoUtil.INSTANCE.decrypt(encrypted);
+        			// 	get the authentication request from the message
+            		byte[] encrypted = (byte[]) message.getProperties().getProperty(SecurityService.AUTH_REQUEST);
+            		AuthenticationRequest authRequest = (AuthenticationRequest) PublicCryptoUtil.INSTANCE.decrypt(encrypted);
 
-        		//	perform the authentication
-    			SecurityServiceFactory.getSecurityService().authenticate(securityConf, securityContext, authRequest);
+            		//  authenticate the caller
+        			SecurityServiceFactory.getSecurityService().authenticate(securityConf, securityContext, authRequest);
+		        }
+		        /*
+		         * The SecurityContext was not null so we were able to decrypt the security context
+		         * and this is a valid authenticated request and re-authentication is not done.
+		         */
 
-    			//  seal the security context add as a thread local
-    			SecurityContext.setContext(PrivateCryptoUtil.INSTANCE.encrypt(securityContext));
+		        // check the allowed roles if configured.
+        		boolean checkRolesAllowed = SecurityServiceFactory.getSecurityService().checkRolesAllowed(securityConf.getRolesAllowed(), securityContext);
+        		if (!checkRolesAllowed)
+        		{
+        			throw new SecurityServiceException("Caller did not belong to any of the rolesAllowed " + securityConf.getRolesAllowed());
+        		}
 		    }
 		}
 		catch (final SecurityServiceException e)
 		{
-			LOGGER.error( "Authentication exception : ", e);
+			LOGGER.error( "SecurityService exception : ", e);
 			faultTo(callDetails, Factory.createErrorMessage(Factory.UNEXPECTED_ERROR, message, e));
 			return false;
 		}
 		catch (final ConfigurationException e)
 		{
-			LOGGER.error( "Authentication exception : ", e);
+			LOGGER.error( "SecurityService exception : ", e);
 			faultTo(callDetails, Factory.createErrorMessage(Factory.UNEXPECTED_ERROR, message, e));
 			return false;
 		}
 		finally
 		{
-			//	always remove the authentication request and security context as they contains sensitive information
+		    // always remove the security context
+    		message.getProperties().remove(SecurityService.CONTEXT);
     		message.getProperties().remove(SecurityService.AUTH_REQUEST);
-    		message.getProperties().remove(SecurityService.CONTEXT);
 		}
 
+		// the work to be performed in the context of the authenticated caller
 		PrivilegedAction<Boolean> action = new PrivilegedAction<Boolean>()
 		{
 			public Boolean run()
@@ -461,11 +471,8 @@
 			}
 		};
 
-		Boolean processResult = (Boolean) Subject.doAsPrivileged(securityContext.getSubject(), action, null);
+		Boolean processResult = (Boolean)Subject.doAsPrivileged(securityContext.getSubject(), action, null);
 
-		//  unset the security context from the thread local
-		SecurityContext.setContext(null);
-
 		return processResult.booleanValue();
 	}
 

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java	2008-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -22,17 +22,25 @@
 
 import static org.jboss.soa.esb.services.security.principals.Group.ROLES_GROUP_NAME;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.security.Principal;
 import java.security.acl.Group;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Set;
 
 import javax.security.auth.Subject;
 
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.internal.soa.esb.services.security.PrivateCryptoUtil;
+import org.jboss.soa.esb.services.security.auth.AuthenticationRequest;
+import org.mvel.ast.AssertNode;
+
 /**
- * Security Context contains security related information that
- * is not sensitive.
+ * Security Context contains security related information.
  * <p/>
  * Note that even though a Subject object instance is serialiable,
  * its private and public credentials are not(they are transient).
@@ -47,20 +55,12 @@
 {
 	private static final long serialVersionUID = 1L;
 
-	private static ThreadLocal<byte[]> context = new ThreadLocal<byte[]>();
+	private final Subject subject;
 
-	public static byte[] getContext()
-	{
-	    return context.get();
-	}
+    private Set<?> pubCredentials;
 
-	public static void setContext(final byte[] encrypted)
-	{
-	    context.set(encrypted);
-	}
+    private Set<?> privCredentials;
 
-	private final Subject subject;
-
 	public SecurityContext()
 	{
 		subject = new Subject();
@@ -68,6 +68,7 @@
 
 	public SecurityContext(Subject subject)
 	{
+	    AssertArgument.isNotNull(subject, "subject");
 		this.subject = subject;
 	}
 
@@ -107,9 +108,106 @@
         return false;
 	}
 
-	public Set<? extends Principal> getPrincipals()
+	private void writeObject(final ObjectOutputStream out) throws IOException
 	{
-		return subject.getPrincipals();
+	   out.defaultWriteObject();
+	   out.writeObject(subject.getPrivateCredentials());
+	   out.writeObject(subject.getPublicCredentials());
 	}
 
+	private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException
+	{
+	   in.defaultReadObject();
+	   privCredentials = (Set<?>) in.readObject();
+	   pubCredentials = (Set<?>) in.readObject();
+	}
+
+	final Set<? extends Principal> getPrincipals()
+	{
+		return Collections.unmodifiableSet(subject.getPrincipals());
+	}
+
+    final Set<?> getPubCredentials()
+    {
+        return Collections.unmodifiableSet(pubCredentials);
+    }
+
+    public Set<?> getPrivCredentials()
+    {
+        return Collections.unmodifiableSet(privCredentials);
+    }
+
+    /**
+     * Will check if the passed in {@link AuthenticationRequest} contains the
+     * same security information (Principal and credentials) as the this context.
+     *
+     * @param authrequest - the authentication request to compare
+     * @return true - if this security context has the same principal and credentials as the passed in authentication request.
+     */
+    public boolean compareTo(final AuthenticationRequest authrequest)
+    {
+        if ( authrequest == null )
+        {
+            return false;
+        }
+
+        final Principal authPrincipal = authrequest.getPrincipal();
+        if (subject.getPrincipals().contains(authPrincipal))
+        {
+            final Set<?> authCredentials = authrequest.getCredentials();
+
+            // check if the auth request credentials exist as a public credential
+            final Set<Object> publicCredentials = subject.getPublicCredentials();
+            for (final Object object : authCredentials)
+            {
+                if (publicCredentials.contains(object))
+                {
+                    return true;
+                }
+            }
+
+            // check if the auth request credentials exist as a public credential
+            final Set<Object> privateCredentials = subject.getPrivateCredentials();
+            for (final Object object : authCredentials)
+            {
+                if (privateCredentials.contains(object))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public static SecurityContext decryptContext(final byte[] encrypt) throws SecurityServiceException
+    {
+        SecurityContext context = null;
+        if (encrypt == null)
+            return context;
+
+        Serializable decrypted = PrivateCryptoUtil.INSTANCE.decrypt(encrypt);
+        if (decrypted instanceof SecurityContext)
+        {
+           context = (SecurityContext) decrypted;
+           final Subject subject = context.getSubject();
+           final Set<?> publCreds = context.getPubCredentials();
+           if (publCreds != null )
+           {
+               subject.getPublicCredentials().addAll(publCreds);
+           }
+           final Set<?> privCreds = context.getPrivCredentials();
+           if (privCreds != null)
+           {
+               subject.getPrivateCredentials().addAll(privCreds);
+           }
+        }
+        return context;
+    }
+
+    public static byte[] encryptContext(final SecurityContext context) throws SecurityServiceException
+    {
+        return PrivateCryptoUtil.INSTANCE.encrypt(context);
+    }
+
 }

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityService.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityService.java	2008-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityService.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -21,6 +21,7 @@
 package org.jboss.soa.esb.services.security;
 
 import java.security.Principal;
+import java.util.List;
 
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginException;
@@ -62,6 +63,16 @@
 	void authenticate(final SecurityConfig securityConfig, final SecurityContext securityContext, final AuthenticationRequest authRequest) throws SecurityServiceException;
 
 	/**
+	 * Check if the the SecurityContext has a principal that is a member of one
+	 * of the passed in rolesAllowed list.
+	 *
+	 * @param rolesAllowed - list or allowed roles
+	 * @param securityContext - the security context
+	 * @return true - if the SecurityContext has a principal that is a member of one the roles.
+	 */
+	boolean checkRolesAllowed(final List<String> rolesAllowed, SecurityContext securityContext);
+
+	/**
 	 * Determines if the subject contains the passed in role in it's
 	 * set of Principals.
 	 *

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JaasSecurityServiceUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JaasSecurityServiceUnitTest.java	2008-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/internal/soa/esb/services/security/JaasSecurityServiceUnitTest.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -145,6 +145,8 @@
         SecurityConfig configInfo = builder.build();
         SecurityContext context = new SecurityContext(subject);
         service.authenticate( configInfo, context, null );
+        boolean checkRolesAllowed = service.checkRolesAllowed(configInfo.getRolesAllowed(), context);
+        assertTrue(checkRolesAllowed);
     }
 
 	@Test

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-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipelineUnitTest.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -22,21 +22,45 @@
 
 package org.jboss.soa.esb.listeners.message;
 
+import java.io.Serializable;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+
+import javax.security.auth.Subject;
+
+import junit.framework.JUnit4TestAdapter;
 import junit.framework.TestCase;
 
 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;
+import org.jboss.soa.esb.message.Message;
 import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.services.security.PublicCryptoUtil;
+import org.jboss.soa.esb.services.security.SecurityContext;
+import org.jboss.soa.esb.services.security.SecurityContextUnitTest;
+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;
+import org.jboss.soa.esb.services.security.principals.User;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.After;
+import org.junit.Before;
 
 public class ActionProcessingPipelineUnitTest extends TestCase
 {
-	public void testProperty() {
-		
+	private String jbossEsbProperties;
+
+    public void testProperty() {
+
 	}
-	
+
     @Override
     protected void setUp() throws Exception
     {
@@ -47,20 +71,26 @@
         com.arjuna.common.util.propertyservice.PropertyManager pm = ModulePropertyManager.getPropertyManager(ModulePropertyManager.DBSTORE_MODULE);
         pm.setProperty("javax.xml.registry.ConnectionFactoryClass", "org.apache.ws.scout.registry.ConnectionFactoryImpl");
         LifecycleResourceManager.getSingleton().associateDeployment(getClass().getCanonicalName()) ;
+
+        jbossEsbProperties = System.getProperty(Environment.PROPERTIES_FILE);
+        URL resource = ClassUtil.getResource("security-properties.xml", getClass());
+        System.setProperty(Environment.PROPERTIES_FILE, "abs://" + resource.getFile());
     }
-    
+
     @Override
     protected void tearDown() throws Exception
     {
         LifecycleResourceManager.getSingleton().disassociateDeployment(getClass().getCanonicalName()) ;
+        if ( jbossEsbProperties != null )
+            System.setProperty(Environment.PROPERTIES_FILE, jbossEsbProperties);
         super.tearDown();
     }
-    
+
     /*
      * Tests to run
      *  - create a pipeline with a failure, make sure failure is called in correct order and subsequent actions are not called.
      *    Check initialise and destroy called.
-     *  
+     *
      *  Do the above for each type of action.
      */
     public void testActionPipelineProcessor()
@@ -79,30 +109,30 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList(), 0, 2, 4) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4) ;
         checkOrder(MockActionInfo.getSuccessList(), 4, 2, 0) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         final boolean secondResult = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", secondResult) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 0, 2, 4) ;
         checkOrder(MockActionInfo.getSuccessList(), 4, 2, 0, 4, 2, 0) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList(), 4, 2, 0) ;
     }
-    
+
     public void testActionPipelineProcessorFailure()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionPipelineProcessor.class.getName(),
             null, null, null) ;
         addAction(configTree, MockActionPipelineProcessorFailure.class.getName(),
@@ -113,7 +143,7 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList(), 0, 2, 4) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertFalse("Pipeline process succeeded", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2) ;
@@ -129,14 +159,14 @@
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList(), 4, 2, 0) ;
     }
-    
+
     public void testOverriddenActionPipelineProcessor()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionPipelineProcessor.class.getName(),
             "process", null, null) ;
         addAction(configTree, MockActionPipelineProcessor.class.getName(),
@@ -149,30 +179,30 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList(), 0, 2, 4, 6) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 6, 7) ;
         checkOrder(MockActionInfo.getSuccessList(), 7, 4, 3, 0) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         final boolean secondResult = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", secondResult) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 6, 7, 0, 2, 4, 6, 7) ;
         checkOrder(MockActionInfo.getSuccessList(), 7, 4, 3, 0, 7, 4, 3, 0) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList(), 6, 4, 2, 0) ;
     }
-    
+
     public void testOverriddenActionPipelineProcessorFailure()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionPipelineProcessor.class.getName(),
             "process", null, null) ;
         addAction(configTree, MockActionPipelineProcessor.class.getName(),
@@ -185,30 +215,30 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList(), 0, 2, 4, 6) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertFalse("Pipeline process succeeded", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4) ;
         checkOrder(MockActionInfo.getSuccessList()) ;
         checkOrder(MockActionInfo.getExceptionList(), 5, 2, 0) ;
-        
+
         final boolean secondResult = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertFalse("Pipeline process succeeded", secondResult) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 0, 2, 4) ;
         checkOrder(MockActionInfo.getSuccessList()) ;
         checkOrder(MockActionInfo.getExceptionList(), 5, 2, 0, 5, 2, 0) ;
-        
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList(), 6, 4, 2, 0) ;
     }
-    
+
     public void testOverriddenActionLifecycleProcessor()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionLifecycleProcessor.class.getName(),
             "process", null, null) ;
         addAction(configTree, MockActionLifecycleProcessor.class.getName(),
@@ -221,30 +251,30 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList(), 0, 2, 4, 6) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 6, 7) ;
         checkOrder(MockActionInfo.getSuccessList(), 7, 2) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         final boolean secondResult = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", secondResult) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 6, 7, 0, 2, 4, 6, 7) ;
         checkOrder(MockActionInfo.getSuccessList(), 7, 2, 7, 2) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList(), 6, 4, 2, 0) ;
     }
-    
+
     public void testOverriddenActionLifecycleProcessorFailure()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionLifecycleProcessor.class.getName(),
             "process", null, null) ;
         addAction(configTree, MockActionLifecycleProcessor.class.getName(),
@@ -257,30 +287,30 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList(), 0, 2, 4, 6) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertFalse("Pipeline process succeeded", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4) ;
         checkOrder(MockActionInfo.getSuccessList()) ;
         checkOrder(MockActionInfo.getExceptionList(), 5) ;
-        
+
         final boolean secondResult = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertFalse("Pipeline process succeeded", secondResult) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 0, 2, 4) ;
         checkOrder(MockActionInfo.getSuccessList()) ;
         checkOrder(MockActionInfo.getExceptionList(), 5, 5) ;
-        
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList(), 6, 4, 2, 0) ;
     }
-    
+
     public void testOverriddenActionProcessor()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionProcessor.class.getName(),
             "process", null, null) ;
         addAction(configTree, MockActionProcessor.class.getName(),
@@ -293,30 +323,30 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList()) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 6, 7) ;
         checkOrder(MockActionInfo.getSuccessList(), 7, 2) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         final boolean secondResult = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertTrue("Pipeline process failure", secondResult) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 6, 7, 8, 10, 12, 14, 15) ;
         checkOrder(MockActionInfo.getSuccessList(), 7, 2, 15, 10) ;
         checkOrder(MockActionInfo.getExceptionList()) ;
-        
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList()) ;
     }
-    
+
     public void testOverriddenActionProcessorFailure()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionProcessor.class.getName(),
             "process", null, null) ;
         addAction(configTree, MockActionProcessor.class.getName(),
@@ -329,23 +359,23 @@
         final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
         pipeline.initialise() ;
         checkOrder(MockActionInfo.getInitialiseList()) ;
-        
+
         final boolean result = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertFalse("Pipeline process succeeded", result) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4) ;
         checkOrder(MockActionInfo.getSuccessList()) ;
         checkOrder(MockActionInfo.getExceptionList(), 5) ;
-        
+
         final boolean secondResult = pipeline.process(MessageFactory.getInstance().getMessage()) ;
         assertFalse("Pipeline process succeeded", secondResult) ;
         checkOrder(MockActionInfo.getProcessList(), 0, 2, 4, 6, 8, 10) ;
         checkOrder(MockActionInfo.getSuccessList()) ;
         checkOrder(MockActionInfo.getExceptionList(), 5, 11) ;
-        
+
         pipeline.destroy() ;
         checkOrder(MockActionInfo.getDestroyList()) ;
     }
-    
+
     public void testErrorActionProcessorException() throws Exception
 	{
 		final ConfigTree configTree = new ConfigTree("parent");
@@ -365,13 +395,13 @@
 		final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(
 				configTree);
 		pipeline.initialise();
-		
+
 		final boolean result = pipeline.process(MessageFactory.getInstance()
 				.getMessage());
-		
+
 		assertFalse(result);
 	}
-    
+
     public void testNPEActionProcessorException() throws Exception
 	{
 		final ConfigTree configTree = new ConfigTree("parent");
@@ -391,20 +421,20 @@
 		final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(
 				configTree);
 		pipeline.initialise();
-		
+
 		final boolean result = pipeline.process(MessageFactory.getInstance()
 				.getMessage());
-		
+
 		assertFalse(result);
 	}
-    
+
     public void testInvalidConstructor()
         throws Exception
     {
         final ConfigTree configTree = new ConfigTree("parent") ;
         configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG,
         		ListenerTagNames.MEP_ONE_WAY) ;
-        
+
         addAction(configTree, MockActionPipelineProcessorConstructorFailure.class.getName(),
             null, null, null) ;
         try
@@ -414,10 +444,118 @@
         }
         catch (final ConfigurationException ce)
         {
-            
+
         }
     }
 
+    public void testSecuredServiceWithoutExistingSecurityContext() throws Exception
+    {
+        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) ;
+        pipeline.initialise() ;
+        checkOrder(MockActionInfo.getInitialiseList()) ;
+
+        Message message = MessageFactory.getInstance().getMessage();
+
+        //  create an AuthenticationRequest which is needed to authenticate if the security
+        AuthenticationRequest build = new AuthenticationRequestImpl.Builder().build();
+        message.getProperties().setProperty(SecurityService.AUTH_REQUEST, PublicCryptoUtil.INSTANCE.encrypt((Serializable) build));
+
+        final boolean result = pipeline.process(message);
+        assertTrue(result);
+        assertEquals(new TestPrincipal("test").getName(), MockSecuredActionProcessor.getSubject().getPrincipals().iterator().next().getName());
+
+        pipeline.destroy() ;
+        checkOrder(MockActionInfo.getDestroyList()) ;
+    }
+
+    public void testSecuredServiceWithPreExistingSecurityContext() throws Exception
+    {
+        final ConfigTree configTree = new ConfigTree("parent") ;
+        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) ;
+        pipeline.initialise() ;
+        checkOrder(MockActionInfo.getInitialiseList()) ;
+
+        Message message = MessageFactory.getInstance().getMessage();
+
+        Subject subject = new Subject();
+        //  add principal
+        User user = new User("AustinPowerwich");
+        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);
+        byte[] encrypt = SecurityContext.encryptContext(securityContext);
+
+        message.getProperties().setProperty(SecurityService.CONTEXT, encrypt);
+
+        final boolean result = pipeline.process(message);
+
+        assertTrue(result);
+        assertEquals(user, MockSecuredActionProcessor.getSubject().getPrincipals().iterator().next());
+
+        pipeline.destroy() ;
+        checkOrder(MockActionInfo.getDestroyList()) ;
+    }
+
+    public void testSecuredWithSecurityContextRolesAllowedNegativeCheck() throws Exception
+    {
+        final ConfigTree configTree = new ConfigTree("parent") ;
+        configTree.setAttribute(ListenerTagNames.MEP_ATTRIBUTE_TAG, ListenerTagNames.MEP_ONE_WAY) ;
+        addSecurityConfig(configTree, "adminRole", null, "SuccessfulLogin", "noRole");
+
+        addAction(configTree, MockSecuredActionProcessor.class.getName(), "process", null, null) ;
+
+        final ActionProcessingPipeline pipeline = new ActionProcessingPipeline(configTree) ;
+        pipeline.initialise() ;
+        checkOrder(MockActionInfo.getInitialiseList()) ;
+
+        Message message = MessageFactory.getInstance().getMessage();
+
+        Subject subject = new Subject();
+        User user = new User("AustinPowerwich");
+        subject.getPrincipals().add(user);
+        byte[] publicCred = "publicsecret".getBytes();
+        subject.getPublicCredentials().add(publicCred);
+        byte[] privateCred = "privatesecret".getBytes();
+        subject.getPrivateCredentials().add(privateCred);
+        SecurityContext securityContext = new SecurityContext(subject);
+        byte[] encrypt = SecurityContext.encryptContext(securityContext);
+
+        message.getProperties().setProperty(SecurityService.CONTEXT, encrypt);
+
+        try
+        {
+            pipeline.process(message);
+        }
+        catch(final Exception e)
+        {
+            e.printStackTrace();
+            assertTrue (e instanceof SecurityServiceException);
+        }
+
+        pipeline.destroy() ;
+        checkOrder(MockActionInfo.getDestroyList()) ;
+    }
+
     public static void addAction(final ConfigTree configTree, final String actionName) {
         addAction(configTree, actionName, null, null, null);
     }
@@ -440,17 +578,36 @@
             actionChild.setAttribute(ListenerTagNames.EXCEPTION_METHOD_TAG, exceptionOverride) ;
         }
     }
-    
+
     private void checkOrder(final Integer[] list, int ... values)
     {
         final int numValues = (values == null ? 0 : values.length) ;
         final int listLength = (list == null ? 0 : list.length) ;
-        
+
         assertEquals("Unexpected list/values count", numValues, listLength) ;
-        
+
         for(int count = 0 ; count < numValues ; count++)
         {
             assertEquals("Unexpected call order at count " + count, values[count], list[count].intValue()) ;
         }
     }
+
+    private ConfigTree addSecurityConfig(
+            final ConfigTree parent,
+            final String runAs,
+            final String callerIdentity,
+            final String moduleName,
+            final String rolesAllowed)
+    {
+        final ConfigTree securityElement = new ConfigTree(ListenerTagNames.SECURITY_TAG, parent);
+        securityElement.setAttribute(ListenerTagNames.RUN_AS_TAG, runAs);
+        securityElement.setAttribute(ListenerTagNames.USE_CALLERS_IDENTIDY_TAG, callerIdentity);
+        securityElement.setAttribute(ListenerTagNames.MODULE_NAME_TAG, moduleName);
+        if ( rolesAllowed != null )
+        {
+            securityElement.setAttribute(ListenerTagNames.ROLES_ALLOWED, rolesAllowed);
+        }
+        return securityElement;
+    }
+
 }

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecuredActionProcessor.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecuredActionProcessor.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/MockSecuredActionProcessor.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, 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.soa.esb.listeners.message;
+
+import java.security.AccessController;
+
+import javax.security.auth.Subject;
+
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+
+public class MockSecuredActionProcessor
+{
+    private static Subject subject ;
+
+    public MockSecuredActionProcessor(final ConfigTree tree)
+    {
+    }
+
+    public Message process(Message message) throws ActionProcessingException
+    {
+        subject = Subject.getSubject(AccessController.getContext());
+        return message ;
+    }
+
+    public static Subject getSubject()
+    {
+        return subject;
+    }
+
+}

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/privateKeyStore
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/privateKeyStore
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: 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	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/listeners/message/security-properties.xml	2008-09-24 14:06:27 UTC (rev 23048)
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  JBoss, Home of Professional Open Source
+  Copyright 2006, JBoss Inc., and others contributors as indicated 
+  by the @authors tag. All rights reserved. 
+  See the copyright.txt in the distribution for a
+  full listing of individual contributors. 
+  This copyrighted material is made available to anyone wishing to use,
+  modify, copy, or redistribute it subject to the terms and conditions
+  of the GNU Lesser General Public License, v. 2.1.
+  This program is distributed in the hope that it will be useful, but WITHOUT A 
+  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,
+  v.2.1 along with this distribution; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+  MA  02110-1301, USA.
+  
+  (C) 2005-2006,
+  @author JBoss Inc.
+-->
+<!-- $Id: jbossesb-unittest-properties.xml $ -->
+<!--
+  These options are described in the JBossESB manual.
+  Defaults are provided here for convenience only.
+ 
+  Please read through this file prior to using the system, and consider
+  updating the specified entries.
+-->
+<esb
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:noNamespaceSchemaLocation="jbossesb-1_0.xsd">
+    <properties name="core">
+		<property name="org.jboss.soa.esb.jndi.server.context.factory" value="org.jnp.interfaces.NamingContextFactory"/>
+		<property name="org.jboss.soa.esb.jndi.server.url" value="${jboss.esb.bind.address}:1099"/>
+		<property name="org.jboss.soa.esb.persistence.connection.factory" 	value="org.jboss.internal.soa.esb.persistence.format.MessageStoreFactoryImpl"/>
+        <property name="org.jboss.soa.esb.loadbalancer.policy" value="org.jboss.soa.esb.listeners.ha.RoundRobin"/>
+        <property name="jboss.esb.invm.scope.default" value="NONE"/>
+    </properties>
+    <properties name="security">
+    	<property name="org.jboss.soa.esb.services.security.implementationClass" value="org.jboss.internal.soa.esb.services.security.JaasSecurityService"/>
+    	<property name="org.jboss.soa.esb.services.security.callbackHandler" value="org.jboss.internal.soa.esb.services.security.UserPassCallbackHandler"/>
+    	<property name="org.jboss.soa.esb.services.security.configUrl" value="jaas.login"/>
+    	
+    	<property name="org.jboss.soa.esb.services.security.privateKeystore" value="privateKeyStore"/>
+    	<property name="org.jboss.soa.esb.services.security.privateKeystorePassword" value="testKeystorePassword"/>
+    	<property name="org.jboss.soa.esb.services.security.privateKeyAlias" value="testAlias"/>
+    	<property name="org.jboss.soa.esb.services.security.privateKeyPassword" value="testPassword"/>
+    	
+    	<property name="org.jboss.soa.esb.services.security.publicKeystore" value="publicKeyStore"/>
+    	<property name="org.jboss.soa.esb.services.security.publicKeystorePassword" value="testKeystorePassword"/>
+    	<property name="org.jboss.soa.esb.services.security.publicKeyAlias" value="testAlias"/>
+    	<property name="org.jboss.soa.esb.services.security.publicKeyPassword" value="testPassword"/>
+    	<property name="org.jboss.soa.esb.services.security.publicKeyTransformation" value="RSA/ECB/PKCS1Padding"/>
+    </properties>
+    <properties name="registry">
+    	<property name="org.jboss.soa.esb.registry.queryManagerURI" value="org.apache.juddi.registry.local.InquiryService#inquire"/>
+    	<property name="org.jboss.soa.esb.registry.lifeCycleManagerURI" value="org.apache.juddi.registry.local.PublishService#publish"/>
+    	<property name="org.jboss.soa.esb.registry.implementationClass" value="org.jboss.internal.soa.esb.services.registry.JAXRRegistryImpl"/>
+    	<property name="org.jboss.soa.esb.registry.factoryClass" value="org.apache.ws.scout.registry.ConnectionFactoryImpl"/>
+    	<property name="org.jboss.soa.esb.registry.user" value="jbossesb"/>
+    	<property name="org.jboss.soa.esb.registry.password" value="password"/>
+    	<!-- the following parameter is scout specific to set the type of communication between scout and the UDDI (embedded, rmi, soap) -->
+    	<property name="org.jboss.soa.esb.scout.proxy.transportClass" value="org.apache.ws.scout.transport.LocalTransport"/>
+    </properties>
+    <properties name="transports" depends="core">
+    	<property name="org.jboss.soa.esb.mail.smtp.host" value="localhost"/>
+    	<property name="org.jboss.soa.esb.mail.smtp.user" value="jbossesb"/>
+    	<property name="org.jboss.soa.esb.mail.smtp.password" value=""/>
+    	<property name="org.jboss.soa.esb.mail.smtp.port" value="25"/>
+    	<property name="org.jboss.soa.esb.mail.smtp.auth" value="true"/>
+    	<property name="org.jboss.soa.esb.ftp.localdir" value="/tmp"/>
+    	<property name="org.jboss.soa.esb.ftp.remotedir" value="/tmp"/>
+    	<property name="org.jboss.soa.esb.jms.connectionPool" value="20"/>
+    	<property name="org.jboss.soa.esb.jms.sessionSleep" value="30"/>
+    </properties>
+    <properties name="connection">
+    	<property name="min-pool-size" value="5"/>
+    	<property name="max-pool=size" value="10"/>
+    	<property name="blocking-timeout-millis" value="5000"/>
+    	<property name="abandoned-connection-timeout" value="10000"/>
+    	<property name="abandoned-connection-time-interval" value="30000"/>
+    </properties>
+    <properties name="dbstore">
+    	
+    	<!--  connection manager type -->
+	    <!-- <property name="org.jboss.soa.esb.persistence.db.conn.manager" 		value="org.jboss.internal.soa.esb.persistence.manager.StandaloneConnectionManager"/>	 -->    
+	     <property name="org.jboss.soa.esb.persistence.db.conn.manager" value="org.jboss.internal.soa.esb.persistence.manager.J2eeConnectionManager"/>
+	    
+	    <!-- this property is only used if using the j2ee connection manager -->
+	    <property name="org.jboss.soa.esb.persistence.db.datasource.name" 	value="java:/JBossESBDS"/>
+		
+		<!-- standalone connection pooling settings -->
+		<property name="org.jboss.soa.esb.persistence.db.connection.url" 	value="jdbc:hsqldb:hsql://localhost:9001/"/>
+		<property name="org.jboss.soa.esb.persistence.db.jdbc.driver" 		value="org.hsqldb.jdbcDriver"/>
+		<property name="org.jboss.soa.esb.persistence.db.user" 				value="sa"/>
+		<property name="org.jboss.soa.esb.persistence.db.pwd" 				value=""/>		
+		<property name="org.jboss.soa.esb.persistence.db.pool.initial.size"	value="2"/>
+		<property name="org.jboss.soa.esb.persistence.db.pool.min.size"		value="2"/>
+		<property name="org.jboss.soa.esb.persistence.db.pool.max.size"		value="5"/>
+		<!--table managed by pool to test for valid connections - created by pool automatically -->
+		<property name="org.jboss.soa.esb.persistence.db.pool.test.table"	value="pooltest"/>		
+		<property name="org.jboss.soa.esb.persistence.db.pool.timeout.millis"	value="5000"/> 
+		
+    </properties>    
+    <properties name="filters">
+    	<property name="org.jboss.soa.esb.filter.1" value="org.jboss.internal.soa.esb.message.filter.MetaDataFilter"/>
+    	<property name="org.jboss.soa.esb.filter.2" value="org.jboss.internal.soa.esb.message.filter.GatewayFilter"/>
+    </properties>
+</esb>

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityContextUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityContextUnitTest.java	2008-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityContextUnitTest.java	2008-09-24 14:06:27 UTC (rev 23048)
@@ -2,17 +2,17 @@
  * 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
@@ -21,24 +21,47 @@
 package org.jboss.soa.esb.services.security;
 
 import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URL;
+import java.util.HashSet;
+
 import javax.security.auth.Subject;
 
+import junit.framework.JUnit4TestAdapter;
+
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.common.Environment;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.message.format.MessageType;
+import org.jboss.soa.esb.services.security.auth.AuthenticationRequest;
+import org.jboss.soa.esb.services.security.auth.AuthenticationRequestImpl;
 import org.jboss.soa.esb.services.security.principals.Group;
 import org.jboss.soa.esb.services.security.principals.Role;
 import org.jboss.soa.esb.services.security.principals.User;
+import org.jboss.soa.esb.util.ClassUtil;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
-import junit.framework.JUnit4TestAdapter;
-
 /**
- * 
+ *
  * @author <a href="mailto:dbevenius at redhat.com">Daniel Bevenius</a>
  *
  */
 public class SecurityContextUnitTest
 {
-	@Test
+	private String jbossEsbProperties;
+
+    @Test
 	public void isCallerInRole()
 	{
 		Subject subject = new Subject();
@@ -46,12 +69,138 @@
 		Group roles = new Group("Roles");
 		roles.addMember( new Role("Admin"));
 		subject.getPrincipals().add(roles);
-		
+
 		SecurityContext securityContext = new SecurityContext(subject);
 		boolean callerInRole = securityContext.isCallerInRole("Admin");
 		assertTrue( callerInRole );
 	}
 
+	@Test
+    public void serializeAndDeserialize() throws IOException, ClassNotFoundException
+    {
+        Subject subject = new Subject();
+        User user = new User("AustinPowerwich");
+        subject.getPrincipals().add(user);
+        byte[] publicCred = "secret".getBytes();
+        subject.getPublicCredentials().add(publicCred);
+
+        SecurityContext securityContext = new SecurityContext(subject);
+        assertEquals( user, securityContext.getSubject().getPrincipals().iterator().next() );
+        assertEquals( publicCred, securityContext.getSubject().getPublicCredentials().iterator().next());
+
+        //  serialize object
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bout);
+        out.writeObject(securityContext);
+
+        //  deserialize object
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream oin = new ObjectInputStream(bin);
+        Object readObject = oin.readObject();
+
+        //  assert that the content is still matches.
+        assertTrue (readObject instanceof SecurityContext);
+        SecurityContext deserialized = (SecurityContext)readObject;
+        assertEquals( user, deserialized.getSubject().getPrincipals().iterator().next() );
+        assertEquals( new String(publicCred), new String((byte[])deserialized.getPubCredentials().iterator().next()));
+    }
+
+	@Test
+    public void encryptThenSerializeAndDeserialize() throws IOException, ClassNotFoundException, SecurityServiceException
+    {
+        Subject subject = new Subject();
+        User user = new User("AustinPowerwich");
+        subject.getPrincipals().add(user);
+        byte[] publicCred = "secret".getBytes();
+        subject.getPublicCredentials().add(publicCred);
+
+        SecurityContext securityContext = new SecurityContext(subject);
+        Message message = MessageFactory.getInstance().getMessage(MessageType.JAVA_SERIALIZED);
+        byte[] encryptContext = SecurityContext.encryptContext(securityContext);
+        message.getProperties().setProperty(SecurityService.CONTEXT, encryptContext);
+
+
+        //  serialize object
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bout);
+        out.writeObject(message);
+
+        //  deserialize object
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream oin = new ObjectInputStream(bin);
+        Object readObject = oin.readObject();
+
+        //  assert that the content is still matches.
+        assertTrue (readObject instanceof Message);
+        Message deserializedMsg = (Message) readObject;
+        SecurityContext deserialized = SecurityContext.decryptContext((byte[]) deserializedMsg.getProperties().getProperty(SecurityService.CONTEXT));
+        assertEquals( user, deserialized.getSubject().getPrincipals().iterator().next() );
+        //assertEquals( new String(publicCred), new String((byte[])deserialized.getPubCredentials().iterator().next()));
+        assertEquals( new String(publicCred), new String((byte[])deserialized.getSubject().getPublicCredentials().iterator().next()));
+    }
+
+	@Test
+	public void decryptionConstructor() throws SecurityServiceException
+	{
+        Subject subject = new Subject();
+        User user = new User("AustinPowerwich");
+        subject.getPrincipals().add(user);
+        byte[] publicCred = "publicsecret".getBytes();
+        subject.getPublicCredentials().add(publicCred);
+        byte[] privateCred = "privatesecret".getBytes();
+        subject.getPrivateCredentials().add(privateCred);
+
+        SecurityContext securityContext = new SecurityContext(subject);
+        byte[] encrypt = SecurityContext.encryptContext(securityContext);
+        assertNotNull(encrypt);
+
+        SecurityContext decryptContext = SecurityContext.decryptContext(encrypt);
+        assertEquals( new String(publicCred), new String((byte[])decryptContext.getPubCredentials().iterator().next()));
+        assertEquals( new String(privateCred), new String((byte[])decryptContext.getPrivCredentials().iterator().next()));
+	}
+
+	@Test
+    public void compareTo() throws SecurityServiceException
+    {
+        Subject subject = new Subject();
+        User user = new User("AustinPowerwich");
+        subject.getPrincipals().add(user);
+        byte[] publicCred = "publicsecret".getBytes();
+        subject.getPublicCredentials().add(publicCred);
+        byte[] privateCred = "privatesecret".getBytes();
+        subject.getPrivateCredentials().add(privateCred);
+
+        SecurityContext securityContext = new SecurityContext(subject);
+
+        HashSet<Object> credentials = new HashSet<Object>();
+        credentials.add(publicCred);
+        credentials.add(privateCred);
+
+        AuthenticationRequest authRequest = new AuthenticationRequestImpl.Builder(user, credentials).build();
+        assertTrue(securityContext.compareTo(authRequest));
+
+        credentials = new HashSet<Object>();
+        credentials.add("public-modified-secret".getBytes());
+        authRequest = new AuthenticationRequestImpl.Builder(user, credentials).build();
+        assertFalse(securityContext.compareTo(authRequest));
+        assertFalse(securityContext.compareTo(null));
+    }
+
+	@Before
+    public void setup() throws ConfigurationException
+    {
+        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 )
+            System.setProperty(Environment.PROPERTIES_FILE, jbossEsbProperties);
+    }
+
 	public static junit.framework.Test suite()
 	{
 		return new JUnit4TestAdapter(SecurityContextUnitTest.class);

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/privateKeyStore
===================================================================
(Binary files differ)


Property changes on: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/privateKeyStore
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/security-properties.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/security-properties.xml	2008-09-24 13:37:13 UTC (rev 23047)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/security-properties.xml	2008-09-24 14:06:27 UTC (rev 23048)
@@ -42,6 +42,11 @@
     	<property name="org.jboss.soa.esb.services.security.callbackHandler" value="org.jboss.internal.soa.esb.services.security.UserPassCallbackHandler"/>
     	<property name="org.jboss.soa.esb.services.security.configUrl" value="jaas.login"/>
     	
+    	<property name="org.jboss.soa.esb.services.security.privateKeystore" value="privateKeyStore"/>
+    	<property name="org.jboss.soa.esb.services.security.privateKeystorePassword" value="testKeystorePassword"/>
+    	<property name="org.jboss.soa.esb.services.security.privateKeyAlias" value="testAlias"/>
+    	<property name="org.jboss.soa.esb.services.security.privateKeyPassword" value="testPassword"/>
+    	
     	<property name="org.jboss.soa.esb.services.security.publicKeystore" value="publicKeyStore"/>
     	<property name="org.jboss.soa.esb.services.security.publicKeystorePassword" value="testKeystorePassword"/>
     	<property name="org.jboss.soa.esb.services.security.publicKeyAlias" value="testAlias"/>




More information about the jboss-svn-commits mailing list