123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- <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: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>
- <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 language="xml"><![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-jaasauthenticationprovider">
- <info>
- <title>JaasAuthenticationProvider</title>
- </info>
- <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:
- <programlisting language="txt">
- JAASTest {
- sample.SampleLoginModule required;
- };</programlisting></para>
- <para>Like all Spring Security beans, the <classname>JaasAuthenticationProvider</classname>
- is configured via the application context. The following definitions would correspond to
- the above JAAS login configuration file: <programlisting language="xml"><![CDATA[
- <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>
- ]]></programlisting></para>
- </section>
- <section xml:id="jaas-apiprovision">
- <info>
- <title xml:id="jaas-api-provision">Running as a Subject</title>
- </info>
- <para>If configured, the <classname>JaasApiIntegrationFilter</classname> will attempt to
- run as the <literal>Subject</literal> on the
- <classname>JaasAuthenticationToken</classname>. This means that the
- <literal>Subject</literal> can be accessed using:
- <programlisting language="java"><![CDATA[
- Subject subject = Subject.getSubject(AccessController.getContext());
- ]]></programlisting>
- This integration can easily be configured using the
- <link xlink:href="#nsa-http-jaas-api-provision">jaas-api-provision</link> attribute. This
- feature is useful when integrating with legacy or external API's that rely on the
- JAAS Subject being populated.</para>
- </section>
- </chapter>
|