Spring Security provides a package that can delegate authentication requests to the Java Authentication and Authorization Service (JAAS). This package is described in detail below.

AbstractJaasAuthenticationProvider

AbstractJaasAuthenticationProvider is the basis for the provided AuthenticationProvider implementations in JAAS. Subclasses must implement a method that creates a LoginContext. AbstractJaasAuthenticationProvider has a number of dependencies that can be injected into it, which are described below.

JAAS CallbackHandler

Most LoginModule from JAAS require some type of callback. These callbacks are typically used to retrieve the username and password from the user.

When deployed using Spring Security, Spring Security is responsible for this user interaction (via an authentication mechanism). Thus, by the time the authentication request is passed to JAAS, the Spring Security authentication mechanism will have already completely populated the Authentication object containing all the information required by the LoginModule from JAAS.

The JAAS package for Spring Security therefore contains two standard callback handlers, JaasNameCallbackHandler and JaasPasswordCallbackHandler. Each of these callback handlers implements JaasAuthenticationCallbackHandler. In most cases, these callback handlers can simply be used without having to understand their internal mechanics.

For those who require full control over the callback logic, the AbstractJaasAuthenticationProvider internally wraps these JaasAuthenticationCallbackHandler instances with InternalCallbackHandler. InternalCallbackHandler is a class that actually implements the regular CallbackHandler interface from JAAS. Each time a LoginModule is used from JAAS, it is passed a list of InternalCallbackHandler instances configured in the application context. If LoginModule requests a callback for InternalCallbackHandlers, the callback is in turn passed to the wrapped instances of JaasAuthenticationCallbackHandler.

JAAS Authority Granter

JAAS works with principals. In JAAS, even "roles" are represented as principals. Spring Security, on the other hand, works with Authentication objects. Each Authentication object contains one principal and multiple GrantedAuthoritys. To make it easier to map between these different concepts, the JAAS package in Spring Security contains the AuthorityGranter interface.

The AuthorityGranter is responsible for validating the JAAS principal and returns a set of String representing the authority granted to the principal. For each permission string returned, the AbstractJaasAuthenticationProvider creates a JaasGrantedAuthority (which implements the GrantedAuthority interface from Spring Security) containing the authority string and the JAAS principal that was passed AuthorityGranter. The AbstractJaasAuthenticationProvider obtains the JAAS principals by first successfully authenticating the user's credentials using the LoginModule from JAAS, and then accessing the returned LoginContext. A call to LoginContext.getSubject().getPrincipals() is made, and each principal received is passed to each AuthorityGranter defined in the AbstractJaasAuthenticationProvider.setAuthorityGranters(List).

Spring Security does not contain any production AuthorityGranters because each JAAS principal has an implementation-specific value. However, unit tests have a TestAuthorityGranter that clearly demonstrates how a simple AuthorityGranter implementation works.

DefaultJaasAuthenticationProvider

The DefaultJaasAuthenticationProvider allows you to inject a JAAS Configuration object into it as a dependency. It then creates a LoginContext using the injected Configuration from JAAS. This means that DefaultJaasAuthenticationProvider is not bound to a specific Configuration implementation like JaasAuthenticationProvider is.

InMemoryConfiguration

To make it easier to implement Configuration in the DefaultJaasAuthenticationProvider, there is an in-memory implementation called InMemoryConfiguration by default. The implementation constructor takes a Map in which each key represents a login configuration name and the value is a Array consisting of an AppConfigurationEntry. InMemoryConfiguration also supports a standard Array consisting of AppConfigurationEntry objects, which will be used if no mapping is found in the specified Map. For details, refer to the class-level javadoc on InMemoryConfiguration.

DefaultJaasAuthenticationProvider configuration example

Although the Spring configuration for InMemoryConfiguration can be more crowded than standard JAAS configuration files, using it in combination with the DefaultJaasAuthenticationProvider is more flexible than using the JaasAuthenticationProvider , since it does not depend on the standard implementation of Configuration.

The following is an example of a DefaultJaasAuthenticationProvider configuration using InMemoryConfiguration. Please note that custom implementations of Configuration can easily be implemented in DefaultJaasAuthenticationProvider.


        <bean id="jaasAuthProvider"
              class="org.springframework.security.authentication.jaas.DefaultJaasAuthenticationProvider">
<property name="configuration">
<bean class="org.springframework.security.authentication.jaas.memory.InMemoryConfiguration">
<constructor-arg>
	<map>
    
	<entry key="SPRINGSECURITY">
	<array>
	<bean class="javax.security.auth.login.AppConfigurationEntry">
		<constructor-arg value="sample.SampleLoginModule" />
		<constructor-arg>
		<util:constant static-field=
                               "javax.security.auth.login.AppConfigurationEntry$LoginModuleControlFlag.REQUIRED"/>
		</constructor-arg>
		<constructor-arg>
		<map></map>
		</constructor-arg>
		</bean>
	</array>
	</entry>
	</map>
	</constructor-arg>
</bean>
</property>
<property name="authorityGranters">
<list>
    
	<bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
</list>
</property>
</bean>

JaasAuthenticationProvider

JaasAuthenticationProvider assumes that the default Configuration is an instance of ConfigFile. This assumption is made in order to attempt to update Configuration. The JaasAuthenticationProvider then uses the standard Configuration to create a LoginContext.

Suppose we have a JAAS login configuration file, /WEB-INF/login.conf, with the following content:

JAASTest {
    sample.SampleLoginModule required;
};

Like all Spring Security beans, JaasAuthenticationProvider is configured through the application context. The following definitions will match the login JAAS configuration file above:

<bean id="jaasAuthenticationProvider"
class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
<property name="loginConfig" value="/WEB-INF/login.conf"/>
<property name="loginContextName" value="JAASTest"/>
<property name="callbackHandlers">
<list>
<bean
    class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
<bean
    class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler"/>
</list>
</property>
<property name="authorityGranters">
	<list>
	<bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
	</list>
</property>
</bean>

Run as Subject

JaasApiIntegrationFilter - if added to the configuration - will try to execute as Subject for JaasAuthenticationToken. This means that Subject can be accessed with:

Subject subject = Subject.getSubject(AccessController.getContext());

This integration can be easily configured using the jaas-api-provision attribute. This feature is useful when integrating with legacy or external APIs that rely on JAAS entity population.