[jboss-svn-commits] JBL Code SVN: r25071 - in labs/jbossesb/trunk/product: rosetta/src/org/jboss/soa/esb/client and 3 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Feb 3 06:33:05 EST 2009
Author: kevin.conner at jboss.com
Date: 2009-02-03 06:33:05 -0500 (Tue, 03 Feb 2009)
New Revision: 25071
Added:
labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java
Modified:
labs/jbossesb/trunk/product/docs/ProgrammersGuide.odt
labs/jbossesb/trunk/product/docs/ServicesGuide.odt
labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java
labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java
labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java
Log:
Merged across 4.4CP2_CR4
Modified: labs/jbossesb/trunk/product/docs/ProgrammersGuide.odt
===================================================================
(Binary files differ)
Modified: labs/jbossesb/trunk/product/docs/ServicesGuide.odt
===================================================================
(Binary files differ)
Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java 2009-02-03 10:56:05 UTC (rev 25070)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/client/ServiceInvoker.java 2009-02-03 11:33:05 UTC (rev 25071)
@@ -308,8 +308,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.
@@ -318,95 +316,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 healthy 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 healthy 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);
-
- if (Type.isFaultMessage(replyMessage)) {
- Factory.createExceptionFromFault(replyMessage) ;
+ 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) ;
+ }
+
+ // 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.debug("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.debug("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...
Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java 2009-02-03 10:56:05 UTC (rev 25070)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/http/configurators/HttpProtocol.java 2009-02-03 11:33:05 UTC (rev 25071)
@@ -77,7 +77,7 @@
URI targetURI = getTargetURI(properties, true);
String factory;
String scheme = targetURI.getScheme();
- int port = 80; //default to http;
+ final int port ;
org.apache.commons.httpclient.protocol.Protocol protocol;
KeyMaterial keyMaterial = null;
ProtocolSocketFactory socketFactory;
@@ -92,12 +92,12 @@
keyMaterial = getKeyMaterial(properties);
setHttpsProxyHost(httpClient, properties);
- if(port == -1) {
- port = 443;
- }
+ port = 443;
} else {
factory = properties.getProperty("protocol-socket-factory", DefaultProtocolSocketFactory.class.getName());
setHttpProxyHost(httpClient, properties);
+
+ port = 80;
}
assertPropertySetAndNotBlank(factory, "protocol-socket-factory");
socketFactory = createFactoryClass(factory, keyMaterial, properties);
Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java 2009-02-03 10:56:05 UTC (rev 25070)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/services/security/SecurityContext.java 2009-02-03 11:33:05 UTC (rev 25071)
@@ -32,6 +32,7 @@
import javax.crypto.SealedObject;
import javax.security.auth.Subject;
+import org.apache.log4j.Logger;
import org.jboss.internal.soa.esb.assertion.AssertArgument;
import org.jboss.internal.soa.esb.services.security.PrivateCryptoUtil;
import org.jboss.soa.esb.common.Configuration;
@@ -61,8 +62,17 @@
private static final long serialVersionUID = 1L;
private static transient ThreadLocal<SealedObject> securityContextTl = new ThreadLocal<SealedObject>();
+
+ /**
+ * Logger instance.
+ */
+ private static final Logger LOGGER = Logger.getLogger(SecurityConfig.class) ;
+ /**
+ * default timeout value if not set.
+ */
+ private static final long DEFAULT_TIMEOUT_VALUE = 30000 ;
- private static long globalConfiguredTimeout;
+ private static final long globalConfiguredTimeout = getGlobalConfigurationTimeout() ;
/**
* The Subject associated with this context.
@@ -72,7 +82,7 @@
/**
* Timeout (ms) for the security context. Defaults to 5 mins.
*/
- private long timeout = 30000;
+ private final long timeout ;
/**
* Time of creation.
@@ -80,9 +90,26 @@
private long timeOfCreation = System.currentTimeMillis();
/**
+ * Creates a SecurityContext with a default Subject.
+ */
+ public SecurityContext()
+ {
+ this(new Subject()) ;
+ }
+
+ /**
* Creates a SecurityContext associating the passed in Subject with it.
*
* @param subject The Subject that is to be associated with this security context.
+ */
+ public SecurityContext(final Subject subject)
+ {
+ this(subject, globalConfiguredTimeout) ;
+ }
+ /**
+ * Creates a SecurityContext associating the passed in Subject with it.
+ *
+ * @param subject The Subject that is to be associated with this security context.
* @param timeout A timeout which specifies how long this Security Context is valid for. Must be a positiv value.
*/
public SecurityContext(final Subject subject, final long timeout)
@@ -230,15 +257,11 @@
/**
* Get the globally configured security context timeout.
- * @return
+ * @return the configuration context timeout
* @throws SecurityServiceException
*/
public static long getConfigurationTimeout() throws SecurityServiceException
{
- if (globalConfiguredTimeout == 0l)
- {
- globalConfiguredTimeout = getGlobalConfigurationTimeout();
- }
return globalConfiguredTimeout;
}
@@ -252,12 +275,16 @@
return SecurityContext.securityContextTl.get();
}
- private static long getGlobalConfigurationTimeout() throws SecurityServiceException
+ private static long getGlobalConfigurationTimeout()
{
final String timeoutStr = Configuration.getSecurityServiceContextTimeout();
if (timeoutStr == null)
{
- throw new SecurityServiceException("No timeout was configured for the security context. Please set the value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' to the timeout you desire");
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("No timeout was configured for the security context, using the default value. Please set the value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' to the timeout you desire");
+ }
+ return DEFAULT_TIMEOUT_VALUE ;
}
else
{
@@ -267,7 +294,8 @@
}
catch(final NumberFormatException e)
{
- throw new SecurityServiceException("The value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' must be specified as a long");
+ LOGGER.warn("The value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' is invalid, using default value") ;
+ return DEFAULT_TIMEOUT_VALUE ;
}
}
}
Copied: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java (from rev 25025, labs/jbossesb/branches/JBESB_4_4_GA_CP/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java)
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/services/security/SecurityPropagationUnitTest.java 2009-02-03 11:33:05 UTC (rev 25071)
@@ -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);
+ }
+}
More information about the jboss-svn-commits
mailing list