| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ca"><info><title>Container Adapter Authentication</title></info>
-
- <section xml:id="ca-overview">
- <info><title>Overview</title></info>
-
- <para>Very early versions of Spring Security exclusively used
- Container Adapters for interfacing authentication with end users.
- Whilst this worked well, it required considerable time to support
- multiple container versions and the configuration itself was
- relatively time-consuming for developers. For this reason the HTTP
- Form Authentication and HTTP Basic Authentication approaches were
- developed, and are today recommended for almost all
- applications.</para>
- <para>Container Adapters enable Spring Security to integrate directly
- with the containers used to host end user applications. This
- integration means that applications can continue to leverage the
- authentication and authorization capabilities built into containers
- (such as <literal>isUserInRole()</literal> and form-based or basic
- authentication), whilst benefiting from the enhanced security
- interception capabilities provided by Spring Security (it should be
- noted that Spring Security also offers
- <literal>ContextHolderAwareRequestWrapper</literal> to deliver
- <literal>isUserInRole()</literal> and similar Servlet Specification
- compatibility methods).</para>
- <para>The integration between a container and Spring Security is
- achieved through an adapter. The adapter provides a
- container-compatible user authentication provider, and needs to return
- a container-compatible user object.</para>
- <para>The adapter is instantiated by the container and is defined in a
- container-specific configuration file. The adapter then loads a Spring
- application context which defines the normal authentication manager
- settings, such as the authentication providers that can be used to
- authenticate the request. The application context is usually named
- <literal>acegisecurity.xml</literal> and is placed in a
- container-specific location.</para>
- <para>Spring Security currently supports Jetty, Catalina (Tomcat),
- JBoss and Resin. Additional container adapters can easily be
- written</para>
- </section>
- <section xml:id="ca-adapter"><info><title>Adapter Authentication Provider</title></info>
-
- <para>As is always the case, the container adapter generated
- <literal>Authentication</literal> object still needs to be
- authenticated by an <literal>AuthenticationManager</literal> when
- requested to do so by the
- <literal>AbstractSecurityInterceptor</literal>. The
- <literal>AuthenticationManager</literal> needs to be certain the
- adapter-provided <literal>Authentication</literal> object is valid and
- was actually authenticated by a trusted adapter.</para>
- <para>Adapters create <literal>Authentication</literal> objects which
- are immutable and implement the <literal>AuthByAdapter</literal>
- interface. These objects store the hash of a key that is defined by
- the adapter. This allows the <literal>Authentication</literal> object
- to be validated by the <literal>AuthByAdapterProvider</literal>. This
- authentication provider is defined as follows:</para>
- <para><programlisting><bean id="authByAdapterProvider"
- class="org.springframework.security.adapters.AuthByAdapterProvider">
- <property name="key"><value>my_password</value></property>
- </bean> </programlisting></para>
- <para>The key must match the key that is defined in the
- container-specific configuration file that starts the adapter. The
- <literal>AuthByAdapterProvider</literal> automatically accepts as
- valid any <literal>AuthByAdapter</literal> implementation that returns
- the expected hash of the key.</para>
- <para>To reiterate, this means the adapter will perform the initial
- authentication using providers such as
- <literal>DaoAuthenticationProvider</literal>, returning an
- <literal>AuthByAdapter</literal> instance that contains a hash code of
- the key. Later, when an application calls a security interceptor
- managed resource, the <literal>AuthByAdapter</literal> instance in the
- <literal>SecurityContext</literal> in the
- <literal>SecurityContextHolder</literal> will be tested by the
- application's <literal>AuthByAdapterProvider</literal>. There is no
- requirement for additional authentication providers such as
- <literal>DaoAuthenticationProvider</literal> within the
- application-specific application context, as the only type of
- <literal>Authentication</literal> instance that will be presented by
- the application is from the container adapter.</para>
- <para>Classloader issues are frequent with containers and the use of
- container adapters illustrates this further. Each container requires a
- very specific configuration. The installation instructions are
- provided below. Once installed, please take the time to try the sample
- application to ensure your container adapter is properly
- configured.</para>
- <para>When using container adapters with the
- <literal>DaoAuthenticationProvider</literal>, ensure you set its
- <literal>forcePrincipalAsString</literal> property to
- <literal>true</literal>.</para>
- </section>
- <section xml:id="ca-jetty"><info><title>Jetty</title></info>
-
- <para>The following was tested with Jetty 4.2.18.</para>
- <para><literal>$JETTY_HOME</literal> refers to the root of your Jetty
- installation.</para>
- <para>Edit your <literal>$JETTY_HOME/etc/jetty.xml</literal> file so
- the <literal><Configure class></literal> section has a new
- <literal>addRealm</literal> call:</para>
- <para><programlisting>
- <Call name="addRealm">
- <Arg>
- <New class="org.springframework.security.adapters.jetty.JettySpringSecurityUserRealm">
- <Arg>Spring Powered Realm</Arg>
- <Arg>my_password</Arg>
- <Arg>etc/acegisecurity.xml</Arg>
- </New>
- </Arg>
- </Call>
- </programlisting></para>
- <para>Copy <literal>acegisecurity.xml</literal> into
- <literal>$JETTY_HOME/etc</literal>.</para>
- <para>Copy the following files into
- <literal>$JETTY_HOME/ext</literal>:<itemizedlist>
- <listitem>
- <para><literal>aopalliance.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>commons-logging.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>spring.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>acegi-security-jetty-XX.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>commons-codec.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>burlap.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>hessian.jar</literal></para>
- </listitem>
- </itemizedlist></para>
- <para>None of the above JAR files (or
- <literal>acegi-security-XX.jar</literal>) should be in your
- application's <literal>WEB-INF/lib</literal>. The realm name indicated
- in your <literal>web.xml</literal> does matter with Jetty. The
- <literal>web.xml</literal> must express the same
- <literal><realm-name></literal> as your
- <literal>jetty.xml</literal> (in the example above, "Spring Powered
- Realm").</para>
- </section>
- <section xml:id="ca-jboss"><info><title>JBoss</title></info>
-
- <para>The following was tested with JBoss 3.2.6.</para>
- <para><literal>$JBOSS_HOME</literal> refers to the root of your JBoss
- installation.</para>
- <para>There are two different ways of making spring context available
- to the Jboss integration classes.</para>
- <para>The first approach is by editing your
- <literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal>
- file so that it contains a new entry under the
- <literal><Policy></literal> section:</para>
- <para><programlisting>
- <application-policy name = "SpringPoweredRealm">
- <authentication>
- <login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
- flag = "required">
- <module-option name = "appContextLocation">acegisecurity.xml</module-option>
- <module-option name = "key">my_password</module-option>
- </login-module>
- </authentication>
- </application-policy>
- </programlisting></para>
- <para>Copy <literal>acegisecurity.xml</literal> into
- <literal>$JBOSS_HOME/server/your_config/conf</literal>.</para>
- <para>In this configuration <literal>acegisecurity.xml</literal>
- contains the spring context definition including all the
- authentication manager beans. You have to bear in mind though, that
- <literal>SecurityContext</literal> is created and destroyed on each
- login request, so the login operation might become costly.
- Alternatively, the second approach is to use Spring singleton
- capabilities through
- <literal>org.springframework.beans.factory.access.SingletonBeanFactoryLocator</literal>.
- The required configuration for this approach is:</para>
- <para><programlisting>
- <application-policy name = "SpringPoweredRealm">
- <authentication>
- <login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
- flag = "required">
- <module-option name = "singletonId">springRealm</module-option>
- <module-option name = "key">my_password</module-option>
- <module-option name = "authenticationManager">authenticationManager</module-option>
- </login-module>
- </authentication>
- </application-policy>
- </programlisting></para>
- <para>In the above code fragment,
- <literal>authenticationManager</literal> is a helper property that
- defines the expected name of the
- <literal>AuthenticationManager</literal> in case you have several
- defined in the IoC container. The <literal>singletonId</literal>
- property references a bean defined in a
- <literal>beanRefFactory.xml</literal> file. This file needs to be
- available from anywhere on the JBoss classpath, including
- <literal>$JBOSS_HOME/server/your_config/conf</literal>. The
- <literal>beanRefFactory.xml</literal> contains the following
- declaration:</para>
- <para><programlisting>
- <beans>
- <bean id="springRealm" singleton="true" lazy-init="true" class="org.springframework.context.support.ClassPathXmlApplicationContext">
- <constructor-arg>
- <list>
- <value>acegisecurity.xml</value>
- </list>
- </constructor-arg>
- </bean>
- </beans>
- </programlisting></para>
- <para>Finally, irrespective of the configuration approach you need to
- copy the following files into
- <literal>$JBOSS_HOME/server/your_config/lib</literal>:<itemizedlist>
- <listitem>
- <para><literal>aopalliance.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>spring.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>acegi-security-jboss-XX.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>commons-codec.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>burlap.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>hessian.jar</literal></para>
- </listitem>
- </itemizedlist></para>
- <para>None of the above JAR files (or
- <literal>acegi-security-XX.jar</literal>) should be in your
- application's <literal>WEB-INF/lib</literal>. The realm name indicated
- in your <literal>web.xml</literal> does not matter with JBoss.
- However, your web application's
- <literal>WEB-INF/jboss-web.xml</literal> must express the same
- <literal><security-domain></literal> as your
- <literal>login-config.xml</literal>. For example, to match the above
- example, your <literal>jboss-web.xml</literal> would look like
- this:</para>
- <para><programlisting>
- <jboss-web>
- <security-domain>java:/jaas/SpringPoweredRealm</security-domain>
- </jboss-web></programlisting></para>
- <para>JBoss is a widely-used container adapter (mostly due to the need
- to support legacy EJBs), so please let us know if you have any
- difficulties.</para>
- </section>
- <section xml:id="ca-resin"><info><title>Resin</title></info>
-
- <para>The following was tested with Resin 3.0.6.</para>
- <para><literal>$RESIN_HOME</literal> refers to the root of your Resin
- installation.</para>
- <para>Resin provides several ways to support the container adapter. In
- the instructions below we have elected to maximise consistency with
- other container adapter configurations. This will allow Resin users to
- simply deploy the sample application and confirm correct
- configuration. Developers comfortable with Resin are naturally able to
- use its capabilities to package the JARs with the web application
- itself, and/or support single sign-on.</para>
- <para>Copy the following files into
- <literal>$RESIN_HOME/lib</literal>:<itemizedlist>
- <listitem>
- <para><literal>aopalliance.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>commons-logging.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>spring.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>acegi-security-resin-XX.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>commons-codec.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>burlap.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>hessian.jar</literal></para>
- </listitem>
- </itemizedlist></para>
- <para>Unlike the container-wide <literal>acegisecurity.xml</literal>
- files used by other container adapters, each Resin web application
- will contain its own
- <literal>WEB-INF/resin-acegisecurity.xml</literal> file. Each web
- application will also contain a <literal>resin-web.xml</literal> file
- which Resin uses to start the container adapter:</para>
- <para><programlisting>
- <web-app>
- <authenticator>
- <type>org.springframework.security.adapters.resin.ResinAcegiAuthenticator</type>
- <init>
- <app-context-location>WEB-INF/resin-acegisecurity.xml</app-context-location>
- <key>my_password</key>
- </init>
- </authenticator>
- </web-app>
- </programlisting></para>
- <para>With the basic configuration provided above, none of the JAR
- files listed (or <literal>acegi-security-XX.jar</literal>) should be
- in your application's <literal>WEB-INF/lib</literal>. The realm name
- indicated in your <literal>web.xml</literal> does not matter with
- Resin, as the relevant authentication class is indicated by the
- <literal><authenticator></literal> setting</para>
- </section>
- <section xml:id="ca-tomcat"><info><title>Tomcat</title></info>
-
- <para>The following was tested with Jakarta Tomcat 4.1.30 and
- 5.0.19.</para>
- <para><literal>$CATALINA_HOME</literal> refers to the root of your
- Catalina (Tomcat) installation.</para>
- <para>Edit your <literal>$CATALINA_HOME/conf/server.xml</literal> file
- so the <literal><Engine></literal> section contains only one
- active <literal><Realm></literal> entry. An example realm
- entry:</para>
- <para><programlisting> <Realm
- className="org.springframework.security.adapters.catalina.CatalinaSpringSecurityUserRealm"
- appContextLocation="conf/acegisecurity.xml"
- key="my_password" /></programlisting></para>
- <para>Be sure to remove any other <literal><Realm></literal>
- entry from your <literal><Engine></literal> section.</para>
- <para>Copy <literal>acegisecurity.xml</literal> into
- <literal>$CATALINA_HOME/conf</literal>.</para>
- <para>Copy <literal>spring-security-catalina-XX.jar</literal> into
- <literal>$CATALINA_HOME/server/lib</literal>.</para>
- <para>Copy the following files into
- <literal>$CATALINA_HOME/common/lib</literal>:</para>
- <itemizedlist>
- <listitem>
- <para><literal>aopalliance.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>spring.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>commons-codec.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>burlap.jar</literal></para>
- </listitem>
- <listitem>
- <para><literal>hessian.jar</literal></para>
- </listitem>
- </itemizedlist>
- <para>None of the above JAR files (or
- <literal>spring-security-XX.jar</literal>) should be in your
- application's <literal>WEB-INF/lib</literal>. The realm name indicated
- in your <literal>web.xml</literal> does not matter with
- Catalina.</para>
- <para>We have received reports of problems using this Container
- Adapter with Mac OS X. A work-around is to use a script such as
- follows:</para>
- <para><programlisting>#!/bin/sh
- export CATALINA_HOME="/Library/Tomcat"
- export JAVA_HOME="/Library/Java/Home"
- cd /
- $CATALINA_HOME/bin/startup.sh</programlisting></para>
- <para>Finally, restart Tomcat.</para>
- </section>
- </chapter>
|