1
0
mirror of synced 2026-08-02 16:27:08 +00:00

SEC-1564: JAAS Configuration can now be injected into DefaultJaasAuthenticationProvider

This commit is contained in:
rwinch
2010-09-10 20:17:22 -05:00
parent 8bf1b8420a
commit 58d9903ebc
19 changed files with 1521 additions and 332 deletions
+171 -87
View File
@@ -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 Securitys
<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 users 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 users
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>Lets 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 Securitys
<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 users 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>
+6
View File
@@ -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