[jboss-svn-commits] JBL Code SVN: r25025 - in labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta: tests/src/org/jboss/soa/esb/services/security and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jan 30 13:51:32 EST 2009


Author: kevin.conner at jboss.com
Date: 2009-01-30 13:51:32 -0500 (Fri, 30 Jan 2009)
New Revision: 25025

Added:
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java
Modified:
   labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java
Log:
Fix security context propagation in ServiceInvoker: JBESB-2324

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	2009-01-30 17:26:58 UTC (rev 25024)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java	2009-01-30 18:51:32 UTC (rev 25025)
@@ -296,8 +296,6 @@
         if (sealedObject != null)
         {
             message.getContext().setContext(SecurityService.CONTEXT, sealedObject);
-            // clear the security context from the thread local.
-            SecurityContext.setSecurityContext(null);
         }
         /*
          * Re-attach encrypted AuthenticationRequest to outgoing message.
@@ -306,95 +304,98 @@
         if (encryptedAuthRequest != null)
         {
             message.getContext().setContext(SecurityService.AUTH_REQUEST, encryptedAuthRequest);
-            // clear the auth request from the thread local.
-            AuthenticationRequestImpl.setEncryptedAuthRequest(null);
         }
 
-        //We are removing dead EPRs from the serviceClusterInfo. *Previous* deliveries maybe have
-        //removed EPRs that have now come back to life. We should try once more to pull a fresh list of EPRS
-        //from the registry before we give up (and fail-over to redelivery at a later time in the care
-        //of asyncDeliver). I think the end-user expects the message to be delivered successfully if there
-        //is a healhty EPR out there. So this is really for EPR cache management (serviceClusterInfo will
-        //be empty when going for the 2nd attempt, or else there delivery was successful and there will be
-        //no second attempt!).
-        while (staleEPRCache) {
-            if ((serviceClusterInfo.getEPRs().size() == 0) || (new Date().after(expirationDate))) {
-                loadServiceClusterInfo();
-
-                if (initialPass && (serviceClusterInfo.getEPRs().size() == 0)) // zero from a previous send
-                {
-                	/*
-                	 * We need to check to see if this instance used up all of it's attempts to deliver
-                	 * in a previous deliver or we'll only refresh the cache once per subsequent send
-                	 * because we will have exhausted the EPRs in the cache, i.e., size==0.
-                	 *
-                	 * When the instance is originally created we do an initial cache fetch. Until this
-                	 * check, that cache fetch was not being done again after a complete failure. Unlikely
-                	 * to cause problems anyway, but possible.
-                	 */
-                	initialPass = false;
+        try {
+            //We are removing dead EPRs from the serviceClusterInfo. *Previous* deliveries maybe have
+            //removed EPRs that have now come back to life. We should try once more to pull a fresh list of EPRS
+            //from the registry before we give up (and fail-over to redelivery at a later time in the care
+            //of asyncDeliver). I think the end-user expects the message to be delivered successfully if there
+            //is a healhty EPR out there. So this is really for EPR cache management (serviceClusterInfo will
+            //be empty when going for the 2nd attempt, or else there delivery was successful and there will be
+            //no second attempt!).
+            while (staleEPRCache) {
+                if ((serviceClusterInfo.getEPRs().size() == 0) || (new Date().after(expirationDate))) {
+                    loadServiceClusterInfo();
+    
+                    if (initialPass && (serviceClusterInfo.getEPRs().size() == 0)) // zero from a previous send
+                    {
+                    	/*
+                    	 * We need to check to see if this instance used up all of it's attempts to deliver
+                    	 * in a previous deliver or we'll only refresh the cache once per subsequent send
+                    	 * because we will have exhausted the EPRs in the cache, i.e., size==0.
+                    	 *
+                    	 * When the instance is originally created we do an initial cache fetch. Until this
+                    	 * check, that cache fetch was not being done again after a complete failure. Unlikely
+                    	 * to cause problems anyway, but possible.
+                    	 */
+                    	initialPass = false;
+                    }
+                    else
+                    	staleEPRCache = false;
                 }
-                else
-                	staleEPRCache = false;
-            }
-            Message replyMessage;
-            EPR epr;
-            // Iterate over all the EPRs in the list until delivered
-            while ((epr = loadBalancer.chooseEPR(serviceClusterInfo)) != null) {
-            	try
-            	{
-	                replyMessage = eprInvoker.attemptDelivery(message, epr);
-	                if (replyMessage != null) {
-                        if(eprInvoker.synchronous) {
-                            // remove the security context so that it is not exposed to the action pipeline.
-                            replyMessage.getContext().removeContext(SecurityService.CONTEXT);
-                            replyMessage.getContext().removeContext(SecurityService.AUTH_REQUEST);
+                Message replyMessage;
+                EPR epr;
+                // Iterate over all the EPRs in the list until delivered
+                while ((epr = loadBalancer.chooseEPR(serviceClusterInfo)) != null) {
+                	try
+                	{
+    	                replyMessage = eprInvoker.attemptDelivery(message, epr);
+    	                if (replyMessage != null) {
+                            if(eprInvoker.synchronous) {
+                                // remove the security context so that it is not exposed to the action pipeline.
+                                replyMessage.getContext().removeContext(SecurityService.CONTEXT);
+                                replyMessage.getContext().removeContext(SecurityService.AUTH_REQUEST);
 
-                            if (Type.isFaultMessage(replyMessage)) {
-                                Factory.createExceptionFromFault(replyMessage) ;
+                                if (Type.isFaultMessage(replyMessage)) {
+                                    Factory.createExceptionFromFault(replyMessage) ;
+                                }
+    
+                                // We've delivered it, we're done!
+                                return replyMessage;
+                            } else {
+                                // It was an async delivery.  The replyMessage was just an indicator that
+                                // the delivery succeeded.  Return null...
+                                return null;
                             }
-
-                            // We've delivered it, we're done!
-                            return replyMessage;
                         } else {
-                            // It was an async delivery.  The replyMessage was just an indicator that
-                            // the delivery succeeded.  Return null...
-                            return null;
-                        }
-                    } else {
-	                    logger.info("Unresponsive EPR: " + epr+" for message: "+message.getHeader());
-
-	                    serviceClusterInfo.removeDeadEPR(epr);
-
-	                    /*
-	                     * So far we've only removed the EPR from the cache. Should we
-	                     * also remove it from the registry?
-	                     */
-
-	                    if (removeDeadEprs)
-	                    	RegistryUtil.unregister(service.getCategory(), service.getName(), epr);
-
-	                    /*
-	                     * If the message property is set to fail immediately, or the global property is set,
-	                     * then don't do retries even if there are other EPRs in the list.
-	                     */
-
-	                    if (("true".equals(message.getProperties().getProperty(Environment.EXCEPTION_ON_DELIVERY_FAILURE, "false")) || exceptionOnDeliveryFailure))
-	                	throw new MessageDeliverException("Failed to deliver message ["+message.getHeader()+"] to Service [" + service + "].  Told not to retry.");
-	                }
-            	}
-            	catch (MalformedEPRException ex)  // so we can differentiate failure modes, since returning null is limiting
-            	{
-            		logger.info("Invalid EPR for service (probably ESB-unaware): ignoring for message: "+message.getHeader());
-
-            		serviceClusterInfo.removeDeadEPR(epr);
-
-            		/*
-            		 * DO NOT remove from the registry - it is not dead!!
-            		 */
-            	}
-
+    	                    logger.info("Unresponsive EPR: " + epr+" for message: "+message.getHeader());
+    
+    	                    serviceClusterInfo.removeDeadEPR(epr);
+    
+    	                    /*
+    	                     * So far we've only removed the EPR from the cache. Should we
+    	                     * also remove it from the registry?
+    	                     */
+    
+    	                    if (removeDeadEprs)
+    	                    	RegistryUtil.unregister(service.getCategory(), service.getName(), epr);
+    
+    	                    /*
+    	                     * If the message property is set to fail immediately, or the global property is set,
+    	                     * then don't do retries even if there are other EPRs in the list.
+    	                     */
+    
+    	                    if (("true".equals(message.getProperties().getProperty(Environment.EXCEPTION_ON_DELIVERY_FAILURE, "false")) || exceptionOnDeliveryFailure))
+    	                	throw new MessageDeliverException("Failed to deliver message ["+message.getHeader()+"] to Service [" + service + "].  Told not to retry.");
+    	                }
+                	}
+                	catch (MalformedEPRException ex)  // so we can differentiate failure modes, since returning null is limiting
+                	{
+                		logger.info("Invalid EPR for service (probably ESB-unaware): ignoring for message: "+message.getHeader());
+    
+                		serviceClusterInfo.removeDeadEPR(epr);
+    
+                		/*
+                		 * DO NOT remove from the registry - it is not dead!!
+                		 */
+                	}
+    
+                }
             }
+        } finally {
+            message.getContext().removeContext(SecurityService.CONTEXT);
+            message.getContext().removeContext(SecurityService.AUTH_REQUEST);
         }
 
         // Throw exception if delivery failed...

Added: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java	                        (rev 0)
+++ labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java	2009-01-30 18:51:32 UTC (rev 25025)
@@ -0,0 +1,167 @@
+/*
+ * 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.services.security;
+
+import java.util.Properties;
+
+import javax.crypto.SealedObject;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertNull;
+import junit.framework.JUnit4TestAdapter;
+
+import org.jboss.internal.soa.esb.couriers.MockCourier;
+import org.jboss.internal.soa.esb.couriers.MockCourierFactory;
+import org.jboss.internal.soa.esb.services.registry.MockRegistry;
+import org.jboss.soa.esb.addressing.MalformedEPRException;
+import org.jboss.soa.esb.client.ServiceInvoker;
+import org.jboss.soa.esb.common.Environment;
+import org.jboss.soa.esb.couriers.CourierException;
+import org.jboss.soa.esb.message.ByReferenceMessage;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.jboss.soa.esb.services.security.auth.AuthenticationRequestImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for security propagation.
+ * 
+ * @author <a href="mailto:Kevin.Conner at jboss.com">Kevin Conner</a>
+ */
+public class SecurityPropagationUnitTest
+{
+    private Properties props ;
+
+    @Before
+    public void setup()
+    {
+        props = System.getProperties() ;
+        final Properties newProps = new Properties(props) ;
+        newProps.setProperty(Environment.SECURITY_SERVICE_SEAL_ALGORITHM, "TripleDES") ;
+        newProps.setProperty(Environment.SECURITY_SERVICE_SEAL_KEYSIZE, "168") ;
+        System.setProperties(newProps) ;
+        MockCourierFactory.install() ;
+        MockRegistry.install() ;
+    }
+
+    @After
+    public void tearDown()
+    {
+        MockRegistry.uninstall() ;
+        MockCourierFactory.uninstall() ;
+        System.setProperties(props) ;
+    }
+
+    @Test
+    public void securityContextPropagation()
+        throws Exception
+    {
+        final String category = "test" ;
+        final String service = "securityContextPropagation" ;
+        final MockCourier mockCourier = new PropagationMockCourier() ;
+        MockRegistry.register(category, service, mockCourier) ;
+        
+        final ServiceInvoker si = new ServiceInvoker(category, service) ;
+        final Message message = MessageFactory.getInstance().getMessage() ;
+        
+        assertNull("securityContext", SecurityContext.getSecurityContext()) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.CONTEXT)) ;
+        
+        final SealedObject securityContext = SecurityContext.encryptContext(new SecurityContext()) ;
+        SecurityContext.setSecurityContext(securityContext) ;
+        
+        assertNotNull("securityContext", SecurityContext.getSecurityContext()) ;
+        
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("securityContext", SecurityContext.getSecurityContext()) ;
+        
+        mockCourier.reset();
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.CONTEXT)) ;
+        assertNotNull("securityContext", SecurityContext.getSecurityContext()) ;
+    }
+
+    @Test
+    public void authenticationRequestPropagation()
+        throws Exception
+    {
+        final String category = "test" ;
+        final String service = "authenticationRequestPropagation" ;
+        final MockCourier mockCourier = new PropagationMockCourier() ;
+        MockRegistry.register(category, service, mockCourier) ;
+        
+        final ServiceInvoker si = new ServiceInvoker(category, service) ;
+        final Message message = MessageFactory.getInstance().getMessage() ;
+        
+        assertNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        
+        final byte[] authenticationRequest = new byte[0] ;
+        AuthenticationRequestImpl.setEncryptedAuthRequest(authenticationRequest) ;
+        
+        assertNotNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+        
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+        
+        mockCourier.reset();
+        si.deliverAsync(message) ;
+        
+        assertNotSame("messages", message, mockCourier.message) ;
+        assertNull("message context", message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("delivered message context", mockCourier.message.getContext().getContext(SecurityService.AUTH_REQUEST)) ;
+        assertNotNull("authenticationRequest", AuthenticationRequestImpl.getEncryptedAuthRequest()) ;
+    }
+
+    private static final class PropagationMockCourier extends MockCourier
+    {
+        PropagationMockCourier()
+        {
+            super(true) ;
+        }
+        
+        @Override
+        public boolean deliver(final Message message)
+            throws CourierException, MalformedEPRException
+        {
+            return super.deliver(((ByReferenceMessage)message).reference());
+        }
+    }
+    
+    public static junit.framework.Test suite()
+    {
+        return new JUnit4TestAdapter(SecurityPropagationUnitTest.class);
+    }
+}


Property changes on: labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java
___________________________________________________________________
Name: svn:keywords
   + Rev Date
Name: svn:eol-style
   + native




More information about the jboss-svn-commits mailing list