Bug 1124271

Summary: JaasSecurityService does not utilize JAAS cache for Authentications
Product: [JBoss] JBoss Enterprise SOA Platform 5 Reporter: Jason Shepherd <jshepherd>
Component: unspecifiedAssignee: Mark Little <mark.little>
Status: NEW --- QA Contact:
Severity: high Docs Contact:
Priority: unspecified    
Version: 5.3.1CC: soa-p-jira
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
implementation of caching JaasSecurityService none

Description Jason Shepherd 2014-07-29 07:35:31 UTC
Description of problem:

JaasSecurityService does not implement JAAS caching, resulting in slow response times with ESB calls that need to be authenticated to a backend, such as LDAP.


Version-Release number of selected component (if applicable):

JBoss ESB JBESP_4_11_CP


How reproducible:

The problem can easily be reproduced with the security_basic quickstart. If I enable TRACE level logging for the 'org.jboss.security' package, and invoke 'and sendesb' a few times, I can see that the login module is validating the user on each request:


2014-07-25 11:17:06,006 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] (pool-26-thread-1) initialize
2014-07-25 11:17:06,006 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] (pool-26-thread-1) Security domain: jbossesb
...
2014-07-25 11:17:06,007 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] (pool-26-thread-1) User 'esbuser' authenticated, loginOk=true
2014-07-25 11:17:06,007 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] (pool-26-thread-1) commit, loginOk=true
2014-07-25 11:17:06,007 TRACE [org.jboss.security.auth.spi.UsersRolesLoginModule] (pool-26-thread-1) Checking user: esbuser, roles string: esbrole

As per my understanding, the expectation is that the principal would be obtained from cache instead.


Let's take a look at the underlying ESB classes related to the security integration. First, the security check is done in ActionProcessingPipeline.processPipeline [1]:

    			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));
		        }


And the securityService.authenticate in JaasSecurityService is implemented as:

	public void authenticate(final SecurityConfig config, SecurityContext securityContext, final AuthenticationRequest authRequest) throws SecurityServiceException
	{
		AssertArgument.isNotNull(config, "config");

		LoginContext loginContext;
		try
		{
			final EsbCallbackHandler callbackHandler = createCallbackHandler(config, authRequest);
			if (callbackHandler != null)
			{
    			loginContext = new LoginContext(config.getModuleName(), securityContext.getSubject(), callbackHandler);
			}
			else
			{
    			loginContext = new LoginContext(config.getModuleName(), securityContext.getSubject());
			}

    		loginContext.login();

    		//	add a runAs group if specified
    		addRunAs(config.getRunAs(), securityContext.getSubject());

		}
		catch (final LoginException e)
		{
			throw new SecurityServiceException("Exception while trying to login:", e);
		}

	}
 

[1] http://anonsvn.jboss.org/repos/labs/labs/jbossesb/tags/JBESB_4_11_CP2_CR1/product/rosetta/src/org/jboss/soa/esb/listeners/message/ActionProcessingPipeline.java
[2] http://anonsvn.jboss.org/repos/labs/labs/jbossesb/tags/JBESB_4_11_CP2_CR1/product/rosetta/src/org/jboss/internal/soa/esb/services/security/JaasSecurityService.java

Comment 1 Jason Shepherd 2014-08-04 02:14:17 UTC
Created attachment 923726 [details]
implementation of caching JaasSecurityService

Comment 2 Jason Shepherd 2014-08-04 02:15:35 UTC
An initial version of a custom ESB SecurityService implementation example is attached. Tadayoshi Sato tested it locally using the 'security_basic' quickstart and confirmed that the login module was invoked only once even calls were made twice.

The following Maven command under the custom-security-service project will build a JAR:

    $ mvn clean package

Then simply copy the JAR into $PROFILE/lib/ and rewrite $PROFILE/deployers/esb.deployer/jbossesb-properties.xml as follows:


    <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.implementationClass" value="com.redhat.samples.esb.SampleSecurityService"/>
        ...