SEC-1564: JAAS Configuration can now be injected into DefaultJaasAuthenticationProvider
This commit is contained in:
@@ -1,28 +1,188 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="jaas">
|
||||
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="jaas">
|
||||
<info>
|
||||
<title>Java Authentication and Authorization Service (JAAS) Provider</title>
|
||||
</info>
|
||||
|
||||
<section xml:id="jaas-overview">
|
||||
<section xml:aid="jaas-overview">
|
||||
<info>
|
||||
<title>Overview</title>
|
||||
</info>
|
||||
<para>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.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="jaas-abstractjaasauthenticationprovider">
|
||||
<info>
|
||||
<title>AbstractJaasAuthenticationProvider</title>
|
||||
</info>
|
||||
<para>The <classname>AbstractJaasAuthenticationProvider</classname> is the basis for the
|
||||
provided JAAS <interfacename>AuthenticationProvider</interfacename> implementations. Subclasses
|
||||
must implement a method that creates the <classname>LoginContext</classname>. The
|
||||
<classname>AbstractJaasAuthenticationProvider</classname> has a number of dependencies that can
|
||||
be injected into it that are discussed below.</para>
|
||||
|
||||
<para>Central to JAAS operation are login configuration files. To learn more about JAAS
|
||||
login configuration files, consult the JAAS reference documentation available from Sun
|
||||
Microsystems. We expect you to have a basic understanding of JAAS and its login
|
||||
configuration file syntax in order to understand this section.</para>
|
||||
<section xml:id="jaas-callbackhandler">
|
||||
<info>
|
||||
<title xml:id="jaas-callback-handler">JAAS CallbackHandler</title>
|
||||
</info>
|
||||
|
||||
<para>Most JAAS <literal>LoginModule</literal>s require a callback of some sort. These
|
||||
callbacks are usually used to obtain the username and password from the user.</para>
|
||||
|
||||
<para>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 <interfacename>Authentication</interfacename>
|
||||
object containing all the information required by the JAAS
|
||||
<literal>LoginModule</literal>.</para>
|
||||
|
||||
<para>Therefore, the JAAS package for Spring Security provides two default callback
|
||||
handlers, <literal>JaasNameCallbackHandler</literal> and
|
||||
<literal>JaasPasswordCallbackHandler</literal>. Each of these callback handlers
|
||||
implement <literal>JaasAuthenticationCallbackHandler</literal>. In most cases these
|
||||
callback handlers can simply be used without understanding the internal
|
||||
mechanics.</para>
|
||||
|
||||
<para>For those needing full control over the callback behavior, internally
|
||||
<classname>AbstractJaasAuthenticationProvider</classname> wraps these
|
||||
<literal>JaasAuthenticationCallbackHandler</literal>s with an
|
||||
<literal>InternalCallbackHandler</literal>. The
|
||||
<literal>InternalCallbackHandler</literal> is the class that actually implements
|
||||
JAAS’ normal <literal>CallbackHandler</literal> interface. Any time that the JAAS
|
||||
<literal>LoginModule</literal> is used, it is passed a list of application context
|
||||
configured <literal>InternalCallbackHandler</literal>s. If the
|
||||
<literal>LoginModule</literal> requests a callback against the
|
||||
<literal>InternalCallbackHandler</literal>s, the callback is in-turn passed to the
|
||||
<literal>JaasAuthenticationCallbackHandler</literal>s being wrapped.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="jaas-authoritygranter">
|
||||
<info>
|
||||
<title xml:id="jaas-authority-granter">JAAS AuthorityGranter</title>
|
||||
</info>
|
||||
|
||||
<para>JAAS works with principals. Even "roles" are represented as principals in JAAS.
|
||||
Spring Security, on the other hand, works with
|
||||
<interfacename>Authentication</interfacename> objects. Each
|
||||
<interfacename>Authentication</interfacename> object contains a single principal,
|
||||
and multiple <interfacename>GrantedAuthority</interfacename>s. To facilitate
|
||||
mapping between these different concepts, Spring Security's JAAS package includes an
|
||||
<literal>AuthorityGranter</literal> interface.</para>
|
||||
|
||||
<para>An <literal>AuthorityGranter</literal> is responsible for inspecting a JAAS
|
||||
principal and returning a set of <literal>String</literal>s, representing the
|
||||
authorities assigned to the principal. For each returned authority string, the
|
||||
<classname>AbstractJaasAuthenticationProvider</classname> creates a
|
||||
<classname>JaasGrantedAuthority</classname> (which implements Spring Security’s
|
||||
<interfacename>GrantedAuthority</interfacename> interface) containing the authority
|
||||
string and the JAAS principal that the
|
||||
<interfacename>AuthorityGranter</interfacename> was passed. The
|
||||
<classname>AbstractJaasAuthenticationProvider</classname> obtains the JAAS principals by
|
||||
firstly successfully authenticating the user’s credentials using the JAAS
|
||||
<literal>LoginModule</literal>, and then accessing the
|
||||
<literal>LoginContext</literal> it returns. A call to
|
||||
<literal>LoginContext.getSubject().getPrincipals()</literal> is made, with each
|
||||
resulting principal passed to each <interfacename>AuthorityGranter</interfacename>
|
||||
defined against the
|
||||
<literal>AbstractJaasAuthenticationProvider.setAuthorityGranters(List)</literal>
|
||||
property.</para>
|
||||
|
||||
<para>Spring Security does not include any production
|
||||
<interfacename>AuthorityGranter</interfacename>s given that every JAAS principal has
|
||||
an implementation-specific meaning. However, there is a
|
||||
<literal>TestAuthorityGranter</literal> in the unit tests that demonstrates a simple
|
||||
<literal>AuthorityGranter</literal> implementation.</para>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="jaas-defaultjaasauthenticationprovider">
|
||||
<info>
|
||||
<title>DefaultJaasAuthenticationProvider</title>
|
||||
</info>
|
||||
<para>The <classname>DefaultJaasAuthenticationProvider</classname> allows a JAAS
|
||||
<classname>Configuration</classname> object to be injected into it as a dependency. It then
|
||||
creates a <classname>LoginContext</classname> using the injected JAAS <classname>Configuration</classname>.
|
||||
This means that <classname>DefaultJaasAuthenticationProvider</classname> is not bound any particular implementation
|
||||
of <classname>Configuration</classname> as <classname>JaasAuthenticationProvider</classname> is.</para>
|
||||
|
||||
<section xml:id="jaas-inmemoryconfiguration">
|
||||
<info>
|
||||
<title>InMemoryConfiguration</title>
|
||||
</info>
|
||||
<para>In order to make it easy to inject a <classname>Configuration</classname> into
|
||||
<classname>DefaultJaasAuthenticationProvider</classname>, a default in memory
|
||||
implementation named <classname>InMemoryConfiguration</classname> is provided. The
|
||||
implementation constructor accepts a <interfacename>Map</interfacename> where each key represents a
|
||||
login configuration name and the value represents an <classname>Array</classname> of
|
||||
<classname>AppConfigurationEntry</classname>s.
|
||||
<classname>InMemoryConfiguration</classname> also supports a default
|
||||
<classname>Array</classname> of <classname>AppConfigurationEntry</classname> objects that
|
||||
will be used if no mapping is found within the provided <interfacename>Map</interfacename>. For
|
||||
details, refer to the class level javadoc of <classname>InMemoryConfiguration</classname>.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="jaas-djap-config">
|
||||
<info>
|
||||
<title>DefaultJaasAuthenticationProvider Example Configuration</title>
|
||||
</info>
|
||||
<para>While the Spring configuration for <classname>InMemoryConfiguration</classname> can be
|
||||
more verbose than the standarad JAAS configuration files, using it in conjuction with
|
||||
<classname>DefaultJaasAuthenticationProvider</classname> is more flexible than
|
||||
<classname>JaasAuthenticationProvider</classname> since it not dependant on the default
|
||||
<classname>Configuration</classname> implementation.</para>
|
||||
<para>An example configuration of <classname>DefaultJaasAuthenticationProvider</classname> using
|
||||
<classname>InMemoryConfiguration</classname> is provided below. Note that custom implementations of
|
||||
<classname>Configuration</classname> can easily be injected into
|
||||
<classname>DefaultJaasAuthenticationProvider</classname> as well.</para>
|
||||
<programlisting><![CDATA[
|
||||
<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>
|
||||
]]></programlisting>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section xml:id="jaas-config">
|
||||
<section xml:id="jaas-jaasauthenticationprovider">
|
||||
<info>
|
||||
<title>Configuration</title>
|
||||
<title>JaasAuthenticationProvider</title>
|
||||
</info>
|
||||
<para>The <literal>JaasAuthenticationProvider</literal> attempts to authenticate a user’s
|
||||
principal and credentials through JAAS.</para>
|
||||
<para>The <classname>JaasAuthenticationProvider</classname> assumes the default <classname>Configuration</classname> is an instance of
|
||||
<link xlink:href="http://download.oracle.com/javase/1.4.2/docs/guide/security/jaas/spec/com/sun/security/auth/login/ConfigFile.html">
|
||||
ConfigFile</link>. This assumption is made in order to attempt to update the <classname>Configuration</classname>. The
|
||||
<classname>JaasAuthenticationProvider</classname> then uses the default <classname>Configuration</classname> to create the
|
||||
<classname>LoginContext</classname>.</para>
|
||||
|
||||
<para>Let’s assume we have a JAAS login configuration file,
|
||||
<literal>/WEB-INF/login.conf</literal>, with the following contents:
|
||||
@@ -52,81 +212,5 @@ JAASTest {
|
||||
</property>
|
||||
</bean>
|
||||
]]></programlisting></para>
|
||||
|
||||
<para>The <literal>CallbackHandler</literal>s and
|
||||
<interfacename>AuthorityGranter</interfacename>s are discussed below.</para>
|
||||
|
||||
<section xml:id="jaas-callbackhandler">
|
||||
<info>
|
||||
<title xml:id="jaas-callback-handler">JAAS CallbackHandler</title>
|
||||
</info>
|
||||
|
||||
<para>Most JAAS <literal>LoginModule</literal>s require a callback of some sort. These
|
||||
callbacks are usually used to obtain the username and password from the user.</para>
|
||||
|
||||
<para>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 <interfacename>Authentication</interfacename>
|
||||
object containing all the information required by the JAAS
|
||||
<literal>LoginModule</literal>.</para>
|
||||
|
||||
<para>Therefore, the JAAS package for Spring Security provides two default callback
|
||||
handlers, <literal>JaasNameCallbackHandler</literal> and
|
||||
<literal>JaasPasswordCallbackHandler</literal>. Each of these callback handlers
|
||||
implement <literal>JaasAuthenticationCallbackHandler</literal>. In most cases these
|
||||
callback handlers can simply be used without understanding the internal
|
||||
mechanics.</para>
|
||||
|
||||
<para>For those needing full control over the callback behavior, internally
|
||||
<literal>JaasAuthenticationProvider</literal> wraps these
|
||||
<literal>JaasAuthenticationCallbackHandler</literal>s with an
|
||||
<literal>InternalCallbackHandler</literal>. The
|
||||
<literal>InternalCallbackHandler</literal> is the class that actually implements
|
||||
JAAS’ normal <literal>CallbackHandler</literal> interface. Any time that the JAAS
|
||||
<literal>LoginModule</literal> is used, it is passed a list of application context
|
||||
configured <literal>InternalCallbackHandler</literal>s. If the
|
||||
<literal>LoginModule</literal> requests a callback against the
|
||||
<literal>InternalCallbackHandler</literal>s, the callback is in-turn passed to the
|
||||
<literal>JaasAuthenticationCallbackHandler</literal>s being wrapped.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="jaas-authoritygranter">
|
||||
<info>
|
||||
<title xml:id="jaas-authority-granter">JAAS AuthorityGranter</title>
|
||||
</info>
|
||||
|
||||
<para>JAAS works with principals. Even "roles" are represented as principals in JAAS.
|
||||
Spring Security, on the other hand, works with
|
||||
<interfacename>Authentication</interfacename> objects. Each
|
||||
<interfacename>Authentication</interfacename> object contains a single principal,
|
||||
and multiple <interfacename>GrantedAuthority</interfacename>s. To facilitate
|
||||
mapping between these different concepts, Spring Security's JAAS package includes an
|
||||
<literal>AuthorityGranter</literal> interface.</para>
|
||||
|
||||
<para>An <literal>AuthorityGranter</literal> is responsible for inspecting a JAAS
|
||||
principal and returning a set of <literal>String</literal>s, representing the
|
||||
authorities assigned to the principal. For each returned authority string, the
|
||||
<classname>JaasAuthenticationProvider</classname> creates a
|
||||
<classname>JaasGrantedAuthority</classname> (which implements Spring Security’s
|
||||
<interfacename>GrantedAuthority</interfacename> interface) containing the authority
|
||||
string and the JAAS principal that the
|
||||
<interfacename>AuthorityGranter</interfacename> was passed. The
|
||||
<classname>JaasAuthenticationProvider</classname> obtains the JAAS principals by
|
||||
firstly successfully authenticating the user’s credentials using the JAAS
|
||||
<literal>LoginModule</literal>, and then accessing the
|
||||
<literal>LoginContext</literal> it returns. A call to
|
||||
<literal>LoginContext.getSubject().getPrincipals()</literal> is made, with each
|
||||
resulting principal passed to each <interfacename>AuthorityGranter</interfacename>
|
||||
defined against the
|
||||
<literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal>
|
||||
property.</para>
|
||||
|
||||
<para>Spring Security does not include any production
|
||||
<interfacename>AuthorityGranter</interfacename>s given that every JAAS principal has
|
||||
an implementation-specific meaning. However, there is a
|
||||
<literal>TestAuthorityGranter</literal> in the unit tests that demonstrates a simple
|
||||
<literal>AuthorityGranter</literal> implementation.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
</chapter>
|
||||
@@ -129,6 +129,12 @@ Success! Your web filters appear to be properly configured!
|
||||
download the CAS Server web application (a war file) from the CAS site and drop it into
|
||||
the <filename>samples/cas/server</filename> directory. </para>
|
||||
</section>
|
||||
<section xml:id="jaas-sample">
|
||||
<title>JAAS Sample</title>
|
||||
<para>The JAAS sample is very simple example of how to use a JAAS LoginModule with Spring Security. The provided LoginModule will
|
||||
successfully authenticate a user if the username equals the password otherwise a LoginException is thrown. The AuthorityGranter
|
||||
used in this example always grants the role ROLE_USER.</para>
|
||||
</section>
|
||||
<section xml:id="preauth-sample">
|
||||
<title>Pre-Authentication Sample</title>
|
||||
<para> This sample application demonstrates how to wire up beans from the <link
|
||||
|
||||
Reference in New Issue
Block a user