[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