mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-11-04 08:39:05 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			171 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
[[servlet-jaas]]
 | 
						|
= Java Authentication and Authorization Service (JAAS) Provider
 | 
						|
 | 
						|
 | 
						|
== Overview
 | 
						|
Spring Security provides a package able to delegate authentication requests to the Java Authentication and Authorization Service (JAAS).
 | 
						|
This package is discussed in detail below.
 | 
						|
 | 
						|
 | 
						|
[[jaas-abstractjaasauthenticationprovider]]
 | 
						|
== AbstractJaasAuthenticationProvider
 | 
						|
The `AbstractJaasAuthenticationProvider` is the basis for the provided JAAS `AuthenticationProvider` implementations.
 | 
						|
Subclasses must implement a method that creates the `LoginContext`.
 | 
						|
The `AbstractJaasAuthenticationProvider` has a number of dependencies that can be injected into it that are discussed below.
 | 
						|
 | 
						|
 | 
						|
[[jaas-callbackhandler]]
 | 
						|
=== JAAS CallbackHandler
 | 
						|
Most JAAS ``LoginModule``s require a callback of some sort.
 | 
						|
These callbacks are usually used to obtain the username and password from the user.
 | 
						|
 | 
						|
In a Spring Security deployment, Spring Security is responsible for this user interaction (via the authentication mechanism).
 | 
						|
Thus, by the time the authentication request is delegated through to JAAS, Spring Security's authentication mechanism will already have fully-populated an `Authentication` object containing all the information required by the JAAS `LoginModule`.
 | 
						|
 | 
						|
Therefore, the JAAS package for Spring Security provides two default callback handlers, `JaasNameCallbackHandler` and `JaasPasswordCallbackHandler`.
 | 
						|
Each of these callback handlers implement `JaasAuthenticationCallbackHandler`.
 | 
						|
In most cases these callback handlers can simply be used without understanding the internal mechanics.
 | 
						|
 | 
						|
For those needing full control over the callback behavior, internally `AbstractJaasAuthenticationProvider` wraps these ``JaasAuthenticationCallbackHandler``s with an `InternalCallbackHandler`.
 | 
						|
The `InternalCallbackHandler` is the class that actually implements JAAS normal `CallbackHandler` interface.
 | 
						|
Any time that the JAAS `LoginModule` is used, it is passed a list of application context configured ``InternalCallbackHandler``s.
 | 
						|
If the `LoginModule` requests a callback against the ``InternalCallbackHandler``s, the callback is in-turn passed to the ``JaasAuthenticationCallbackHandler``s being wrapped.
 | 
						|
 | 
						|
 | 
						|
[[jaas-authoritygranter]]
 | 
						|
=== JAAS AuthorityGranter
 | 
						|
JAAS works with principals.
 | 
						|
Even "roles" are represented as principals in JAAS.
 | 
						|
Spring Security, on the other hand, works with `Authentication` objects.
 | 
						|
Each `Authentication` object contains a single principal, and multiple ``GrantedAuthority``s.
 | 
						|
To facilitate mapping between these different concepts, Spring Security's JAAS package includes an `AuthorityGranter` interface.
 | 
						|
 | 
						|
An `AuthorityGranter` is responsible for inspecting a JAAS principal and returning a set of ``String``s, representing the authorities assigned to the principal.
 | 
						|
For each returned authority string, the `AbstractJaasAuthenticationProvider` creates a `JaasGrantedAuthority` (which implements Spring Security's `GrantedAuthority` interface) containing the authority string and the JAAS principal that the `AuthorityGranter` was passed.
 | 
						|
The `AbstractJaasAuthenticationProvider` obtains the JAAS principals by firstly successfully authenticating the user's credentials using the JAAS `LoginModule`, and then accessing the `LoginContext` it returns.
 | 
						|
A call to `LoginContext.getSubject().getPrincipals()` is made, with each resulting principal passed to each `AuthorityGranter` defined against the `AbstractJaasAuthenticationProvider.setAuthorityGranters(List)` property.
 | 
						|
 | 
						|
Spring Security does not include any production ``AuthorityGranter``s given that every JAAS principal has an implementation-specific meaning.
 | 
						|
However, there is a `TestAuthorityGranter` in the unit tests that demonstrates a simple `AuthorityGranter` implementation.
 | 
						|
 | 
						|
 | 
						|
[[jaas-defaultjaasauthenticationprovider]]
 | 
						|
== DefaultJaasAuthenticationProvider
 | 
						|
The `DefaultJaasAuthenticationProvider` allows a JAAS `Configuration` object to be injected into it as a dependency.
 | 
						|
It then creates a `LoginContext` using the injected JAAS `Configuration`.
 | 
						|
This means that `DefaultJaasAuthenticationProvider` is not bound any particular implementation of `Configuration` as `JaasAuthenticationProvider` is.
 | 
						|
 | 
						|
 | 
						|
[[jaas-inmemoryconfiguration]]
 | 
						|
=== InMemoryConfiguration
 | 
						|
In order to make it easy to inject a `Configuration` into `DefaultJaasAuthenticationProvider`, a default in-memory implementation named `InMemoryConfiguration` is provided.
 | 
						|
The implementation constructor accepts a `Map` where each key represents a login configuration name and the value represents an `Array` of ``AppConfigurationEntry``s.
 | 
						|
`InMemoryConfiguration` also supports a default `Array` of `AppConfigurationEntry` objects that will be used if no mapping is found within the provided `Map`.
 | 
						|
For details, refer to the class level javadoc of `InMemoryConfiguration`.
 | 
						|
 | 
						|
 | 
						|
[[jaas-djap-config]]
 | 
						|
=== DefaultJaasAuthenticationProvider Example Configuration
 | 
						|
While the Spring configuration for `InMemoryConfiguration` can be more verbose than the standard JAAS configuration files, using it in conjunction with `DefaultJaasAuthenticationProvider` is more flexible than `JaasAuthenticationProvider` since it not dependant on the default `Configuration` implementation.
 | 
						|
 | 
						|
An example configuration of `DefaultJaasAuthenticationProvider` using `InMemoryConfiguration` is provided below.
 | 
						|
Note that custom implementations of `Configuration` can easily be injected into `DefaultJaasAuthenticationProvider` as well.
 | 
						|
 | 
						|
 | 
						|
[source,xml]
 | 
						|
----
 | 
						|
 | 
						|
<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>
 | 
						|
	<!--
 | 
						|
	SPRINGSECURITY is the default loginContextName
 | 
						|
	for AbstractJaasAuthenticationProvider
 | 
						|
	-->
 | 
						|
	<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>
 | 
						|
	<!-- You will need to write your own implementation of AuthorityGranter -->
 | 
						|
	<bean class="org.springframework.security.authentication.jaas.TestAuthorityGranter"/>
 | 
						|
</list>
 | 
						|
</property>
 | 
						|
</bean>
 | 
						|
 | 
						|
----
 | 
						|
 | 
						|
 | 
						|
 | 
						|
[[jaas-jaasauthenticationprovider]]
 | 
						|
== JaasAuthenticationProvider
 | 
						|
The `JaasAuthenticationProvider` assumes the default `Configuration` is an instance of https://docs.oracle.com/javase/8/docs/jre/api/security/jaas/spec/com/sun/security/auth/login/ConfigFile.html[ ConfigFile].
 | 
						|
This assumption is made in order to attempt to update the `Configuration`.
 | 
						|
The `JaasAuthenticationProvider` then uses the default `Configuration` to create the `LoginContext`.
 | 
						|
 | 
						|
Let's assume we have a JAAS login configuration file, `/WEB-INF/login.conf`, with the following contents:
 | 
						|
 | 
						|
[source,txt]
 | 
						|
----
 | 
						|
JAASTest {
 | 
						|
	sample.SampleLoginModule required;
 | 
						|
};
 | 
						|
----
 | 
						|
 | 
						|
Like all Spring Security beans, the `JaasAuthenticationProvider` is configured via the application context.
 | 
						|
The following definitions would correspond to the above JAAS login configuration file:
 | 
						|
 | 
						|
[source,xml]
 | 
						|
----
 | 
						|
 | 
						|
<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>
 | 
						|
----
 | 
						|
 | 
						|
[[jaas-apiprovision]]
 | 
						|
== Running as a Subject
 | 
						|
If configured, the `JaasApiIntegrationFilter` will attempt to run as the `Subject` on the `JaasAuthenticationToken`.
 | 
						|
This means that the `Subject` can be accessed using:
 | 
						|
 | 
						|
[source,java]
 | 
						|
----
 | 
						|
Subject subject = Subject.getSubject(AccessController.getContext());
 | 
						|
----
 | 
						|
 | 
						|
This integration can easily be configured using the xref:servlet/appendix/namespace/http.adoc#nsa-http-jaas-api-provision[jaas-api-provision] attribute.
 | 
						|
This feature is useful when integrating with legacy or external API's that rely on the JAAS Subject being populated.
 |