* @param sealedSecurityContext The sealed SecurityContext which will exist if the caller has already been authenticated.
* @return true If the action pipeline was processed successfully.
*/
private boolean processPipeline(final Message message, final SealedObject sealedSecurityContext)
{
SecurityContext securityContext = null;
if (sealedSecurityContext != null )
{
// Store the security context. Will be re-attached to outgoing messages regardless whether the service is secured or not.
SecurityContext.setSecurityContext(sealedSecurityContext);
}
AuthenticationRequest authRequest;
try
{
/*
* Get the authentication reqeust if one exists. Note that this is needed even if
* the current service does not require authentication. A service later down the line might
* need to access this information, it might call an EJB that is secured for example, and
* this way pass it through.
*/
authRequest = getAutenticationRequest(message);
if (isServiceSecured())
{
try
{
// Try to decrypt the security context.
securityContext = SecurityContext.decryptContext(sealedSecurityContext);
}
catch (final SecurityServiceException ignored)
{
LOGGER.info("Could not decrypt the security context in Service '" + serviceName + "'. The call might have come from a different VM. Will re-authenticate if security is enabled for this service.", ignored);
securityContext = null;
}
if (LOGGER.isDebugEnabled())
{
if (securityContext != null)
{
/*
* Might be interesting to know if a security context is often invalid as this
* will cause re-authentication. This might be avoidable by setting a longer
* timeout by overriding the default timeout(jbossesb-properties.xml) and specifying
* one on the security element in jboss-esb.xml.
*/
LOGGER.debug(securityContext);
}
}
final SecurityService securityService = SecurityServiceFactory.getSecurityService();
final String moduleName = securityConf.getModuleName() ;
if (securityContext == null || !securityContext.isValid() || ((moduleName != null) && !moduleName.equals(securityContext.getDomain())))
{
if (authRequest == null)
{
throw new SecurityServiceException("Service '" + serviceName + "' has been configured for security but no AuthenticationRequest could be located in the Message Context. Cannot authenticate without an AuthenticationRequest.");
}
// No existing security context exist or it had expired. Create a new one to drive the autentication.
securityContext = new SecurityContext(new Subject(), getSecurityContextTimeout(securityConf), moduleName);
// Authenticate the caller
securityService.authenticate(securityConf, securityContext, authRequest);
// Store the encrypted security context. Will be re-attached to outgoing messages.
SecurityContext.setSecurityContext(SecurityContext.encryptContext(securityContext));
}
// Check that the caller is a member of atleast one of the declared roles.
if (!securityService.checkRolesAllowed(securityConf.getRolesAllowed(), securityContext))
{
throw new SecurityServiceException("Caller did not belong to any of the rolesAllowed " + securityConf.getRolesAllowed());
}
}
}
catch (final SecurityServiceException e)
{
LOGGER.error( "SecurityService exception : ", e);
faultTo(createCallDetails(message), Factory.createErrorMessage(Factory.UNEXPECTED_ERROR, message, e));
return false;
}
catch (final ConfigurationException e)
{
LOGGER.error( "SecurityService exception : ", e);
faultTo(createCallDetails(message), Factory.createErrorMessage(Factory.UNEXPECTED_ERROR, message, e));
return false;
}
finally
{
// Always remove the security context.
message.getContext().removeContext(SecurityService.CONTEXT);
message.getContext().removeContext(SecurityService.AUTH_REQUEST);
}
if (securityContext != null)
{
try
{
// Need to propagate the security context regardless if security was enabled for this service or not.
propagateSecurityContext(message, securityContext, authRequest);
return (Boolean) Subject.doAsPrivileged(securityContext.getSubject(), getPrivilegedAction(message), null);
}
catch (final SecurityServiceException e)
{
LOGGER.error( "SecurityService exception : ", e);
faultTo(createCallDetails(message), Factory.createErrorMessage(Factory.UNEXPECTED_ERROR, message, e));