<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
 * ========================================================================
 * 
 * Copyright 2004 Acegi Technology Pty Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ========================================================================
-->
<book>
  <bookinfo>
    <title>Acegi Security System for Spring</title>

    <subtitle>Reference Documentation</subtitle>

    <releaseinfo>0.9.0</releaseinfo>

    <authorgroup>
      <author>
        <firstname>Ben</firstname>

        <surname>Alex</surname>
      </author>
    </authorgroup>
  </bookinfo>

  <toc></toc>

  <preface id="preface">
    <title>Preface</title>

    <para>This document provides a reference guide to the Acegi Security
    System for Spring, which is a series of classes that deliver
    authentication and authorization services within the Spring
    Framework.</para>

    <para>I would like to acknowledge this reference was prepared using the
    DocBook configuration included with the Spring Framework. The Spring team
    in turn acknowledge Chris Bauer (Hibernate) for his assistance with their
    DocBook.</para>
  </preface>

  <chapter id="security">
    <title>Security</title>

    <sect1 id="security-before-you-begin">
      <title>Before You Begin</title>

      <para>For your security, each official release JAR of Acegi Security has
      been signed by the project leader. This does not in any way alter the
      liability disclaimer contained in the License, but it does ensure you
      are using a properly reviewed, official build of Acegi Security. Please
      refer to the <literal>readme.txt</literal> file in the root of the
      release distribution for instructions on how to validate the JARs are
      correctly signed, and which certificate has been used to sign
      them.</para>
    </sect1>

    <sect1 id="security-introduction">
      <title>Introduction</title>

      <para>The Acegi Security System for Spring provides authentication and
      authorization capabilities for Spring-powered projects, with optional
      integration with popular web containers. The security architecture was
      designed from the ground up using "The Spring Way" of development, which
      includes using bean contexts, interceptors and interface-driven
      programming. As a consequence, the Acegi Security System for Spring is
      useful out-of-the-box for those seeking to secure their Spring-based
      applications, and can be easily adapted to complex customized
      requirements.</para>

      <para>Security involves two distinct operations, authentication and
      authorization. The former relates to resolving whether or not a caller
      is who they claim to be. Authorization on the other hand relates to
      determining whether or not an authenticated caller is permitted to
      perform a given operation.</para>

      <para>Throughout the Acegi Security System for Spring, the user, system
      or agent that needs to be authenticated is referred to as a "principal".
      The security architecture does not have a notion of roles or groups,
      which you may be familiar with from other security implementations,
      although equivalent functionality is fully accommodated by Acegi
      Security.</para>

      <sect2 id="security-introduction-status">
        <title>Current Status</title>

        <para>The Acegi Security System for Spring is widely used by members
        of the Spring Community. The APIs are considered stable and only minor
        changes are expected. Having said that, like many other projects we
        need to strike a balance between backward compatibility and
        improvement. Effective version 0.6.1, Acegi Security uses the Apache
        Portable Runtime Project versioning guidelines, available from
        <literal>http://apr.apache.org/versioning.html</literal>.</para>

        <para>Some minor improvements are currently intended prior to the
        1.0.0 release, although each of these represent additional
        functionality that will in no way modify the project's central
        interfaces or classes. Users of Acegi Security System for Spring
        should therefore be comfortable depending on the current version of
        the project in their applications.</para>
      </sect2>
    </sect1>

    <sect1 id="security-high-level-design">
      <title>High Level Design</title>

      <sect2 id="security-high-level-design-key-components">
        <title>Key Components</title>

        <para>Most enterprise applications have four basic security
        requirements. First, they need to be able to authenticate a principal.
        Second, they need to be able to secure web requests. Third, enterprise
        applications need to be able to secure services layer methods.
        Finally, quite often an enterprise application will need to secure
        domain object instances. Acegi Security provides a comprehensive
        framework for achieving all of these four common enterprise
        application security requirements.</para>

        <para>The Acegi Security System for Spring essentially comprises eight
        key functional parts:</para>

        <itemizedlist spacing="compact">
          <listitem>
            <para>An <literal>Authentication</literal> object which holds the
            principal, credentials and the authorities granted to the
            principal. The object can also store additional information
            associated with an authentication request, such as the source
            TCP/IP address.</para>
          </listitem>

          <listitem>
            <para>A <literal>ContextHolder</literal> which holds the
            <literal>Authentication</literal> object in a
            <literal>ThreadLocal</literal>-bound object.</para>
          </listitem>

          <listitem>
            <para>An <literal>AuthenticationManager</literal> to authenticate
            the <literal>Authentication</literal> object presented via the
            <literal>ContextHolder</literal>.</para>
          </listitem>

          <listitem>
            <para>An <literal>AccessDecisionManager</literal> to authorize a
            given operation.</para>
          </listitem>

          <listitem>
            <para>A <literal>RunAsManager</literal> to optionally replace the
            <literal>Authentication</literal> object whilst a given operation
            is being executed.</para>
          </listitem>

          <listitem>
            <para>A "secure object" interceptor, which coordinates the
            authentication, authorization, run-as replacement, after
            invocation handling and execution of a given operation.</para>
          </listitem>

          <listitem>
            <para>An <literal>AfterInvocationManager</literal> which can
            modify an <literal>Object</literal> returned from a "secure
            object" invocation, such as removing <literal>Collection</literal>
            elements a principal does not have authority to access.</para>
          </listitem>

          <listitem>
            <para>An acess control list (ACL) management package, which can be
            used to obtain the ACLs applicable for domain object
            instances.</para>
          </listitem>
        </itemizedlist>

        <para>A "secure object" interceptor executes most of the Acegi
        Security key classes and in doing so delivers the framework's major
        features. Given its importance, Figure 1 shows the key relationships
        and concrete implementations of
        <literal>AbstractSecurityInterceptor</literal>.</para>

        <para><mediaobject>
            <imageobject role="html">
              <imagedata align="center"
                         fileref="images/SecurityInterception.gif"
                         format="GIF" />
            </imageobject>

            <caption>
              <para>Figure 1: The key "secure object" model</para>
            </caption>
          </mediaobject></para>

        <para>Each "secure object" interceptor (hereinafter called a "security
        interceptor") works with a particular type of "secure object". So,
        what is a secure object? Secure objects refer to any type of object
        that can have security applied to it. A secure object must provide
        some form of callback, so that the security interceptor can
        transparently do its work as required, and callback the object when it
        is time for it to proceed with the requested operation. If secure
        objects cannot provide a native callback approach, a wrapper needs to
        be written so this becomes possible.</para>

        <para>Each secure object has its own package under
        <literal>net.sf.acegisecurity.intercept</literal>. Every other package
        in the security system is secure object independent, in that it can
        support any type of secure object presented.</para>

        <para>Only developers contemplating an entirely new way of
        intercepting and authorizing requests would need to use secure objects
        directly. For example, it would be possible to build a new secure
        object to secure calls to a messaging system that does not use
        <literal>MethodInvocation</literal>s. Most Spring applications will
        simply use the three currently supported secure object types (AOP
        Alliance <literal>MethodInvocation</literal>, AspectJ
        <literal>JoinPoint</literal> and web request
        <literal>FilterInterceptor</literal>) with complete
        transparency.</para>

        <para>Each of the eight key parts of Acegi Security are discussed in
        detail throughout this document.</para>
      </sect2>

      <sect2 id="security-high-level-design-supported-secure-objects">
        <title>Supported Secure Objects</title>

        <para>As shown in the base of Figure 1, the Acegi Security System for
        Spring currently supports three secure objects.</para>

        <para>The first handles an AOP Alliance
        <literal>MethodInvocation</literal>. This is the secure object type
        used to protect Spring beans. Developers will generally use this
        secure object type to secure their business objects. To make a
        standard Spring-hosted bean available as a
        <literal>MethodInvocation</literal>, the bean is simply published
        through a <literal>ProxyFactoryBean</literal> or
        <literal>BeanNameAutoProxyCreator</literal> or
        <literal>DefaultAdvisorAutoProxyCreator</literal>. Most Spring
        developers would already be familiar with these due to their use in
        transactions and other areas of Spring.</para>

        <para>The second type is an AspectJ <literal>JoinPoint</literal>.
        AspectJ has a particular use in securing domain object instances, as
        these are most often managed outside the Spring bean container. By
        using AspectJ, standard constructs such as <literal>new
        Person();</literal> can be used and full security will be applied to
        them by Acegi Security. The
        <literal>AspectJSecurityInterceptor</literal> is still managed by
        Spring, which creates the aspect singleton and wires it with the
        appropriate authentication managers, access decision managers and so
        on.</para>

        <para>The third type is a <literal>FilterInvocation</literal>. This is
        an object included with the Acegi Security System for Spring. It is
        created by an included filter and simply wraps the HTTP
        <literal>ServletRequest</literal>, <literal>ServletResponse</literal>
        and <literal>FilterChain</literal>. The
        <literal>FilterInvocation</literal> enables HTTP resources to be
        secured. Developers do not usually need to understand the mechanics of
        how this works, because they just add the filters to their
        <literal>web.xml</literal> and let the security system do its
        work.</para>
      </sect2>

      <sect2 id="security-high-level-design-configuration-attributes">
        <title>Configuration Attributes</title>

        <para>Every secure object can represent an infinite number of
        individual requests. For example, a
        <literal>MethodInvocation</literal> can represent the invocation of
        any method with any arguments, whilst a
        <literal>FilterInvocation</literal> can represent any HTTP URL.</para>

        <para>The Acegi Security System for Spring needs to record the
        configuration that applies to each of these possible requests. The
        security configuration of a request to
        <literal>BankManager.getBalance(int accountNumber)</literal> needs to
        be very different from the security configuration of a request to
        <literal>BankManager.approveLoan(int applicationNumber)</literal>.
        Similarly, the security configuration of a request to
        <literal>http://some.bank.com/index.htm</literal> needs to be very
        different from the security configuration of
        <literal>http://some.bank.com/manage/timesheet.jsp</literal>.</para>

        <para>To store the various security configurations associated with
        different requests, a configuration attribute is used. At an
        implementation level a configuration attribute is represented by the
        <literal>ConfigAttribute</literal> interface. One concrete
        implementation of <literal>ConfigAttribute</literal> is provided,
        <literal>SecurityConfig</literal>, which simply stores a configuration
        attribute as a <literal>String</literal>.</para>

        <para>The collection of <literal>ConfigAttribute</literal>s associated
        with a particular request is held in a
        <literal>ConfigAttributeDefinition</literal>. This concrete class is
        simply a holder of <literal>ConfigAttribute</literal>s and does
        nothing special.</para>

        <para>When a request is received by the security interceptor, it needs
        to determine which configuration attributes apply. In other words, it
        needs to find the <literal>ConfigAttributeDefinition</literal> which
        applies to the request. This decision is handled by the
        <literal>ObjectDefinitionSource</literal> interface. The main method
        provided by this interface is <literal>public
        ConfigAttributeDefinition getAttributes(Object object)</literal>, with
        the <literal>Object</literal> being the secure object. Recall the
        secure object contains details of the request, so the
        <literal>ObjectDefinitionSource</literal> implementation will be able
        to extract the details it requires to lookup the relevant
        <literal>ConfigAttributeDefinition</literal>.</para>
      </sect2>
    </sect1>

    <sect1 id="security-request-contexts">
      <title>Request Contexts</title>

      <sect2 id="security-contexts-history">
        <title>Historical Approach</title>

        <para>Prior to release 0.9.0, Acegi Security used a
        <literal>ContextHolder</literal> to store a <literal>Context</literal>
        between sessions. A particular subclass of <literal>Context</literal>,
        <literal>SecureContext</literal> defined an interface used for storage
        of the <literal>Authentication</literal> object. The
        <literal>ContextHolder</literal> was a <literal>ThreadLocal</literal>.
        This was removed from 0.9.0 after discussion with other Spring
        developers for the sake of consistency. See for example
        <literal>http://article.gmane.org/gmane.comp.java.springframework.devel/8290</literal>.
        This history is mentioned as the long period
        <literal>ContextHolder</literal> was used will likely mean that
        certain documentation you encounter concerning Acegi Security might
        still refer to <literal>ContextHolder</literal>. Generally you can
        just substitute "<literal>SecurityContextHolder</literal>" for
        "<literal>ContextHolder</literal>", and
        "<literal>SecurityContext</literal>" for
        "<literal>SecureContext</literal>", and you'll have the primary
        meaning of such documentation.</para>
      </sect2>

      <sect2 id="security-contexts-security-context">
        <title>SecurityContext</title>

        <para>The Acegi Security System for Spring uses a
        <literal>SecurityContextHolder</literal> to store the
        <literal>SecurityContext</literal>. The
        <literal>SecurityContext</literal> contains a single getter/setter for
        <literal>Authentication</literal>. All Acegi Security classes query
        the <literal>SecurityContextHolder</literal> for obtaining the current
        <literal>SecurityContext</literal> (and in turn the principal).
        <literal>SecurityContextHolder</literal> is an
        <literal>InheritableThreadLocal</literal>, meaning it is associated
        with the current thread of execution.</para>
      </sect2>

      <sect2 id="security-contexts-storage">
        <title>Context Storage</title>

        <para>Central to Acegi Security's design is that the contents of the
        <literal>SecurityContextHolder</literal> (which is simply a
        <literal>SecurityContext</literal> implementation) can be stored
        between web requests. This is so that a successfully authenticated
        principal can be identified on subsequent requests through the
        <literal>Authentication</literal> stored inside the
        <literal>SecurityContext</literal> obtained from the
        <literal>SecurityContextHolder</literal>. The
        <literal>HttpSessionContextIntegrationFilter</literal> exists to
        automatically copy the contents of a well-defined
        <literal>HttpSession</literal> attribute into the
        <literal>SecurityContextHolder</literal>, then at the end of each
        request, copy the <literal>SecurityContextHolder</literal> contents
        back into the <literal>HttpSession</literal> ready for next
        request.</para>

        <para>It is essential - and an extremely common error of end users -
        that <literal>HttpSessionContextIntegrationFilter</literal> appears
        before any other Acegi Security filter. Acegi Security filters expect
        to be able to modify the <literal>SecurityContextHolder</literal>
        contents as they see fit, and something else (namely
        <literal>HttpSessionContextIntegrationFilter</literal>) will store
        those between requests if necessary. This is why
        <literal>HttpSessionContextIntegrationFilter</literal> must be the
        first filter used.</para>

        <para>You can define a custom <literal>SecurityContext</literal>
        implementation be used in your application by setting the
        <literal>context</literal> property on the
        <literal>HttpSessionContextIntegrationFilter</literal> bean.</para>
      </sect2>
    </sect1>

    <sect1 id="security-interception">
      <title>Security Interception</title>

      <sect2 id="security-interception-all-secure-objects">
        <title>All Secure Objects</title>

        <para>As described in the High Level Design section, each secure
        object has its own security interceptor which is responsible for
        handling each request. Handling involves a number of
        operations:</para>

        <orderedlist>
          <listitem>
            <para>Store the configuration attributes that are associated with
            each secure request.</para>
          </listitem>

          <listitem>
            <para>Extract the <literal>ConfigAttributeDefinition</literal>
            that applies to the request from the relevant
            <literal>ObjectDefinitionSource</literal>.</para>
          </listitem>

          <listitem>
            <para>Obtain the <literal>Authentication</literal> object from the
            <literal>SecureContext</literal>, which is held in the
            <literal>ContextHolder</literal>.</para>
          </listitem>

          <listitem>
            <para>Pass the <literal>Authentication</literal> object to the
            <literal>AuthenticationManager</literal>, update the
            <literal>ContextHolder</literal> with the response.</para>
          </listitem>

          <listitem>
            <para>Pass the <literal>Authentication</literal> object, the
            <literal>ConfigAttributeDefinition</literal>, and the secure
            object to the <literal>AccessDecisionManager</literal>.</para>
          </listitem>

          <listitem>
            <para>Pass the <literal>Authentication</literal> object, the
            <literal>ConfigAttributeDefinition</literal>, and the secure
            object to the <literal>RunAsManager</literal>.</para>
          </listitem>

          <listitem>
            <para>If the <literal>RunAsManager</literal> returns a new
            <literal>Authentication</literal> object, update the
            <literal>ContextHolder</literal> with it.</para>
          </listitem>

          <listitem>
            <para>Proceed with the request execution of the secure
            object.</para>
          </listitem>

          <listitem>
            <para>If the <literal>RunAsManager</literal> earlier returned a
            new <literal>Authentication</literal> object, update the
            <literal>ContextHolder</literal> with the
            <literal>Authentication</literal> object that was previously
            returned by the <literal>AuthenticationManager</literal>.</para>
          </listitem>

          <listitem>
            <para>If an <literal>AfterInvocationManager</literal> is defined,
            pass it the result of the secure object execution so that it may
            throw an <literal>AccessDeniedException</literal> or mutate the
            returned object if required.</para>
          </listitem>

          <listitem>
            <para>Return any result received from the
            <literal>AfterInvocationManager</literal>, or if no
            <literal>AfterInvocationManager</literal> is defined, simply
            return the result provided by the secure object execution.</para>
          </listitem>
        </orderedlist>

        <para>Whilst this may seem quite involved, don't worry. Developers
        interact with the security process by simply implementing basic
        interfaces (such as <literal>AccessDecisionManager</literal>), which
        are fully discussed below.</para>

        <para>The <literal>AbstractSecurityInterceptor</literal> handles the
        majority of the flow listed above. As shown in Figure 1, each secure
        object has its own security interceptor which subclasses
        <literal>AbstractSecurityInterceptor</literal>. Each of these secure
        object-specific security interceptors are discussed below.</para>
      </sect2>

      <sect2 id="security-interception-aopalliance">
        <title>AOP Alliance (MethodInvocation) Security Interceptor</title>

        <para>To secure <literal>MethodInvocation</literal>s, developers
        simply add a properly configured
        <literal>MethodSecurityInterceptor</literal> into the application
        context. Next the beans requiring security are chained into the
        interceptor. This chaining is accomplished using Spring’s
        <literal>ProxyFactoryBean</literal> or
        <literal>BeanNameAutoProxyCreator</literal>, as commonly used by many
        other parts of Spring (refer to the sample application for examples).
        Alternatively, Acegi Security provides a
        <literal>MethodDefinitionSourceAdvisor</literal> which may be used
        with Spring's <literal>DefaultAdvisorAutoProxyCreator</literal> to
        automatically chain the security interceptor in front of any beans
        defined against the <literal>MethodSecurityInterceptor</literal>. The
        <literal>MethodSecurityInterceptor</literal> itself is configured as
        follows:</para>

        <para><programlisting>&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"&gt;
  &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  &lt;property name="afterInvocationManager"&gt;&lt;ref bean="afterInvocationManager"/&gt;&lt;/property&gt;
  &lt;property name="objectDefinitionSource"&gt;
    &lt;value&gt;
      net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
      net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>As shown above, the <literal>MethodSecurityInterceptor</literal>
        is configured with a reference to an
        <literal>AuthenticationManager</literal>,
        <literal>AccessDecisionManager</literal> and
        <literal>RunAsManager</literal>, which are each discussed in separate
        sections below. In this case we've also defined an
        <literal>AfterInvocationManager</literal>, although this is entirely
        optional. The <literal>MethodSecurityInterceptor</literal> is also
        configured with configuration attributes that apply to different
        method signatures. A full discussion of configuration attributes is
        provided in the High Level Design section of this document.</para>

        <para>The <literal>MethodSecurityInterceptor</literal> can be
        configured with configuration attributes in three ways. The first is
        via a property editor and the application context, which is shown
        above. The second is via defining the configuration attributes in your
        source code using Jakarta Commons Attributes. The third is via writing
        your own <literal>ObjectDefinitionSource</literal>, although this is
        beyond the scope of this document. Irrespective of the approach used,
        the <literal>ObjectDefinitionSource</literal> is responsible for
        returning a <literal>ConfigAttributeDefinition</literal> object that
        contains all of the configuration attributes associated with a single
        secure method.</para>

        <para>It should be noted that the
        <literal>MethodSecurityInterceptor.setObjectDefinitionSource()</literal>
        method actually expects an instance of
        <literal>MethodDefinitionSource</literal>. This is a marker interface
        which subclasses <literal>ObjectDefinitionSource</literal>. It simply
        denotes the <literal>ObjectDefinitionSource</literal> understands
        <literal>MethodInvocation</literal>s. In the interests of simplicity
        we'll continue to refer to the
        <literal>MethodDefinitionSource</literal> as an
        <literal>ObjectDefinitionSource</literal>, as the distinction is of
        little relevance to most users of the
        <literal>MethodSecurityInterceptor</literal>.</para>

        <para>If using the application context property editor approach (as
        shown above), commas are used to delimit the different configuration
        attributes that apply to a given method pattern. Each configuration
        attribute is assigned into its own <literal>SecurityConfig</literal>
        object. The <literal>SecurityConfig</literal> object is discussed in
        the High Level Design section.</para>

        <para>If using the Jakarta Commons Attributes approach, your bean
        context will be configured differently:</para>

        <para><programlisting>&lt;bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/&gt;
&lt;bean id="objectDefinitionSource" class="net.sf.acegisecurity.intercept.method.MethodDefinitionAttributes"&gt;
  &lt;property name="attributes"&gt;&lt;ref local="attributes"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor"&gt;
  &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  &lt;property name="objectDefinitionSource"&gt;&lt;ref bean="objectDefinitionSource"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>In addition, your source code will contain Jakarta Commons
        Attributes tags that refer to a concrete implementation of
        <literal>ConfigAttribute</literal>. The following example uses the
        <literal>SecurityConfig</literal> implementation to represent the
        configuration attributes, and results in the same security
        configuration as provided by the property editor approach
        above:</para>

        <para><programlisting>public interface BankManager {

    /**
     * @@SecurityConfig("ROLE_SUPERVISOR")
     * @@SecurityConfig("RUN_AS_SERVER")
     */
    public void deleteSomething(int id);

    /**
     * @@SecurityConfig("ROLE_SUPERVISOR")
     * @@SecurityConfig("RUN_AS_SERVER")
     */
    public void deleteAnother(int id);

    /**
     * @@SecurityConfig("ROLE_TELLER")
     * @@SecurityConfig("ROLE_SUPERVISOR")
     * @@SecurityConfig("BANKSECURITY_CUSTOMER")
     * @@SecurityConfig("RUN_AS_SERVER")
     */
    public float getBalance(int id);
}</programlisting></para>

        <para>You might have noticed the
        <literal>validateConfigAttributes</literal> property in the above
        <literal>MethodSecurityInterceptor</literal> examples. When set to
        <literal>true</literal> (the default), at startup time the
        <literal>MethodSecurityInterceptor</literal> will evaluate if the
        provided configuration attributes are valid. It does this by checking
        each configuration attribute can be processed by either the
        <literal>AccessDecisionManager</literal> or the
        <literal>RunAsManager</literal>. If neither of these can process a
        given configuration attribute, an exception is thrown. If using the
        Jakarta Commons Attributes method of configuration, you should set
        <literal>validateConfigAttributes</literal> to
        <literal>false</literal>.</para>
      </sect2>

      <sect2 id="security-interception-aspectj">
        <title>AspectJ (JoinPoint) Security Interceptor</title>

        <para>The AspectJ security interceptor is very similar to the AOP
        Alliance security interceptor discussed in the previous section.
        Indeed we will only discuss the differences in this section.</para>

        <para>The AspectJ interceptor is named
        <literal>AspectJSecurityInterceptor</literal>. Unlike the AOP Alliance
        security interceptor, which relies on the Spring application context
        to weave in the security interceptor via proxying, the
        <literal>AspectJSecurityInterceptor</literal> is weaved in via the
        AspectJ compiler. It would not be uncommon to use both types of
        security interceptors in the same application, with
        <literal>AspectJSecurityInterceptor</literal> being used for domain
        object instance security and the AOP Alliance
        <literal>MethodSecurityInterceptor</literal> being used for services
        layer security.</para>

        <para>Let's first consider how the
        <literal>AspectJSecurityInterceptor</literal> is configured in the
        Spring application context:</para>

        <para><programlisting>&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor"&gt;
  &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  &lt;property name="afterInvocationManager"&gt;&lt;ref bean="afterInvocationManager"/&gt;&lt;/property&gt;
  &lt;property name="objectDefinitionSource"&gt;
    &lt;value&gt;
      net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
      net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>As you can see, aside from the class name, the
        <literal>AspectJSecurityInterceptor</literal> is exactly the same as
        the AOP Alliance security interceptor. Indeed the two interceptors can
        share the same <literal>objectDefinitionSource</literal>, as the
        <literal>ObjectDefinitionSource</literal> works with
        <literal>java.lang.reflect.Method</literal>s rather than an AOP
        library-specific class. Of course, your access decisions have access
        to the relevant AOP library-specific invocation (ie
        <literal>MethodInvocation</literal> or <literal>JoinPoint</literal>)
        and as such can consider a range of addition criteria when making
        access decisions (such as method arguments).</para>

        <para>Next you'll need to define an AspectJ <literal>aspect</literal>.
        For example:</para>

        <para><programlisting>package net.sf.acegisecurity.samples.aspectj;

import net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor;
import net.sf.acegisecurity.intercept.method.aspectj.AspectJCallback;
import org.springframework.beans.factory.InitializingBean;

public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {

  private AspectJSecurityInterceptor securityInterceptor;

  pointcut domainObjectInstanceExecution(): target(PersistableEntity) 
             &amp;&amp; execution(public * *(..)) &amp;&amp; !within(DomainObjectInstanceSecurityAspect);

  Object around(): domainObjectInstanceExecution() {
    if (this.securityInterceptor != null) {
      AspectJCallback callback = new AspectJCallback() {
        public Object proceedWithObject() {
        return proceed();
      }
    };
    return this.securityInterceptor.invoke(thisJoinPoint, callback);
    } else {
      return proceed();
    }
  }

  public AspectJSecurityInterceptor getSecurityInterceptor() {
    return securityInterceptor;
  }

  public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) {
    this.securityInterceptor = securityInterceptor;
  }

  public void afterPropertiesSet() throws Exception {
    if (this.securityInterceptor == null)
      throw new IllegalArgumentException("securityInterceptor required");
  }
}</programlisting></para>

        <para>In the above example, the security interceptor will be applied
        to every instance of <literal>PersistableEntity</literal>, which is an
        abstract class not shown (you can use any other class or
        <literal>pointcut</literal> expression you like). For those curious,
        <literal>AspectJCallback</literal> is needed because the
        <literal>proceed();</literal> statement has special meaning only
        within an <literal>around()</literal> body. The
        <literal>AspectJSecurityInterceptor</literal> calls this anonymous
        <literal>AspectJCallback</literal> class when it wants the target
        object to continue.</para>

        <para>You will need to configure Spring to load the aspect and wire it
        with the <literal>AspectJSecurityInterceptor</literal>. A bean
        declaration which achieves this is shown below:</para>

        <para><programlisting>&lt;bean id="domainObjectInstanceSecurityAspect" 
    class="net.sf.acegisecurity.samples.aspectj.DomainObjectInstanceSecurityAspect"
    factory-method="aspectOf"&gt;
  &lt;property name="securityInterceptor"&gt;&lt;ref bean="aspectJSecurityInterceptor"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>That's it! Now you can create your beans from anywhere within
        your application, using whatever means you think fit (eg <literal>new
        Person();</literal>) and they will have the security interceptor
        applied.</para>
      </sect2>

      <sect2 id="security-interception-filterinvocation">
        <title>FilterInvocation Security Interceptor</title>

        <para>To secure <literal>FilterInvocation</literal>s, developers need
        to add a filter to their <literal>web.xml</literal> that delegates to
        the <literal>SecurityEnforcementFilter</literal>. A typical
        configuration example is provided below: <programlisting>&lt;filter&gt;
  &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>

        <para>Notice that the filter is actually a
        <literal>FilterToBeanProxy</literal>. Most of the filters used by the
        Acegi Security System for Spring use this class. Refer to the Filters
        section to learn more about this bean.</para>

        <para>In the application context you will need to configure three
        beans:</para>

        <programlisting>&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
  &lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
  &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;
  &lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
  &lt;property name="forceHttps"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  &lt;property name="objectDefinitionSource"&gt;
    &lt;value&gt;
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      \A/secure/super/.*\Z=ROLE_WE_DONT_HAVE
      \A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting>

        <para>The <literal>AuthenticationEntryPoint</literal> will be called
        if the user requests a secure HTTP resource but they are not
        authenticated. The class handles presenting the appropriate response
        to the user so that authentication can begin. Three concrete
        implementations are provided with the Acegi Security System for
        Spring: <literal>AuthenticationProcessingFilterEntryPoint</literal>
        for commencing a form-based authentication,
        <literal>BasicProcessingFilterEntryPoint</literal> for commencing a
        HTTP Basic authentication process, and
        <literal>CasProcessingFilterEntryPoint</literal> for commencing a Yale
        Central Authentication Service (CAS) login. The
        <literal>AuthenticationProcessingFilterEntryPoint</literal> and
        <literal>CasProcessingFilterEntryPoint</literal> have optional
        properties related to forcing the use of HTTPS, so please refer to the
        JavaDocs if you require this.</para>

        <para>The <literal>PortMapper</literal> provides information on which
        HTTPS ports correspond to which HTTP ports. This is used by the
        <literal>AuthenticationProcessingFilterEntryPoint</literal> and
        several other beans. The default implementation,
        <literal>PortMapperImpl</literal>, knows the common HTTP ports 80 and
        8080 map to HTTPS ports 443 and 8443 respectively. You can customise
        this mapping if desired.</para>

        <para>The <literal>SecurityEnforcementFilter</literal> primarily
        provides session management support and initiates authentication when
        required. It delegates actual <literal>FilterInvocation</literal>
        security decisions to the configured
        <literal>FilterSecurityInterceptor</literal>.</para>

        <para>Like any other security interceptor, the
        <literal>FilterSecurityInterceptor</literal> requires a reference to
        an <literal>AuthenticationManager</literal>,
        <literal>AccessDecisionManager</literal> and
        <literal>RunAsManager</literal>, which are each discussed in separate
        sections below. The <literal>FilterSecurityInterceptor</literal> is
        also configured with configuration attributes that apply to different
        HTTP URL requests. A full discussion of configuration attributes is
        provided in the High Level Design section of this document.</para>

        <para>The <literal>FilterSecurityInterceptor</literal> can be
        configured with configuration attributes in two ways. The first is via
        a property editor and the application context, which is shown above.
        The second is via writing your own
        <literal>ObjectDefinitionSource</literal>, although this is beyond the
        scope of this document. Irrespective of the approach used, the
        <literal>ObjectDefinitionSource</literal> is responsible for returning
        a <literal>ConfigAttributeDefinition</literal> object that contains
        all of the configuration attributes associated with a single secure
        HTTP URL.</para>

        <para>It should be noted that the
        <literal>FilterSecurityInterceptor.setObjectDefinitionSource()</literal>
        method actually expects an instance of
        <literal>FilterInvocationDefinitionSource</literal>. This is a marker
        interface which subclasses <literal>ObjectDefinitionSource</literal>.
        It simply denotes the <literal>ObjectDefinitionSource</literal>
        understands <literal>FilterInvocation</literal>s. In the interests of
        simplicity we'll continue to refer to the
        <literal>FilterInvocationDefinitionSource</literal> as an
        <literal>ObjectDefinitionSource</literal>, as the distinction is of
        little relevance to most users of the
        <literal>FilterSecurityInterceptor</literal>.</para>

        <para>If using the application context property editor approach (as
        shown above), commas are used to delimit the different configuration
        attributes that apply to each HTTP URL. Each configuration attribute
        is assigned into its own <literal>SecurityConfig</literal> object. The
        <literal>SecurityConfig</literal> object is discussed in the High
        Level Design section. The <literal>ObjectDefinitionSource</literal>
        created by the property editor,
        <literal>FilterInvocationDefinitionSource</literal>, matches
        configuration attributes against <literal>FilterInvocations</literal>
        based on expression evaluation of the request URL. Two standard
        expression syntaxes are supported. The default is to treat all
        expressions as regular expressions. Alternatively, the presence of a
        <literal>PATTERN_TYPE_APACHE_ANT</literal> directive will cause all
        expressions to be treated as Apache Ant paths. It is not possible to
        mix expression syntaxes within the same definition. For example, the
        earlier configuration could be generated using Apache Ant paths as
        follows:</para>

        <para><programlisting>&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  &lt;property name="objectDefinitionSource"&gt;
    &lt;value&gt;
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      PATTERN_TYPE_APACHE_ANT
      /secure/super/**=ROLE_WE_DONT_HAVE
      /secure/**=ROLE_SUPERVISOR,ROLE_TELLER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>Irrespective of the type of expression syntax used, expressions
        are always evaluated in the order they are defined. Thus it is
        important that more specific expressions are defined higher in the
        list than less specific expressions. This is reflected in our example
        above, where the more specific <literal>/secure/super/</literal>
        pattern appears higher than the less specific
        <literal>/secure/</literal> pattern. If they were reversed, the
        <literal>/secure/</literal> pattern would always match and the
        <literal>/secure/super/</literal> pattern would never be
        evaluated.</para>

        <para>The special keyword
        <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> causes
        the <literal>FilterInvocationDefinitionSource</literal> to
        automatically convert a request URL to lowercase before comparison
        against the expressions. Whilst by default the case of the request URL
        is not converted, it is generally recommended to use
        <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> and
        write each expression assuming lowercase.</para>

        <para>As with other security interceptors, the
        <literal>validateConfigAttributes</literal> property is observed. When
        set to <literal>true</literal> (the default), at startup time the
        <literal>FilterSecurityInterceptor</literal> will evaluate if the
        provided configuration attributes are valid. It does this by checking
        each configuration attribute can be processed by either the
        <literal>AccessDecisionManager</literal> or the
        <literal>RunAsManager</literal>. If neither of these can process a
        given configuration attribute, an exception is thrown.</para>
      </sect2>
    </sect1>

    <sect1 id="security-authentication">
      <title>Authentication</title>

      <sect2 id="security-authentication-requests">
        <title>Authentication Requests</title>

        <para>Authentication requires a way for client code to present its
        security identification to the Acegi Security System for Spring. This
        is the role of the <literal>Authentication</literal> interface. The
        <literal>Authentication</literal> interface holds three important
        objects: the principal (the identity of the caller), the credentials
        (the proof of the identity of the caller, such as a password), and the
        authorities that have been granted to the principal. The principal and
        its credentials are populated by the client code, whilst the granted
        authorities are populated by the
        <literal>AuthenticationManager</literal>.</para>

        <para><mediaobject>
            <imageobject role="html">
              <imagedata align="center" fileref="images/Authentication.gif"
                         format="GIF" />
            </imageobject>

            <caption>
              <para>Figure 3: Key Authentication Architecture</para>
            </caption>
          </mediaobject></para>

        <para>As shown in Figure 3, the Acegi Security System for Spring
        includes several concrete <literal>Authentication</literal>
        implementations:</para>

        <itemizedlist spacing="compact">
          <listitem>
            <para><literal>UsernamePasswordAuthenticationToken</literal>
            allows a username and password to be presented as the principal
            and credentials respectively. It is also what is created by the
            HTTP Session Authentication system.</para>
          </listitem>

          <listitem>
            <para><literal>TestingAuthenticationToken</literal> facilitates
            unit testing by automatically being considered an authenticated
            object by its associated
            <literal>AuthenticationProvider</literal>.</para>
          </listitem>

          <listitem>
            <para><literal>RunAsUserToken</literal> is used by the default
            run-as authentication replacement implementation. This is
            discussed further in the Run-As Authentication Replacement
            section.</para>
          </listitem>

          <listitem>
            <para><literal>CasAuthenticationToken</literal> is used to
            represent a successful Yale Central Authentication Service (CAS)
            authentication. This is discussed further in the CAS
            section.</para>
          </listitem>

          <listitem>
            <para><literal>PrincipalAcegiUserToken</literal> and
            <literal>JettyAcegiUserToken</literal> implement
            <literal>AuthByAdapter</literal> (a subclass of
            <literal>Authentication</literal>) and are used whenever
            authentication is completed by Acegi Security System for Spring
            container adapters. This is discussed further in the Container
            Adapters section.</para>
          </listitem>
        </itemizedlist>

        <para>The authorities granted to a principal are represented by the
        <literal>GrantedAuthority</literal> interface. The
        <literal>GrantedAuthority</literal> interface is discussed at length
        in the Authorization section.</para>
      </sect2>

      <sect2 id="security-authentication-manager">
        <title>Authentication Manager</title>

        <para>As discussed in the Security Interception section, the
        <literal>AbstractSecurityInterceptor</literal> extracts the
        <literal>Authentication</literal> object from the
        <literal>SecureContext</literal> in the
        <literal>ContextHolder</literal>. This is then passed to an
        <literal>AuthenticationManager</literal>. The
        <literal>AuthenticationManager</literal> interface is very
        simple:</para>

        <programlisting>public Authentication authenticate(Authentication authentication) throws AuthenticationException;</programlisting>

        <para>Implementations of <literal>AuthenticationManager</literal> are
        required to throw an <literal>AuthenticationException</literal> should
        authentication fail, or return a fully populated
        <literal>Authentication</literal> object. In particular, the returned
        <literal>Authentication</literal> object should contain an array of
        <literal>GrantedAuthority</literal> objects. The
        <literal>SecurityInterceptor</literal> places the populated
        <literal>Authentication</literal> object back in the
        <literal>SecureContext</literal> in the
        <literal>ContextHolder</literal>, overwriting the original
        <literal>Authentication</literal> object.</para>

        <para>The <literal>AuthenticationException</literal> has a number of
        subclasses. The most important are
        <literal>BadCredentialsException</literal> (an incorrect principal or
        credentials), <literal>DisabledException</literal> and
        <literal>LockedException</literal>. The latter two exceptions indicate
        the principal was found, but the credentials were not checked and
        authentication is denied. An
        <literal>AuthenticationServiceException</literal> is also provided,
        which indicates the authentication system could not process the
        request (eg a database was unavailable).
        <literal>AuthenticationException</literal> also has a
        <literal>CredentialsExpiredException</literal> and
        <literal>AccoungtExpiredException</literal> subclass, although these
        are less commonly used.</para>
      </sect2>

      <sect2 id="security-authentication-provider">
        <title>Provider-Based Authentication</title>

        <para>Whilst the basic <literal>Authentication</literal> and
        <literal>AuthenticationManager</literal> interfaces enable users to
        develop their own authentication systems, users should consider using
        the provider-based authentication packages provided by the Acegi
        Security System for Spring. The key class,
        <literal>ProviderManager</literal>, is configured via the bean context
        with a list of <literal>AuthenticationProvider</literal>s:</para>

        <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
  &lt;property name="providers"&gt;
    &lt;list&gt;
      &lt;ref bean="daoAuthenticationProvider"/&gt;
      &lt;ref bean="someOtherAuthenticationProvider"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para><literal>ProviderManager</literal> calls a series of registered
        <literal>AuthenticationProvider</literal> implementations, until one
        is found that indicates it is able to authenticate a given
        <literal>Authentication</literal> class. When the first compatible
        <literal>AuthenticationProvider</literal> is located, it is passed the
        authentication request. The <literal>AuthenticationProvider</literal>
        will then either throw an <literal>AuthenticationException</literal>
        or return a fully populated <literal>Authentication</literal>
        object.</para>

        <para>Note the <literal>ProviderManager</literal> may throw a
        <literal>ProviderNotFoundException</literal> (a subclass of
        <literal>AuthenticationException</literal>) if it none of the
        registered <literal>AuthenticationProviders</literal> can validate the
        <literal>Authentication</literal> object.</para>

        <para>Several <literal>AuthenticationProvider</literal>
        implementations are provided with the Acegi Security System for
        Spring:</para>

        <para><itemizedlist spacing="compact">
            <listitem>
              <para><literal>TestingAuthenticationProvider</literal> is able
              to authenticate a <literal>TestingAuthenticationToken</literal>.
              The limit of its authentication is simply to treat whatever is
              contained in the <literal>TestingAuthenticationToken</literal>
              as valid. This makes it ideal for use during unit testing, as
              you can create an <literal>Authentication</literal> object with
              precisely the <literal>GrantedAuthority</literal> objects
              required for calling a given method. You definitely would not
              register this <literal>AuthenticationProvider</literal> on a
              production system.</para>
            </listitem>

            <listitem>
              <para><literal>DaoAuthenticationProvider</literal> is able to
              authenticate a
              <literal>UsernamePasswordAuthenticationToken</literal> by
              accessing an authentication respository via a data access
              object. This is discussed further below, as it is the main way
              authentication is initially handled.</para>
            </listitem>

            <listitem>
              <para><literal>RunAsImplAuthenticationProvider</literal> is able
              to authenticate a <literal>RunAsUserToken</literal>. This is
              discussed further in the Run-As Authentication Replacement
              section. You would not register this
              <literal>AuthenticationProvider</literal> if you were not using
              run-as replacement.</para>
            </listitem>

            <listitem>
              <para><literal>AuthByAdapterProvider</literal> is able to
              authenticate any <literal>AuthByAdapter</literal> (a subclass of
              <literal>Authentication</literal> used with container adapters).
              This is discussed further in the Container Adapters section. You
              would not register this
              <literal>AuthenticationProvider</literal> if you were not using
              container adapters.</para>
            </listitem>

            <listitem>
              <para><literal>CasAuthenticationProvider</literal> is able to
              authenticate Yale Central Authentication Service (CAS) tickets.
              This is discussed further in the CAS Single Sign On
              section.</para>
            </listitem>

            <listitem>
              <para><literal>JaasAuthenticationProvider</literal> is able to
              delegate authentication requests to a JAAS
              <literal>LoginModule</literal>. This is discussed further
              below.</para>
            </listitem>
          </itemizedlist></para>
      </sect2>

      <sect2 id="security-authentication-provider-dao">
        <title>Data Access Object Authentication Provider</title>

        <para>The Acegi Security System for Spring includes a
        production-quality <literal>AuthenticationProvider</literal>
        implementation called <literal>DaoAuthenticationProvider</literal>.
        This authentication provider is able to authenticate a
        <literal>UsernamePasswordAuthenticationToken</literal> by obtaining
        authentication details from a data access object configured at bean
        creation time:</para>

        <para><programlisting>&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  &lt;property name="saltSource"&gt;&lt;ref bean="saltSource"/&gt;&lt;/property&gt;
  &lt;property name="passwordEncoder"&gt;&lt;ref bean="passwordEncoder"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>The <literal>PasswordEncoder</literal> and
        <literal>SaltSource</literal> are optional. A
        <literal>PasswordEncoder</literal> provides encoding and decoding of
        passwords obtained from the authentication repository. A
        <literal>SaltSource</literal> enables the passwords to be populated
        with a "salt", which enhances the security of the passwords in the
        authentication repository. <literal>PasswordEncoder</literal>
        implementations are provided with the Acegi Security System for Spring
        covering MD5, SHA and cleartext encodings. Two
        <literal>SaltSource</literal> implementations are also provided:
        <literal>SystemWideSaltSource</literal> which encodes all passwords
        with the same salt, and <literal>ReflectionSaltSource</literal>, which
        inspects a given property of the returned
        <literal>UserDetails</literal> object to obtain the salt. Please refer
        to the JavaDocs for further details on these optional features.</para>

        <para>In addition to the properties above, the
        <literal>DaoAuthenticationProvider</literal> supports optional caching
        of <literal>UserDetails</literal> objects. The
        <literal>UserCache</literal> interface enables the
        <literal>DaoAuthenticationProvider</literal> to place a
        <literal>UserDetails</literal> object into the cache, and retrieve it
        from the cache upon subsequent authentication attempts for the same
        username. By default the <literal>DaoAuthenticationProvider</literal>
        uses the <literal>NullUserCache</literal>, which performs no caching.
        A usable caching implementation is also provided,
        <literal>EhCacheBasedUserCache</literal>, which is configured as
        follows:</para>

        <para><programlisting>&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  &lt;property name="authenticationDao"&gt;&lt;ref bean="authenticationDao"/&gt;&lt;/property&gt;
  &lt;property name="userCache"&gt;&lt;ref bean="userCache"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"&gt;
  &lt;property name="configLocation"&gt;
    &lt;value&gt;classpath:/ehcache-failsafe.xml&lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;
    
&lt;bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
  &lt;property name="cacheManager"&gt;
    &lt;ref local="cacheManager"/&gt;
  &lt;/property&gt;
  &lt;property name="cacheName"&gt;
    &lt;value&gt;userCache&lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;
   
&lt;bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;
  &lt;property name="cache"&gt;&lt;ref local="userCacheBackend"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>All Acegi Security EH-CACHE implementations (including
        <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE
        <literal>Cache</literal> object. The <literal>Cache</literal> object
        can be obtained from wherever you like, although we recommend you use
        Spring's factory classes as shown in the above configuration. If using
        Spring's factory classes, please refer to the Spring documentation for
        further details on how to optimise the cache storage location, memory
        usage, eviction policies, timeouts etc.</para>

        <para>For a class to be able to provide the
        <literal>DaoAuthenticationProvider</literal> with access to an
        authentication repository, it must implement the
        <literal>AuthenticationDao</literal> interface:</para>

        <para><programlisting>public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;</programlisting></para>

        <para>The <literal>UserDetails</literal> is an interface that provides
        getters that guarantee non-null provision of basic authentication
        information such as the username, password, granted authorities and
        whether the user is enabled or disabled. A concrete implementation,
        <literal>User</literal>, is also provided. Acegi Security users will
        need to decide when writing their <literal>AuthenticationDao</literal>
        what type of <literal>UserDetails</literal> to return. In most cases
        <literal>User</literal> will be used directly or subclassed, although
        special circumstances (such as object relational mappers) may require
        users to write their own <literal>UserDetails</literal> implementation
        from scratch. <literal>UserDetails</literal> is often used to store
        additional principal-related properties (such as their telephone
        number and email address), so they can be easily used by web
        views.</para>

        <para>Given <literal>AuthenticationDao</literal> is so simple to
        implement, it should be easy for users to retrieve authentication
        information using a persistence strategy of their choice.</para>

        <para>A design decision was made not to support account locking in the
        <literal>DaoAuthenticationProvider</literal>, as doing so would have
        increased the complexity of the <literal>AuthenticationDao</literal>
        interface. For instance, a method would be required to increase the
        count of unsuccessful authentication attempts. Such functionality
        could be easily provided by leveraging the application event
        publishing features discussed below.</para>

        <para><literal>DaoAuthenticationProvider</literal> returns an
        <literal>Authentication</literal> object which in turn has its
        <literal>principal</literal> property set. The principal will be
        either a <literal>String</literal> (which is essentially the username)
        or a <literal>UserDetails</literal> object (which was looked up from
        the <literal>AuthenticationDao</literal>). By default the
        <literal>UserDetails</literal> is returned, as this enables
        applications to add extra properties potentially of use in
        applications, such as the user's full name, email address etc. If
        using container adapters, or if your applications were written to
        operate with <literal>String</literal>s (as was the case for releases
        prior to Acegi Security 0.6), you should set the
        <literal>DaoAuthenticationProvider.forcePrincipalAsString</literal>
        property to <literal>true</literal> in your application
        context.</para>
      </sect2>

      <sect2 id="security-authentication-provider-events">
        <title>Event Publishing</title>

        <para>The <literal>DaoAuthenticationProvider</literal> automatically
        obtains the <literal>ApplicationContext</literal> it is running in at
        startup time. This allows the provider to publish events through the
        standard Spring event framework. Three types of event messages are
        published:</para>

        <itemizedlist spacing="compact">
          <listitem>
            <para><literal>AuthenticationSuccessEvent</literal> is published
            when an authentication request is successful.</para>
          </listitem>

          <listitem>
            <para><literal>AuthenticationFailureDisabledEvent</literal> is
            published when an authentication request is unsuccessful because
            the returned <literal>UserDetails</literal> is disabled. This is
            normally the case when an account is locked.</para>
          </listitem>

          <listitem>
            <para><literal>AuthenticationFailureAccountExpiredEvent</literal>
            is published when an authentication request is unsuccessful
            because the returned <literal>UserDetails</literal> indicates the
            account has expired. Some applications may wish to distinguish
            between an account being disabled and expired.</para>
          </listitem>

          <listitem>
            <para><literal>AuthenticationFailureCredentialsExpiredEvent</literal>
            is published when an authentication request is unsuccessful
            because the returned <literal>UserDetails</literal> indicates the
            account's credentials have expired. Some applications may wish to
            expire the credentials if, for example, a password is not changed
            with sufficient regularity.</para>
          </listitem>

          <listitem>
            <para><literal>AuthenticationFailureUsernameNotFoundEvent</literal>
            is published when an authentication request is unsuccessful
            because the <literal>AuthenticationDao</literal> could not locate
            the <literal>UserDetails</literal>.</para>
          </listitem>

          <listitem>
            <para><literal>AuthenticationFailurePasswordEvent</literal> is
            published when an authentication request is unsuccessful because
            the presented password did not match that in the
            <literal>UserDetails</literal>.</para>
          </listitem>
        </itemizedlist>

        <para>Each event contains two objects: the
        <literal>Authentication</literal> object that represented the
        authentication request, and the <literal>UserDetails</literal> object
        that was found in response to the authentication request (clearly the
        latter will be a dummy object in the case of
        <literal>AuthenticationFailureUsernameNotFoundEvent</literal>). The
        <literal>Authentication</literal> interface provides a
        <literal>getDetails()</literal> method which often includes
        information that event consumers may find useful (eg the TCP/IP
        address that the authentication request originated from).</para>

        <para>As per standard Spring event handling, you can receive these
        events by adding a bean to the application context which implements
        the <literal>ApplicationListener</literal> interface. Included with
        Acegi Security is a <literal>LoggerListener</literal> class which
        receives these events and publishes their details to Commons Logging.
        Refer to the JavaDocs for <literal>LoggerListener</literal> for
        details on the logging priorities used for different message
        types.</para>

        <para>This event publishing system enables you to implement account
        locking and record authentication event history. This might be of
        interest to application users, who can be advised of the times and
        source IP address of all unsuccessful password attempts (and account
        lockouts) since their last successful login. Such capabilities are
        simple to implement and greatly improve the security of your
        application.</para>
      </sect2>

      <sect2 id="security-authentication-provider-in-memory">
        <title>In-Memory Authentication</title>

        <para>Whilst it is easy to use the
        <literal>DaoAuthenticationProvider</literal> and create a custom
        <literal>AuthenticationDao</literal> implementation that extracts
        information from a persistence engine of choice, many applications do
        not require such complexity. One alternative is to configure an
        authentication repository in the application context itself using the
        <literal>InMemoryDaoImpl</literal>:</para>

        <para><programlisting>&lt;bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl"&gt;
  &lt;property name="userMap"&gt;
    &lt;value&gt;
      marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
      dianne=emu,ROLE_TELLER
      scott=wombat,ROLE_TELLER
      peter=opal,disabled,ROLE_TELLER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>The <literal>userMap</literal> property contains each of the
        usernames, passwords, a list of granted authorities and an optional
        enabled/disabled keyword. Commas delimit each token. The username must
        appear to the left of the equals sign, and the password must be the
        first token to the right of the equals sign. The
        <literal>enabled</literal> and <literal>disabled</literal> keywords
        (case insensitive) may appear in the second or any subsequent token.
        Any remaining tokens are treated as granted authorities, which are
        created as <literal>GrantedAuthorityImpl</literal> objects (refer to
        the Authorization section for further discussion on granted
        authorities). Note that if a user has no password and/or no granted
        authorities, the user will not be created in the in-memory
        authentication repository.</para>
      </sect2>

      <sect2 id="security-authentication-provider-jdbc">
        <title>JDBC Authentication</title>

        <para>The Acegi Security System for Spring also includes an
        authentication provider that can obtain authentication information
        from a JDBC data source. The typical configuration for the
        <literal>JdbcDaoImpl</literal> is shown below:</para>

        <para><programlisting>&lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
  &lt;property name="driverClassName"&gt;&lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;&lt;/property&gt;
  &lt;property name="url"&gt;&lt;value&gt;jdbc:hsqldb:hsql://localhost:9001&lt;/value&gt;&lt;/property&gt;
  &lt;property name="username"&gt;&lt;value&gt;sa&lt;/value&gt;&lt;/property&gt;
  &lt;property name="password"&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl"&gt;
  &lt;property name="dataSource"&gt;&lt;ref bean="dataSource"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>You can use different relational database management systems by
        modifying the <literal>DriverManagerDataSource</literal> shown above.
        Irrespective of the database used, a standard schema must be used as
        indicated in <literal>dbinit.txt</literal>.</para>

        <para>If you default schema is unsuitable for your needs,
        <literal>JdbcDaoImpl</literal> provides two properties that allow
        customisation of the SQL statements. You may also subclass the
        <literal>JdbcDaoImpl</literal> if further customisation is necessary.
        Please refer to the JavaDocs for details.</para>

        <para>The Acegi Security System for Spring ships with a Hypersonic SQL
        instance that has the required authentication information and sample
        data already populated. To use this server, simply execute the
        <literal>server.bat</literal> or <literal>server.sh</literal> script
        included in the distribution. This will load a new database server
        instance that will service requests made to the URL indicated in the
        bean context configuration shown above.</para>
      </sect2>

      <sect2 id="security-authentication-concurrent-login">
        <title>Concurrent Session Support</title>

        <para>Acegi Security is able to stop the same principal authenticating
        to the same web application multiple times concurrently. Put
        differently, you can stop user "Batman" from logging into a web
        application twice at the same time.</para>

        <para>To use concurrent session support, you'll need to add the
        following to web.xml:</para>

        <para><programlisting>&lt;listener&gt;
  &lt;listener-class&gt;net.sf.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;
&lt;/listener&gt;</programlisting></para>

        <para>The above code causes an <literal>ApplicationEvent</literal> to
        be published to the Spring <literal>ApplicationContext</literal> every
        time a <literal>HttpSession</literal> commences or terminates. This is
        critical, as it allows the
        <literal>ConcurrentSessionControllerImpl</literal> to be notified when
        a session ends. Next up you'll need to wire the
        <literal>ConcurrentSessionControllerImpl</literal> into your existing
        <literal>ProviderManager</literal>:</para>

        <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
  &lt;property name="providers"&gt;
    &lt;!-- your providers go here --&gt;
  &lt;/property&gt;
  &lt;property name="sessionController"&gt;&lt;ref bean="concurrentSessionController"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="concurrentSessionController" class="net.sf.acegisecurity.providers.ConcurrentSessionControllerImpl"&gt;
  &lt;property name="maxSessions"&gt;&lt;value&gt;1&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>Ensure you do not in-line the
        <literal>ConcurrentSessionControllerImpl</literal> when declaring it
        in your XML. This is important, as it appears that in-lined bean
        declarations do not receive ApplicationEvents.</para>

        <para>The <literal>ConcurrentSessionControllerImpl</literal> relies
        heavily on the
        <literal>Authentication.getPrincipal().equals()</literal> method. If
        you are using a custom <literal>Authentication</literal> object,
        please keep this in mind. In order for the
        <literal>ConcurrentSessionControllerImpl</literal> to release a given
        <literal>HttpSession</literal>, and thus let the user log in to a new
        <literal>HttpSession</literal>, the existing
        <literal>HttpSession</literal> must be invalidated. For example, if
        "Batman" logs into the web application, checks for crimes being
        commited, and the just closes his browser with out "logging out", he
        will not be able to log back in until his
        <literal>HttpSession</literal> is timed out by the server (and a
        corresponding <literal>ApplicationEvent</literal> is published via
        <literal>HttpSessionEventPublisher</literal> to the
        <literal>ConcurrentSessionControllerImpl</literal>). You would have to
        look at your container's documentation to determine the default
        timeout period. You can also configure the session timeout in your
        <literal>web.xml</literal>:<programlisting>&lt;session-config&gt;
  &lt;session-timeout&gt;30&lt;/session-timeout&gt;
&lt;/session-config&gt;</programlisting></para>
      </sect2>

      <sect2 id="security-authentication-provider-jaas">
        <title>JAAS Authentication</title>

        <para>Acegi 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>

        <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>

        <sect3>
          <title>JaasAuthenticationProvider</title>

          <para>The <literal>JaasAuthenticationProvider</literal> attempts to
          authenticate a user’s principal and credentials through JAAS.</para>

          <para>Let’s assume we have a JAAS login configuration file,
          <literal>/WEB-INF/login.conf</literal>, with the following
          contents:</para>

          <para><programlisting>JAASTest {
  sample.SampleLoginModule required;
};</programlisting></para>

          <para>Like all Acegi Security beans, the
          <literal>JaasAuthenticationProvider</literal> is configured via the
          application context. The following definitions would correspond to
          the above JAAS login configuration file:</para>

          <para><programlisting>&lt;bean id="jaasAuthenticationProvider" class="net.sf.acegisecurity.providers.jaas.JaasAuthenticationProvider"&gt;
  &lt;property name="loginConfig"&gt;
    &lt;value&gt;/WEB-INF/login.conf&lt;/value&gt;
  &lt;/property&gt;
  &lt;property name="loginContextName"&gt;
    &lt;value&gt;JAASTest&lt;/value&gt;
  &lt;/property&gt;
  &lt;property name="callbackHandlers"&gt;
    &lt;list&gt;
      &lt;bean class="net.sf.acegisecurity.providers.jaas.JaasNameCallbackHandler"/&gt;
      &lt;bean class="net.sf.acegisecurity.providers.jaas.JaasPasswordCallbackHandler"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
  &lt;property name="authorityGranters"&gt;
    &lt;list&gt;
      &lt;bean class="net.sf.acegisecurity.providers.jaas.TestAuthorityGranter"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

          <para>The <literal>CallbackHandler</literal>s and
          <literal>AuthorityGranter</literal>s are discussed below.</para>
        </sect3>

        <sect3>
          <title>Callbacks</title>

          <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. In an Acegi Security
          deployment, Acegi Security is responsible for this user interaction
          (typically via a reference to a
          <literal>ContextHolder</literal>-managed
          <literal>Authentication</literal> object). The JAAS package for
          Acegi 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. For those needing full control over the callback
          behavior, internally <literal>JaasAutheticationProvider</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>
        </sect3>

        <sect3>
          <title>AuthorityGranters</title>

          <para>JAAS works with principals. Even “roles” are represented as
          principals in JAAS. Acegi Security, on the other hand, works with
          <literal>Authentication</literal> objects. Each
          <literal>Authentication</literal> object contains a single
          principal, and multiple <literal>GrantedAuthority</literal>[]s. To
          facilitate mapping between these different concepts, the Acegi
          Security JAAS package includes an
          <literal>AuthorityGranter</literal> interface. An
          <literal>AuthorityGranter</literal> is responsible for inspecting a
          JAAS principal and returning a <literal>String</literal>. The
          <literal>JaasAuthenticationProvider</literal> then creates a
          <literal>JaasGrantedAuthority</literal> (which implements Acegi
          Security’s <literal>GrantedAuthority</literal> interface) containing
          both the <literal>AuthorityGranter</literal>-returned
          <literal>String</literal> and the JAAS principal that the
          <literal>AuthorityGranter</literal> was passed. The
          <literal>JaasAuthenticationProvider</literal> 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
          <literal>AuthorityGranter</literal> defined against the
          <literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal>
          property. Acegi Security does not include any production
          <literal>AuthorityGranter</literal>s given 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>
        </sect3>
      </sect2>

      <sect2 id="security-authentication-recommendations">
        <title>Authentication Recommendations</title>

        <para>With the heavy use of interfaces throughout the authentication
        system (<literal>Authentication</literal>,
        <literal>AuthenticationManager</literal>,
        <literal>AuthenticationProvider</literal> and
        <literal>AuthenticationDao</literal>) it might be confusing to a new
        user to know which part of the authentication system to customize. In
        general, the following is recommended:</para>

        <itemizedlist>
          <listitem>
            <para>Use the
            <literal>UsernamePasswordAuthenticationToken</literal>
            implementation where possible.</para>
          </listitem>

          <listitem>
            <para>If you simply need to implement a new authentication
            repository (eg to obtain user details from your application’s
            existing database), use the
            <literal>DaoAuthenticationProvider</literal> along with the
            <literal>AuthenticationDao</literal>. It is the fastest and safest
            way to integrate an external database.</para>
          </listitem>

          <listitem>
            <para>If you're using Container Adapters or a
            <literal>RunAsManager</literal> that replaces the
            <literal>Authentication</literal> object, ensure you have
            registered the <literal>AuthByAdapterProvider</literal> and
            <literal>RunAsManagerImplProvider</literal> respectively with your
            <literal>ProviderManager</literal>.</para>
          </listitem>

          <listitem>
            <para>Never enable the
            <literal>TestingAuthenticationProvider</literal> on a production
            system. Doing so will allow any client to simply present a
            <literal>TestingAuthenticationToken</literal> and obtain whatever
            access they request.</para>
          </listitem>

          <listitem>
            <para>Adding a new <literal>AuthenticationProvider</literal> is
            sufficient to support most custom authentication requirements.
            Only unusual requirements would require the
            <literal>ProviderManager</literal> to be replaced with a different
            <literal>AuthenticationManager</literal>.</para>
          </listitem>
        </itemizedlist>
      </sect2>
    </sect1>

    <sect1 id="security-authorization">
      <title>Authorization</title>

      <sect2 id="security-authorization-granted-authorities">
        <title>Granted Authorities</title>

        <para>As briefly mentioned in the Authentication section, all
        <literal>Authentication</literal> implementations are required to
        store an array of <literal>GrantedAuthority</literal> objects. These
        represent the authorities that have been granted to the principal. The
        <literal>GrantedAuthority</literal> objects are inserted into the
        <literal>Authentication</literal> object by the
        <literal>AuthenticationManager</literal> and are later read by
        <literal>AccessDecisionManager</literal>s when making authorization
        decisions.</para>

        <para><literal>GrantedAuthority</literal> is an interface with only
        one method:</para>

        <para><programlisting>public String getAuthority();</programlisting></para>

        <para>This method allows <literal>AccessDecisionManager</literal>s to
        obtain a precise <literal>String</literal> representation of the
        <literal>GrantedAuthority</literal>. By returning a representation as
        a <literal>String</literal>, a <literal>GrantedAuthority</literal> can
        be easily "read" by most <literal>AccessDecisionManager</literal>s. If
        a <literal>GrantedAuthority</literal> cannot be precisely represented
        as a <literal>String</literal>, the
        <literal>GrantedAuthority</literal> is considered "complex" and
        <literal>getAuthority()</literal> must return
        <literal>null</literal>.</para>

        <para>An example of a "complex" <literal>GrantedAuthority</literal>
        would be an implementation that stores a list of operations and
        authority thresholds that apply to different customer account numbers.
        Representing this complex <literal>GrantedAuthority</literal> as a
        <literal>String</literal> would be quite complex, and as a result the
        <literal>getAuthority()</literal> method should return
        <literal>null</literal>. This will indicate to any
        <literal>AccessDecisionManager</literal> that it will need to
        specifically support the <literal>GrantedAuthority</literal>
        implementation in order to understand its contents.</para>

        <para>The Acegi Security System for Spring includes one concrete
        <literal>GrantedAuthority</literal> implementation,
        <literal>GrantedAuthorityImpl</literal>. This allows any
        user-specified <literal>String</literal> to be converted into a
        <literal>GrantedAuthority</literal>. All
        <literal>AuthenticationProvider</literal>s included with the security
        architecture use <literal>GrantedAuthorityImpl</literal> to populate
        the <literal>Authentication</literal> object.</para>
      </sect2>

      <sect2 id="security-authorization-access-decision-managers">
        <title>Access Decision Managers</title>

        <para>The <literal>AccessDecisionManager</literal> is called by the
        <literal>AbstractSecurityInterceptor</literal> and is responsible for
        making final access control decisions. The
        <literal>AccessDecisionManager</literal> interface contains three
        methods:</para>

        <para><programlisting>public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException;
public boolean supports(ConfigAttribute attribute);
public boolean supports(Class clazz);</programlisting></para>

        <para>As can be seen from the first method, the
        <literal>AccessDecisionManager</literal> is passed via method
        parameters all information that is likely to be of value in assessing
        an authorization decision. In particular, passing the secure
        <literal>Object</literal> enables those arguments contained in the
        actual secure object invocation to be inspected. For example, let's
        assume the secure object was a <literal>MethodInvocation</literal>. It
        would be easy to query the <literal>MethodInvocation</literal> for any
        <literal>Customer</literal> argument, and then implement some sort of
        security logic in the <literal>AccessDecisionManager</literal> to
        ensure the principal is permitted to operate on that customer.
        Implementations are expected to throw an
        <literal>AccessDeniedException</literal> if access is denied.</para>

        <para>The <literal>supports(ConfigAttribute)</literal> method is
        called by the <literal>AbstractSecurityInterceptor</literal> at
        startup time to determine if the
        <literal>AccessDecisionManager</literal> can process the passed
        <literal>ConfigAttribute</literal>. The
        <literal>supports(Class)</literal> method is called by a security
        interceptor implementation to ensure the configured
        <literal>AccessDecisionManager</literal> supports the type of secure
        object that the security interceptor will present.</para>
      </sect2>

      <sect2 id="security-authorization-voting-decision-manager">
        <title>Voting Decision Manager</title>

        <para>Whilst users can implement their own
        <literal>AccessDecisionManager</literal> to control all aspects of
        authorization, the Acegi Security System for Spring includes several
        <literal>AccessDecisionManager</literal> implementations that are
        based on voting. Figure 4 illustrates the relevant classes.</para>

        <para><mediaobject>
            <imageobject role="html">
              <imagedata align="center"
                         fileref="images/AccessDecisionVoting.gif"
                         format="GIF" />
            </imageobject>

            <caption>
              <para>Figure 4: Voting Decision Manager</para>
            </caption>
          </mediaobject></para>

        <para>Using this approach, a series of
        <literal>AccessDecisionVoter</literal> implementations are polled on
        an authorization decision. The
        <literal>AccessDecisionManager</literal> then decides whether or not
        to throw an <literal>AccessDeniedException</literal> based on its
        assessment of the votes.</para>

        <para>The <literal>AccessDecisionVoter</literal> interface has three
        methods:</para>

        <para><programlisting>public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
public boolean supports(ConfigAttribute attribute);
public boolean supports(Class clazz);</programlisting></para>

        <para>Concrete implementations return an <literal>int</literal>, with
        possible values being reflected in the
        <literal>AccessDecisionVoter</literal> static fields
        <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal>
        and <literal>ACCESS_GRANTED</literal>. A voting implementation will
        return <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an
        authorization decision. If it does have an opinion, it must return
        either <literal>ACCESS_DENIED</literal> or
        <literal>ACCESS_GRANTED</literal>.</para>

        <para>There are three concrete
        <literal>AccessDecisionManager</literal>s provided with the Acegi
        Security System for Spring that tally the votes. The
        <literal>ConsensusBased</literal> implementation will grant or deny
        access based on the consensus of non-abstain votes. Properties are
        provided to control behavior in the event of an equality of votes or
        if all votes are abstain. The <literal>AffirmativeBased</literal>
        implementation will grant access if one or more
        <literal>ACCESS_GRANTED</literal> votes were received (ie a deny vote
        will be ignored, provided there was at least one grant vote). Like the
        <literal>ConsensusBased</literal> implementation, there is a parameter
        that controls the behavior if all voters abstain. The
        <literal>UnanimousBased</literal> provider expects unanimous
        <literal>ACCESS_GRANTED</literal> votes in order to grant access,
        ignoring abstains. It will deny access if there is any
        <literal>ACCESS_DENIED</literal> vote. Like the other implementations,
        there is a parameter that controls the behaviour if all voters
        abstain.</para>

        <para>It is possible to implement a custom
        <literal>AccessDecisionManager</literal> that tallies votes
        differently. For example, votes from a particular
        <literal>AccessDecisionVoter</literal> might receive additional
        weighting, whilst a deny vote from a particular voter may have a veto
        effect.</para>

        <para>There are two concrete <literal>AccessDecisionVoter</literal>
        implementations provided with the Acegi Security System for Spring.
        The <literal>RoleVoter</literal> class will vote if any
        ConfigAttribute begins with <literal>ROLE_</literal>. It will vote to
        grant access if there is a <literal>GrantedAuthority</literal> which
        returns a <literal>String</literal> representation (via the
        <literal>getAuthority()</literal> method) exactly equal to one or more
        <literal>ConfigAttributes</literal> starting with
        <literal>ROLE_</literal>. If there is no exact match of any
        <literal>ConfigAttribute</literal> starting with
        <literal>ROLE_</literal>, the <literal>RoleVoter</literal> will vote
        to deny access. If no <literal>ConfigAttribute</literal> begins with
        <literal>ROLE_</literal>, the voter will abstain.
        <literal>RoleVoter</literal> is case sensitive on comparisons as well
        as the <literal>ROLE_</literal> prefix.</para>

        <para>BasicAclEntryVoter is the other concrete voter included with
        Acegi Security. It integrates with Acegi Security's
        <literal>AclManager</literal> (discussed later). This voter is
        designed to have multiple instances in the same application context,
        such as:</para>

        <para><programlisting>&lt;bean id="aclContactReadVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter"&gt;
  &lt;property name="processConfigAttribute"&gt;&lt;value&gt;ACL_CONTACT_READ&lt;/value&gt;&lt;/property&gt;
  &lt;property name="processDomainObjectClass"&gt;&lt;value&gt;sample.contact.Contact&lt;/value&gt;&lt;/property&gt;
  &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  &lt;property name="requirePermission"&gt;
    &lt;list&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="aclContactDeleteVoter" class="net.sf.acegisecurity.vote.BasicAclEntryVoter"&gt;
  &lt;property name="processConfigAttribute"&gt;&lt;value&gt;ACL_CONTACT_DELETE&lt;/value&gt;&lt;/property&gt;
  &lt;property name="processDomainObjectClass"&gt;&lt;value&gt;sample.contact.Contact&lt;/value&gt;&lt;/property&gt;
  &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  &lt;property name="requirePermission"&gt;
    &lt;list&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>In the above example, you'd define
        <literal>ACL_CONTACT_READ</literal> or
        <literal>ACL_CONTACT_DELETE</literal> against some methods on a
        <literal>MethodSecurityInterceptor</literal> or
        <literal>AspectJSecurityInterceptor</literal>. When those methods are
        invoked, the above applicable voter defined above would vote to grant
        or deny access. The voter would look at the method invocation to
        locate the first argument of type
        <literal>sample.contact.Contact</literal>, and then pass that
        <literal>Contact</literal> to the <literal>AclManager</literal>. The
        <literal>AclManager</literal> will then return an access control list
        (ACL) that applies to the current <literal>Authentication</literal>.
        Assuming that ACL contains one of the listed
        <literal>requirePermission</literal>s, the voter will vote to grant
        access. If the ACL does not contain one of the permissions defined
        against the voter, the voter will vote to deny access.
        <literal>BasicAclEntryVoter</literal> is an important class as it
        allows you to build truly complex applications with domain object
        security entirely defined in the application context. If you're
        interested in learning more about Acegi Security's ACL capabilities
        and how best to apply them, please see the ACL and "After Invocation"
        sections of this reference guide, and the Contacts sample
        application.</para>

        <para>It is also possible to implement a custom
        <literal>AccessDecisionVoter</literal>. Several examples are provided
        in the Acegi Security System for Spring unit tests, including
        <literal>ContactSecurityVoter</literal> and
        <literal>DenyVoter</literal>. The
        <literal>ContactSecurityVoter</literal> abstains from voting decisions
        where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal>
        <literal>ConfigAttribute</literal> is not found. If voting, it queries
        the <literal>MethodInvocation</literal> to extract the owner of the
        <literal>Contact</literal> object that is subject of the method call.
        It votes to grant access if the <literal>Contact</literal> owner
        matches the principal presented in the
        <literal>Authentication</literal> object. It could have just as easily
        compared the <literal>Contact</literal> owner with some
        <literal>GrantedAuthority</literal> the
        <literal>Authentication</literal> object presented. All of this is
        achieved with relatively few lines of code and demonstrates the
        flexibility of the authorization model.</para>
      </sect2>

      <sect2 id="security-authorization-taglib">
        <title>Authorization-Related Tag Libraries</title>

        <para>The Acegi Security System for Spring comes bundled with several
        JSP tag libraries that eases JSP writing. The tag libraries are known
        as <literal>authz</literal> and provide a range of different
        services.</para>

        <para>All taglib classes are included in the core
        <literal>acegi-security-xx.jar</literal> file, with the
        <literal>authz.tld</literal> located in the JAR's
        <literal>META-INF</literal> directory. This means for JSP 1.2+ web
        containers you can simply include the JAR in the WAR's
        <literal>WEB-INF/lib</literal> directory and it will be available. If
        you're using a JSP 1.1 container, you'll need to declare the JSP
        taglib in your <literal>web.xml file</literal>, and include
        <literal>authz.tld</literal> in the <literal>WEB-INF/lib</literal>
        directory. The following fragment is added to
        <literal>web.xml</literal>:</para>

        <para><programlisting>&lt;taglib&gt;
       &lt;taglib-uri&gt;http://acegisecurity.sf.net/authz&lt;/taglib-uri&gt;
       &lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
&lt;/taglib&gt;</programlisting></para>

        <sect3>
          <title>AuthorizeTag</title>

          <para><literal>AuthorizeTag</literal> is used to include content if
          the current principal holds certain
          <literal>GrantedAuthority</literal>s.</para>

          <para>The following JSP fragment illustrates how to use the
          <literal>AuthorizeTag</literal>:</para>

          <para><programlisting>&lt;authz:authorize ifAllGranted="ROLE_SUPERVISOR"&gt;
  &lt;td&gt;
    &lt;A HREF="del.htm?id=&lt;c:out value="${contact.id}"/&gt;"&gt;Del&lt;/A&gt;
  &lt;/td&gt;
&lt;/authz:authorize&gt;</programlisting></para>

          <para>This tag would cause the tag's body to be output if the
          principal has been granted ROLE_SUPERVISOR.</para>

          <para>The <literal>authz:authorize</literal> tag declares the
          following attributes:</para>

          <para><itemizedlist spacing="compact">
              <listitem>
                <para><literal>ifAllGranted</literal>: All the listed roles
                must be granted for the tag to output its body.</para>
              </listitem>

              <listitem>
                <para><literal>ifAnyGranted</literal>: Any of the listed roles
                must be granted for the tag to output its body.</para>
              </listitem>

              <listitem>
                <para><literal>ifNotGranted</literal>: None of the listed
                roles must be granted for the tag to output its body.</para>
              </listitem>
            </itemizedlist></para>

          <para>You'll note that in each attribute you can list multiple
          roles. Simply separate the roles using a comma. The
          <literal>authorize</literal> tag ignores whitespace in
          attributes.</para>

          <para>The tag library logically ANDs all of it's parameters
          together. This means that if you combine two or more attributes, all
          attributes must be true for the tag to output it's body. Don't add
          an <literal>ifAllGranted="ROLE_SUPERVISOR"</literal>, followed by an
          <literal>ifNotGranted="ROLE_SUPERVISOR"</literal>, or you'll be
          surprised to never see the tag's body.</para>

          <para>By requiring all attributes to return true, the authorize tag
          allows you to create more complex authorization scenarios. For
          example, you could declare an
          <literal>ifAllGranted="ROLE_SUPERVISOR"</literal> and an
          <literal>ifNotGranted="ROLE_NEWBIE_SUPERVISOR"</literal> in the same
          tag, in order to prevent new supervisors from seeing the tag body.
          However it would no doubt be simpler to use
          <literal>ifAllGranted="ROLE_EXPERIENCED_SUPERVISOR"</literal> rather
          than inserting NOT conditions into your design.</para>

          <para>One last item: the tag verifies the authorizations in a
          specific order: first <literal>ifNotGranted</literal>, then
          <literal>ifAllGranted</literal>, and finally,
          <literal>ifAnyGranted</literal>.</para>
        </sect3>

        <sect3>
          <title>AuthenticationTag</title>

          <para><literal>AuthenticationTag</literal> is used to simply output
          the current principal to the web page.</para>

          <para>The following JSP fragment illustrates how to use the
          <literal>AuthenticationTag</literal>:</para>

          <para><programlisting>&lt;authz:authentication operation="principal"/&gt;</programlisting></para>

          <para>This tag would cause the principal's name to be output. The
          taglib properly supports the various types of principals that can
          exist in the <literal>Authentication</literal> object, such as a
          <literal>String</literal> or <literal>UserDetails</literal>
          instance.</para>

          <para>The "operation" attribute must always be "principal". This may
          be expanded in the future, such as obtaining other
          <literal>Authentication</literal>-related properties such as email
          address or telephone numbers.</para>
        </sect3>

        <sect3>
          <title>AclTag</title>

          <para><literal>AclTag</literal> is used to include content if the
          current principal has a ACL to the indicated domain object.</para>

          <para>The following JSP fragment illustrates how to use the
          <literal>AclTag</literal>:</para>

          <para><programlisting>&lt;authz:acl domainObject="${contact}" hasPermission="16,1"&gt;
  &lt;td&gt;&lt;A HREF="&lt;c:url value="del.htm"&gt;&lt;c:param name="contactId" value="${contact.id}"/&gt;&lt;/c:url&gt;"&gt;Del&lt;/A&gt;&lt;/td&gt;
&lt;/authz:acl&gt;</programlisting></para>

          <para>This tag would cause the tag's body to be output if the
          principal holds either permission 16 or permission 1 for the
          "contact" domain object. The numbers are actually integers that are
          used with <literal>AbstractBasicAclEntry</literal> bit masking.
          Please refer tro the ACL section of this reference guide to
          understand more about the ACL capabilities of Acegi Security.</para>
        </sect3>
      </sect2>

      <sect2 id="security-authorization-recommendations">
        <title>Authorization Recommendations</title>

        <para>Given there are several ways to achieve similar authorization
        outcomes in the Acegi Security System for Spring, the following
        general recommendations are made:</para>

        <itemizedlist>
          <listitem>
            <para>Grant authorities using
            <literal>GrantedAuthorityImpl</literal> where possible. Because it
            is already supported by the Acegi Security System for Spring, you
            avoid the need to create custom
            <literal>AuthenticationManager</literal> or
            <literal>AuthenticationProvider</literal> implementations simply
            to populate the <literal>Authentication</literal> object with a
            custom <literal>GrantedAuthority</literal>.</para>
          </listitem>

          <listitem>
            <para>Writing an <literal>AccessDecisionVoter</literal>
            implementation and using either <literal>ConsensusBased</literal>,
            <literal>AffirmativeBased</literal> or
            <literal>UnanimousBased</literal> as the
            <literal>AccessDecisionManager</literal> may be the best approach
            to implementing your custom access decision rules.</para>
          </listitem>
        </itemizedlist>
      </sect2>
    </sect1>

    <sect1 id="afterinvocation">
      <title>After Invocation Handling</title>

      <sect2 id="afterinvocation-overview">
        <title>Overview</title>

        <para>Whilst the <literal>AccessDecisionManager</literal> is called by
        the <literal>AbstractSecurityInterceptor</literal> before proceeding
        with the secure object invocation, some applications need a way of
        modifying the object actually returned by the secure object
        invocation. Whilst you could easily implement your own AOP concern to
        achieve this, Acegi Security provides a convenient hook that has
        several concrete implementations that integrate with its ACL
        capabilities.</para>

        <para>Figure 5 illustrates Acegi Security's
        <literal>AfterInvocationManager</literal> and its concrete
        implementations.</para>

        <para><mediaobject>
            <imageobject role="html">
              <imagedata align="center" fileref="images/AfterInvocation.gif"
                         format="GIF" />
            </imageobject>

            <caption>
              <para>Figure 5: After Invocation Implementation</para>
            </caption>
          </mediaobject></para>

        <para>Like many other parts of Acegi Security,
        <literal>AfterInvocationManager</literal> has a single concrete
        implementation, <literal>AfterInvocationProvider</literal>, which
        polls a list of <literal>AfterInvocationProvider</literal>s. Each
        <literal>AfterInvocationProvider</literal> is allowed to modify the
        return object or throw an <literal>AccessDeniedException</literal>.
        Indeed multiple providers can modify the object, as the result of the
        previous provider is passed to the next in the list. Let's now
        consider our ACL-aware implementations of
        <literal>AfterInvocationProvider</literal>.</para>

        <para>Please be aware that if you're using
        <literal>AfterInvocationManager</literal>, you will still need
        configuration attributes that allow the
        <literal>MethodSecurityInterceptor</literal>'s
        <literal>AccessDecisionManager</literal> to allow an operation. If
        you're using the typical Acegi Security included
        <literal>AccessDecisionManager</literal> implementations, having no
        configuration attributes defined for a particular secure method
        invocation will cause each <literal>AccessDecisionVoter</literal> to
        abstain from voting. In turn, if the
        <literal>AccessDecisionManager</literal> property
        "<literal>allowIfAllAbstainDecisions</literal>" is
        <literal>false</literal>, an <literal>AccessDeniedException</literal>
        will be thrown. You may avoid this potential issue by either (i)
        setting "<literal>allowIfAllAbstainDecisions</literal>" to
        <literal>true</literal> (although this is generally not recommended)
        or (ii) simply ensure that there is at least one configuration
        attribute that an <literal>AccessDecisionVoter</literal> will vote to
        grant access for. This latter (recommended) approach is usually
        achieved through a <literal>ROLE_USER</literal> or
        <literal>ROLE_AUTHENTICATED</literal> configuration attribute.</para>
      </sect2>

      <sect2 id="afterinvocation-acl-aware">
        <title>ACL-Aware AfterInvocationProviders</title>

        <para>A common services layer method we've all written at one stage or
        another looks like this:</para>

        <para><programlisting>public Contact getById(Integer id);</programlisting></para>

        <para>Quite often, only principals with permission to read the
        <literal>Contact</literal> should be allowed to obtain it. In this
        situation the <literal>AccessDecisionManager</literal> approach
        provided by the <literal>AbstractSecurityInterceptor</literal> will
        not suffice. This is because the identity of the
        <literal>Contact</literal> is all that is available before the secure
        object is invoked. The
        <literal>BasicAclAfterInvocationProvider</literal> delivers a
        solution, and is configured as follows:</para>

        <para><programlisting>&lt;bean id="afterAclRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider"&gt;
  &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  &lt;property name="requirePermission"&gt;
    &lt;list&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>In the above example, the <literal>Contact</literal> will be
        retrieved and passed to the
        <literal>BasicAclEntryAfterInvocationProvider</literal>. The provider
        will thrown an <literal>AccessDeniedException</literal> if one of the
        listed <literal>requirePermission</literal>s is not held by the
        <literal>Authentication</literal>. The
        <literal>BasicAclEntryAfterInvocationProvider</literal> queries the
        <literal>AclManager</literal> to determine the ACL that applies for
        this domain object to this <literal>Authentication</literal>.</para>

        <para>Similar to the
        <literal>BasicAclEntryAfterInvocationProvider</literal> is
        <literal>BasicAclEntryAfterInvocationCollectionFilteringProvider</literal>.
        It is designed to remove <literal>Collection</literal> or array
        elements for which a principal does not have access. It never thrown
        an <literal>AccessDeniedException</literal> - simply silently removes
        the offending elements. The provider is configured as follows:</para>

        <para><programlisting>&lt;bean id="afterAclCollectionRead" class="net.sf.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider"&gt;
  &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  &lt;property name="requirePermission"&gt;
    &lt;list&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="net.sf.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>As you can imagine, the returned <literal>Object</literal> must
        be a <literal>Collection</literal> or array for this provider to
        operate. It will remove any element if the
        <literal>AclManager</literal> indicates the
        <literal>Authentication</literal> does not hold one of the listed
        <literal>requirePermission</literal>s.</para>

        <para>The Contacts sample application demonstrates these two
        <literal>AfterInvocationProvider</literal>s.</para>
      </sect2>
    </sect1>

    <sect1 id="security-run-as">
      <title>Run-As Authentication Replacement</title>

      <sect2 id="security-run-as-purpose">
        <title>Purpose</title>

        <para>The <literal>AbstractSecurityInterceptor</literal> is able to
        temporarily replace the <literal>Authentication</literal> object in
        the <literal>SecureContext</literal> and
        <literal>ContextHolder</literal> during the
        <literal>SecurityInterceptorCallback</literal>. This only occurs if
        the original <literal>Authentication</literal> object was successfully
        processed by the <literal>AuthenticationManager</literal> and
        <literal>AccessDecisionManager</literal>. The
        <literal>RunAsManager</literal> will indicate the replacement
        <literal>Authentication</literal> object, if any, that should be used
        during the <literal>SecurityInterceptorCallback</literal>.</para>

        <para>By temporarily replacing the <literal>Authentication</literal>
        object during a <literal>SecurityInterceptorCallback</literal>, the
        secured invocation will be able to call other objects which require
        different authentication and authorization credentials. It will also
        be able to perform any internal security checks for specific
        <literal>GrantedAuthority</literal> objects. Because Acegi Security
        provides a number of helper classes that automatically configure
        remoting protocols based on the contents of the
        <literal>ContextHolder</literal>, these run-as replacements are
        particularly useful when calling remote web services.</para>
      </sect2>

      <sect2 id="security-run-as-usage">
        <title>Usage</title>

        <para>A <literal>RunAsManager</literal> interface is provided by the
        Acegi Security System for Spring:</para>

        <para><programlisting>public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config);
public boolean supports(ConfigAttribute attribute);
public boolean supports(Class clazz);</programlisting></para>

        <para>The first method returns the <literal>Authentication</literal>
        object that should replace the existing
        <literal>Authentication</literal> object for the duration of the
        method invocation. If the method returns <literal>null</literal>, it
        indicates no replacement should be made. The second method is used by
        the <literal>AbstractSecurityInterceptor</literal> as part of its
        startup validation of configuration attributes. The
        <literal>supports(Class)</literal> method is called by a security
        interceptor implementation to ensure the configured
        <literal>RunAsManager</literal> supports the type of secure object
        that the security interceptor will present.</para>

        <para>One concrete implementation of a <literal>RunAsManager</literal>
        is provided with the Acegi Security System for Spring. The
        <literal>RunAsManagerImpl</literal> class returns a replacement
        <literal>RunAsUserToken</literal> if any
        <literal>ConfigAttribute</literal> starts with
        <literal>RUN_AS_</literal>. If any such
        <literal>ConfigAttribute</literal> is found, the replacement
        <literal>RunAsUserToken</literal> will contain the same principal,
        credentials and granted authorities as the original
        <literal>Authentication</literal> object, along with a new
        <literal>GrantedAuthorityImpl</literal> for each
        <literal>RUN_AS_</literal> <literal>ConfigAttribute</literal>. Each
        new <literal>GrantedAuthorityImpl</literal> will be prefixed with
        <literal>ROLE_</literal>, followed by the <literal>RUN_AS</literal>
        <literal>ConfigAttribute</literal>. For example, a
        <literal>RUN_AS_SERVER</literal> will result in the replacement
        <literal>RunAsUserToken</literal> containing a
        <literal>ROLE_RUN_AS_SERVER</literal> granted authority.</para>

        <para>The replacement <literal>RunAsUserToken</literal> is just like
        any other <literal>Authentication</literal> object. It needs to be
        authenticated by the <literal>AuthenticationManager</literal>,
        probably via delegation to a suitable
        <literal>AuthenticationProvider</literal>. The
        <literal>RunAsImplAuthenticationProvider</literal> performs such
        authentication. It simply accepts as valid any
        <literal>RunAsUserToken</literal> presented.</para>

        <para>To ensure malicious code does not create a
        <literal>RunAsUserToken</literal> and present it for guaranteed
        acceptance by the <literal>RunAsImplAuthenticationProvider</literal>,
        the hash of a key is stored in all generated tokens. The
        <literal>RunAsManagerImpl</literal> and
        <literal>RunAsImplAuthenticationProvider</literal> is created in the
        bean context with the same key:</para>

        <para><programlisting>&lt;bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl"&gt;
  &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting><programlisting>&lt;bean id="runAsAuthenticationProvider" class="net.sf.acegisecurity.runas.RunAsImplAuthenticationProvider"&gt;
  &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>By using the same key, each <literal>RunAsUserToken</literal>
        can be validated it was created by an approved
        <literal>RunAsManagerImpl</literal>. The
        <literal>RunAsUserToken</literal> is immutable after creation for
        security reasons.</para>
      </sect2>
    </sect1>

    <sect1 id="security-ui">
      <title>User Interfacing with the ContextHolder</title>

      <sect2 id="security-ui-purpose">
        <title>Purpose</title>

        <para>Everything presented so far assumes one thing: the
        <literal>ContextHolder</literal> is populated with a valid
        <literal>SecureContext</literal>, which in turn contains a valid
        <literal>Authentication</literal> object. Developers are free to do
        this in whichever way they like, such as directly calling the relevant
        objects at runtime. However, several classes have been provided to
        make this process transparent in many situations. We call these
        classes "authentication mechanisms".</para>

        <para>The <literal>net.sf.acegisecurity.ui</literal> package provides
        what we call "authentication processing mechanisms". An authentication
        processing mechanism is solely concerned with received an
        authentication request from the principal, testing if it seems valid,
        and if so, placing the authentication request token onto the
        ContextHolder. Of course, if the authentication request is invalid,
        the authentication processing mechanism is responsible for informing
        the principal in whatever way is appropriate to the protocol.</para>

        <para>Recall the HttpSessionContextIntegrationFilter (discussed in the
        context section) is responsible for storing the ContextHolder contents
        between invocations. This means no authentication processing mechanism
        need ever interact directly with HttpSession. Indeed
        HttpSessionContextIntegrationFilter has been designed to minimise the
        unnecessary creation of HttpSessions, as might occur when using Basic
        authentication for example.</para>

        <para>There are several authentication processing mechanisms included
        with Acegi Security, which will be briefly discussed in this chapter.
        The most popular (and almost always recommended) approach is HTTP Form
        Authentication, which uses a login form to authenticate the user.
        Another approach (commonly use with web services) is HTTP Basic
        Authentication, which allows clients to use HTTP headers to present
        authentication information to the Acegi Security System for Spring.
        Alternatively, you can also use Yale Central Authentication Service
        (CAS) for enterprise-wide single sign on. The final (and generally
        unrecommended) approach is via Container Adapters, which allow
        supported web containers to perform the authentication themselves.
        HTTP Form Authentication and Basic Authentication is discussed below,
        whilst CAS and Container Adapters are discussed in separate sections
        of this document.</para>
      </sect2>

      <sect2 id="security-ui-http-form">
        <title>HTTP Form Authentication</title>

        <para>HTTP Form Authentication involves using the
        <literal>AuthenticationProcessingFilter</literal> to process a login
        form. The login form simply contains <literal>j_username</literal> and
        <literal>j_password</literal> input fields, and posts to a URL that is
        monitored by the filter (by default
        <literal>j_acegi_security_check</literal>). The filter is defined in
        <literal>web.xml</literal> behind a
        <literal>FilterToBeanProxy</literal> as follows:</para>

        <para><programlisting>&lt;filter&gt;
  &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>

        <para>For a discussion of <literal>FilterToBeanProxy</literal>, please
        refer to the Filters section. The application context will need to
        define the <literal>AuthenticationProcessingFilter</literal>:</para>

        <para><programlisting>&lt;bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/acegilogin.jsp?login_error=1&lt;/value&gt;&lt;/property&gt;
  &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
  &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_security_check&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>The configured <literal>AuthenticationManager</literal>
        processes each authentication request. If authentication fails, the
        browser will be redirected to the
        <literal>authenticationFailureUrl</literal>. The
        <literal>AuthenticationException</literal> will be placed into the
        <literal>HttpSession</literal> attribute indicated by
        <literal>AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY</literal>,
        enabling a reason to be provided to the user on the error page.</para>

        <para>If authentication is successful, the resulting
        <literal>Authentication</literal> object will be placed into the
        <literal>ContextHolder</literal>.</para>

        <para>Once the <literal>ContextHolder</literal> has been updated, the
        browser will need to be redirected to the target URL. The target URL
        is usually indicated by the <literal>HttpSession</literal> attribute
        specified by
        <literal>AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY</literal>.
        This attribute is automatically set by the
        <literal>SecurityEnforcementFilter</literal> when an
        <literal>AuthenticationException</literal> occurs, so that after login
        is completed the user can return to what they were trying to access.
        If for some reason the <literal>HttpSession</literal> does not
        indicate the target URL, the browser will be redirected to the
        <literal>defaultTargetUrl</literal> property.</para>

        <para>Because this authentication approach is fully contained within a
        single web application, HTTP Form Authentication is recommended to be
        used instead of Container Adapters.</para>
      </sect2>

      <sect2 id="security-ui-http-basic">
        <title>HTTP Basic Authentication</title>

        <para>The Acegi Security System for Spring provides a
        <literal>BasicProcessingFilter</literal> which is capable of
        processing basic authentication credentials presented in HTTP headers.
        This can be used for authenticating calls made by Spring remoting
        protocols (such as Hessian and Burlap), as well as normal user agents
        (such as Internet Explorer and Navigator). The standard governing HTTP
        Basic Authentication is defined by RFC 1945, Section 11, and the
        <literal>BasicProcessingFilter</literal> conforms with this RFC. Basic
        Authentication is an attractive approach to authentication, because it
        is very widely deployed in user agents and implementation is extremely
        simple (it's just a Base64 encoding of the username:password,
        specified in a HTTP header).</para>

        <para>To implement HTTP Basic Authentication, it is necessary to
        define <literal>BasicProcessingFilter</literal> in the fitler chain.
        The application context will need to define the
        <literal>BasicProcessingFilter</literal> and its required
        collaborator:</para>

        <para><programlisting>&lt;bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"&gt;
  &lt;property name="realmName"&gt;&lt;value&gt;Name Of Your Realm&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>The configured <literal>AuthenticationManager</literal>
        processes each authentication request. If authentication fails, the
        configured <literal>AuthenticationEntryPoint</literal> will be used to
        retry the authentication process. Usually you will use the
        <literal>BasicProcessingFilterEntryPoint</literal>, which returns a
        401 response with a suitable header to retry HTTP Basic
        authentication. If authentication is successful, the resulting
        <literal>Authentication</literal> object will be placed into the
        <literal>ContextHolder</literal>.</para>

        <para>If the authentication event was successful, or authentication
        was not attempted because the HTTP header did not contain a supported
        authentication request, the filter chain will continue as normal. The
        only time the filter chain will be interrupted is if authentication
        fails and the <literal>AuthenticationEntryPoint</literal> is called,
        as discussed in the previous paragraph.</para>
      </sect2>

      <sect2 id="security-ui-http-digest">
        <title>HTTP Digest Authentication</title>

        <para>The Acegi Security System for Spring provides a
        <literal>DigestProcessingFilter</literal> which is capable of
        processing digest authentication credentials presented in HTTP
        headers. Digest Authentication attempts to solve many of the
        weakenesses of Basic authentication, specifically by ensuring
        credentials are never sent in clear text across the wire. Many user
        agents support Digest Authentication, including FireFox and Internet
        Explorer. The standard governing HTTP Digest Authentication is defined
        by RFC 2617, which updates an earlier version of the Digest
        Authentication standard prescribed by RFC 2069. Most user agents
        implement RFC 2617. The Acegi Security
        <literal>DigestProcessingFilter</literal> is compatible with the
        "<literal>auth</literal>" quality of protection
        (<literal>qop</literal>) prescribed by RFC 2617, which also provides
        backward compatibility with RFC 2069. Digest Authentication is a
        highly attractive option if you need to use unencrypted HTTP (ie no
        TLS/HTTPS) and wish to maximise security of the authentication
        process. Indeed Digest Authentication is a mandatory requirement for
        the WebDAV protocol, as noted by RFC 2518 Section 17.1, so we should
        expect to see it increasingly deployed and replacing Basic
        Authentication.</para>

        <para>Digest Authentication is definitely the most secure choice
        between Form Authentication, Basic Authentication and Digest
        Authentication, although extra security also means more complex user
        agent implementations. Central to Digest Authentication is a "nonce".
        This is a value the server generates. Acegi Security's nonce adopts
        the following format:</para>

        <para><programlisting>base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))

expirationTime:   The date and time when the nonce expires, expressed in milliseconds
key:              A private key to prevent modification of the nonce token
</programlisting></para>

        <para>The <literal>DigestProcessingFilterEntryPoint</literal> has a
        property specifying the <literal>key</literal> used for generating the
        nonce tokens, along with a <literal>nonceValiditySeconds</literal>
        property for determining the expiration time (default 300, which
        equals five minutes). Whilstever the nonce is valid, the digest is
        computed by concatenating various strings including the username,
        password, nonce, URI being requested, a client-generated nonce (merely
        a random value which the user agent generates each request), the realm
        name etc, then performing an MD5 hash. Both the server and user agent
        perform this digest computation, resulting in different hash codes if
        they disagree on an included value (eg password). In the Acegi
        Security implementation, if the server-generated nonce has merely
        expired (but the digest was otherwise valid), the
        <literal>DigestProcessingFilterEntryPoint</literal> will send a
        <literal>"stale=true"</literal> header. This tells the user agent
        there is no need to disturb the user (as the password and username etc
        is correct), but simply to try again using a new nonce.</para>

        <para>An appropriate value for
        <literal>DigestProcessingFilterEntryPoint</literal>'s
        <literal>nonceValiditySeconds</literal> parameter will depend on your
        application. Extremely secure applications should note that an
        intercepted authentication header can be used to impersonate the
        principal until the <literal>expirationTime</literal> contained in the
        nonce is reached. This is the key principle when selecting an
        appropriate setting, but it would be unusual for immensly secure
        applications to not be running over TLS/HTTPS in the first
        instance.</para>

        <para>Because of the more complex implementation of Digest
        Authentication, there are often user agent issues. For example,
        Internet Explorer fails to present an "<literal>opaque</literal>"
        token on subsequent requests in the same session. The Acegi Security
        filters therefore encapsulate all state information into the
        "<literal>nonce</literal>" token instead. In our testing, the Acegi
        Security implementation works reliably with FireFox and Internet
        Explorer, correctly handling nonce timeouts etc.</para>

        <para>Now that we've reviewed the theory, let's see how to use it. To
        implement HTTP Digest Authentication, it is necessary to define
        <literal>DigestProcessingFilter</literal> in the fitler chain. The
        application context will need to define the
        <literal>DigestProcessingFilter</literal> and its required
        collaborators:</para>

        <para><programlisting>&lt;bean id="digestProcessingFilter" class="net.sf.acegisecurity.ui.digestauth.DigestProcessingFilter"&gt;
  &lt;property name="authenticationDao"&gt;&lt;ref local="jdbcDaoImpl"/&gt;&lt;/property&gt;
  &lt;property name="authenticationEntryPoint"&gt;&lt;ref local="digestProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
  &lt;property name="userCache"&gt;&lt;ref local="userCache"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="digestProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.digestauth.DigestProcessingFilterEntryPoint"&gt;
  &lt;property name="realmName"&gt;&lt;value&gt;Contacts Realm via Digest Authentication&lt;/value&gt;&lt;/property&gt;
  &lt;property name="key"&gt;&lt;value&gt;acegi&lt;/value&gt;&lt;/property&gt;
  &lt;property name="nonceValiditySeconds"&gt;&lt;value&gt;10&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>The configured <literal>AuthenticationDao</literal> is needed
        because <literal>DigestProcessingFilter</literal> must have direct
        access to the clear text password of a user. Digest Authentication
        will NOT work if you are using encoded passwords in your DAO. The DAO
        collaborator, along with the <literal>UserCache</literal>, are
        typically shared directly with a
        <literal>DaoAuthenticationProvider</literal>. The
        <literal>authenticationEntryPoint</literal> property must be
        <literal>DigestProcessingFilterEntryPoint</literal>, so that
        <literal>DigestProcessingFilter</literal> can obtain the correct
        <literal>realmName</literal> and <literal>key</literal> for digest
        calculations.</para>

        <para>Like <literal>BasicAuthenticationFilter</literal>, if
        authentication is successful an <literal>Authentication</literal>
        request token will be placed into the
        <literal>ContextHolder</literal>. If the authentication event was
        successful, or authentication was not attempted because the HTTP
        header did not contain a Digest Authentication request, the filter
        chain will continue as normal. The only time the filter chain will be
        interrupted is if authentication fails and the
        <literal>AuthenticationEntryPoint</literal> is called, as discussed in
        the previous paragraph.</para>

        <para>Digest Authentication's RFC offers a range of additional
        features to further increase security. For example, the nonce can be
        changed on every request. Despite this, the Acegi Security
        implementation was designed to minimise the complexity of the
        implementation (and the doubtless user agent incompatibilities that
        would emerge), and avoid needing to store server-side state. You are
        invited to review RFC 2617 if you wish to explore these features in
        more detail. As far as we are aware, the Acegi Security implementation
        does comply with the minimum standards of this RFC.</para>
      </sect2>

      <sect2 id="security-ui-anonymous">
        <title>Anonymous Authentication</title>

        <para>Particularly in the case of web request URI security, sometimes
        it is more convenient to assign configuration attributes against every
        possible secure object invocation. Put differently, sometimes it is
        nice to say <literal>ROLE_SOMETHING</literal> is required by default
        and only allow certain exceptions to this rule, such as for login,
        logout and home pages of an application. There are also other
        situations where anonymous authentication would be desired, such as
        when an auditing interceptor queries the
        <literal>ContextHolder</literal> to identify which principal was
        responsible for a given operation. Such classes can be authored with
        more robustness if they know the <literal>ContextHolder</literal>
        always contains an <literal>Authentication</literal> object, and never
        <literal>null</literal>.</para>

        <para>Acegi Security provides three classes that together provide an
        anoymous authentication feature.
        <literal>AnonymousAuthenticationToken</literal> is an implementation
        of <literal>Authentication</literal>, and stores the
        <literal>GrantedAuthority</literal>[]s which apply to the anonymous
        principal. There is a corresponding
        <literal>AnonymousAuthenticationProvider</literal>, which is chained
        into the <literal>ProviderManager</literal> so that
        <literal>AnonymousAuthenticationTokens</literal> are accepted.
        Finally, there is an AnonymousProcessingFilter, which is chained after
        the normal authentication mechanisms and automatically add an
        <literal>AnonymousAuthenticationToken</literal> to the
        <literal>ContextHolder</literal> if there is no existing
        <literal>Authentication</literal> held there. The definition of the
        filter and authentication provider appears as follows:</para>

        <para><programlisting>&lt;bean id="anonymousProcessingFilter" class="net.sf.acegisecurity.providers.anonymous.AnonymousProcessingFilter"&gt;
  &lt;property name="key"&gt;&lt;value&gt;foobar&lt;/value&gt;&lt;/property&gt;
  &lt;property name="userAttribute"&gt;&lt;value&gt;anonymousUser,ROLE_ANONYMOUS&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="anonymousAuthenticationProvider" class="net.sf.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider"&gt;
  &lt;property name="key"&gt;&lt;value&gt;foobar&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>The <literal>key</literal> is shared between the filter and
        authentication provider, so that tokens created by the former are
        accepted by the latter. The <literal>userAttribute</literal> is
        expressed in the form of
        <literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>.
        This is the same syntax as used after the equals sign for
        <literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal>
        property.</para>

        <para>As explained earlier, the benefit of anonymous authentication is
        that all URI patterns can have security applied to them. For
        example:</para>

        <para><programlisting>&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="accessDecisionManager"&gt;&lt;ref local="httpRequestAccessDecisionManager"/&gt;&lt;/property&gt;
  &lt;property name="objectDefinitionSource"&gt;
    &lt;value&gt;
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      PATTERN_TYPE_APACHE_ANT
      /index.jsp=ROLE_ANONYMOUS,ROLE_USER
      /hello.htm=ROLE_ANONYMOUS,ROLE_USER
      /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER
      /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER
      /**=ROLE_USER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting>Rounding out the anonymous authentication
        discussion is the <literal>AuthenticationTrustResolver</literal>
        interface, with its corresponding
        <literal>AuthenticationTrustResolverImpl</literal> implementation.
        This interface provides an
        <literal>isAnonymous(Authentication)</literal> method, which allows
        interested classes to take into account this special type of
        authentication status. The
        <literal>SecurityEnforcementFilter</literal> uses this interface in
        processing <literal>AccessDeniedException</literal>s. If an
        <literal>AccessDeniedException</literal> is thrown, and the
        authentication is of an anonymous type, instead of throwing a 403
        (forbidden) response, the filter will instead commence the
        <literal>AuthenticationEntryPoint</literal> so the principal can
        authenticate properly. This is a necessary distinction, otherwise
        principals would always be deemed "authenticated" and never be given
        an opportunity to login via form, basic, digest or some other normal
        authentication mechanism.</para>
      </sect2>

      <sect2 id="security-ui-remember-me">
        <title>Remember-Me Authentication</title>

        <para>Remember-me authentication refers to web sites being able to
        remember the identity of a principal between sessions. This is
        typically accomplished by sending a cookie to the browser, with the
        cookie being detected during future sessions and causing automated
        login to take place. Acegi Security provides the necessary hooks so
        that such operations can take place, along with providing a concrete
        implementation that uses hashing to preserve the security of
        cookie-based tokens.</para>

        <para>Remember-me authentication is not used with digest or basic
        authentication, given they are often not used with
        <literal>HttpSession</literal>s. Remember-me is used with
        <literal>AuthenticationProcessingFilter</literal>, and is implemented
        via hooks in the <literal>AbstractProcessingFilter</literal>
        superclass. The hooks will invoke a concrete
        <literal>RememberMeServices</literal> at the appropriate times. The
        interface looks like this:</para>

        <para><programlisting>public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
public void loginFail(HttpServletRequest request, HttpServletResponse response);
public void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication);</programlisting></para>

        <para>Please refer to JavaDocs for a fuller discussion on what the
        methods do, although note at this stage
        <literal>AbstractProcessingFilter</literal> only calls the
        <literal>loginFail()</literal> and <literal>loginSuccess()</literal>
        methods. The <literal>autoLogin()</literal> method is called by
        <literal>RememberMeProcessingFilter</literal> whenever the
        <literal>ContextHolder</literal> does not contain an
        <literal>Authentication</literal>. This interface therefore provides
        the underlaying remember-me implementation with sufficient
        notification of authentication-related events, and delegates to the
        implementation whenever a candidate web request might contain a cookie
        and wish to be remembered.</para>

        <para>This design allows any number of remember-me implementation
        strategies. In the interests of simplicity and avoiding the need for
        DAO implementations that specify write and create methods, Acegi
        Security's only concrete implementation,
        <literal>TokenBasedRememberMeServices</literal>, uses hashing to
        achieve a useful remember-me strategy. In essence a cookie is sent to
        the browser upon successful interactive authentication, with that
        cookie being composed as follows:</para>

        <para><programlisting>base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key))

username:         As identifiable to TokenBasedRememberMeServices.getAuthenticationDao()
password:         That matches the relevant UserDetails retrieved from TokenBasedRememberMeServices.getAuthenticationDao()
expirationTime:   The date and time when the remember-me token expires, expressed in milliseconds
key:              A private key to prevent modification of the remember-me token
</programlisting></para>

        <para>As such the remember-me token is valid only for the period
        specified, and provided that the username, password and key does not
        change. Notably, this has a potential security issue issue in that a
        captured remember-me token will be usable from any user agent until
        such time as the token expires. This is the same issue as with digest
        authentication. If a principal is aware a token has been captured,
        they can easily change their password and immediately invalidate all
        remember-me tokens on issue. However, if more significant security is
        needed a rolling token approach should be used (this would require a
        database) or remember-me services should simply not be used.</para>

        <para><literal>TokenBasedRememberMeServices</literal> generates a
        <literal>RememberMeAuthenticationToken</literal>, which is processed
        by <literal>RememberMeAuthenticationProvider</literal>. A
        <literal>key</literal> is shared between this authentication provider
        and the <literal>TokenBasedRememberMeServices</literal>. In addition,
        <literal>TokenBasedRememberMeServices</literal> requires an
        <literal>AuthenticationDao</literal> from which it can retrieve the
        username and password for signature comparison purposes, and generate
        the <literal>RememberMeAuthenticationToken</literal> to contain the
        correct <literal>GrantedAuthority</literal>[]s. Some sort of logout
        command should be provided by the application (typically via a JSP)
        that invalidates the cookie upon user request. See the Contacts Sample
        application's <literal>logout.jsp</literal> for an example.</para>

        <para>The beans required in an application context to enable
        remember-me services are as follows:</para>

        <para><programlisting>&lt;bean id="rememberMeProcessingFilter" class="net.sf.acegisecurity.ui.rememberme.RememberMeProcessingFilter"&gt;
  &lt;property name="rememberMeServices"&gt;&lt;ref local="rememberMeServices"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="rememberMeServices" class="net.sf.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"&gt;
  &lt;property name="authenticationDao"&gt;&lt;ref local="jdbcDaoImpl"/&gt;&lt;/property&gt;
  &lt;property name="key"&gt;&lt;value&gt;springRocks&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;
   
&lt;bean id="rememberMeAuthenticationProvider" class="net.sf.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"&gt;
  &lt;property name="key"&gt;&lt;value&gt;springRocks&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting>Don't forget to add your
        <literal>RememberMeServices</literal> implementation to your
        <literal>AuthenticationProcessingFilter.setRememberMeServices()</literal>
        property, include the <literal>RememberMeAuthenticationProvider</literal> in
        your <literal>AuthenticationManager.setProviders()</literal> list, and
        add a call to <literal>RememberMeProcessingFilter</literal> into your
        <literal>FilterChainProxy</literal> (typically immediately after your
        <literal>AuthenticationProcessingFilter</literal>).</para>
      </sect2>

      <sect2 id="security-ui-well-known">
        <title>Well-Known Locations</title>

        <para>Prior to release 0.8.0, Acegi Security referred to "well-known
        locations" in discussions about storing the
        <literal>Authentication</literal>. This approach did not explicitly
        separate the function of <literal>HttpSession</literal> storage of
        <literal>ContextHolder</literal> contents from the processing of
        authentication requests received through various protocols. In
        addition, the previous approach did not facilitate storage of
        non-<literal>Authentication</literal> objects between requests, which
        was limiting usefulness of the <literal>ContextHolder</literal> system
        to member of the community. For these reasons, the notion of
        well-known locations was abandoned, the
        <literal>HttpSessionContextIntegrationFilter</literal> was
        established, and the purpose of authentication processing mechanisms
        was explicitly defined and limited to interaction with the
        <literal>ContextHolder</literal> only. There is no need to refer to
        well-known locations any more and we hope this clearer separation of
        responsibilities enhances understanding of the project.</para>
      </sect2>
    </sect1>

    <sect1 id="security-container-adapters">
      <title>Container Adapters</title>

      <sect2 id="security-container-adapters-overview">
        <title>Overview</title>

        <para>Very early versions of the Acegi Security System for Spring
        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 the Acegi Security System for Spring
        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 the Acegi Security System for
        Spring (it should be noted that Acegi 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 the Acegi Security
        System for Spring 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>The Acegi Security System for Spring currently supports Jetty,
        Catalina (Tomcat), JBoss and Resin. Additional container adapters can
        easily be written.</para>
      </sect2>

      <sect2 id="security-container-adapters-adapter-provider">
        <title>Adapter Authentication Provider</title>

        <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>&lt;bean id="authByAdapterProvider" class="net.sf.acegisecurity.adapters.AuthByAdapterProvider"&gt;
  &lt;property name="key"&gt;&lt;value&gt;my_password&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</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>SecureContext</literal> in the
        <literal>ContextHolder</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>
      </sect2>

      <sect2 id="security-container-adapters-catalina">
        <title>Catalina (Tomcat) Installation</title>

        <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>&lt;Engine&gt;</literal> section contains only one
        active <literal>&lt;Realm&gt;</literal> entry. An example realm
        entry:</para>

        <para><programlisting>      &lt;Realm className="net.sf.acegisecurity.adapters.catalina.CatalinaAcegiUserRealm"
             appContextLocation="conf/acegisecurity.xml"
             key="my_password" /&gt;</programlisting></para>

        <para>Be sure to remove any other <literal>&lt;Realm&gt;</literal>
        entry from your <literal>&lt;Engine&gt;</literal> section.</para>

        <para>Copy <literal>acegisecurity.xml</literal> into
        <literal>$CATALINA_HOME/conf</literal>.</para>

        <para>Copy <literal>acegi-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>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
        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>
      </sect2>

      <sect2 id="security-container-adapters-jetty">
        <title>Jetty Installation</title>

        <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>&lt;Configure class&gt;</literal> section has a new
        addRealm call:</para>

        <para><programlisting>  &lt;Call name="addRealm"&gt;
    &lt;Arg&gt;
      &lt;New class="net.sf.acegisecurity.adapters.jetty.JettyAcegiUserRealm"&gt;
        &lt;Arg&gt;Spring Powered Realm&lt;/Arg&gt;
        &lt;Arg&gt;my_password&lt;/Arg&gt;
        &lt;Arg&gt;etc/acegisecurity.xml&lt;/Arg&gt;
      &lt;/New&gt;
    &lt;/Arg&gt;
  &lt;/Call&gt;</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>&lt;realm-name&gt;</literal> as your
        <literal>jetty.xml</literal> (in the example above, "Spring Powered
        Realm").</para>
      </sect2>

      <sect2 id="security-container-adapters-joss">
        <title>JBoss Installation</title>

        <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>&lt;Policy&gt;</literal> section:</para>

        <para><programlisting>    &lt;application-policy name = "SpringPoweredRealm"&gt;
       &lt;authentication&gt;
          &lt;login-module code = "net.sf.acegisecurity.adapters.jboss.JbossSpringLoginModule"
            flag = "required"&gt;
            &lt;module-option name = "appContextLocation"&gt;acegisecurity.xml&lt;/module-option&gt;
            &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
         &lt;/login-module&gt;
       &lt;/authentication&gt;
    &lt;/application-policy&gt;</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>    &lt;application-policy name = "SpringPoweredRealm"&gt;
       &lt;authentication&gt;
          &lt;login-module code = "net.sf.acegisecurity.adapters.jboss.JbossSpringLoginModule"
            flag = "required"&gt;
            &lt;module-option name = "singletonId"&gt;springRealm&lt;/module-option&gt;
            &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
            &lt;module-option name = "authenticationManager"&gt;authenticationManager&lt;/module-option&gt;
         &lt;/login-module&gt;
       &lt;/authentication&gt;
    &lt;/application-policy&gt;</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>&lt;beans&gt;
  &lt;bean id="springRealm" singleton="true" lazy-init="true" class="org.springframework.context.support.ClassPathXmlApplicationContext"&gt;
    &lt;constructor-arg&gt;
      &lt;list&gt;
        &lt;value&gt;acegisecurity.xml&lt;/value&gt;
      &lt;/list&gt;
    &lt;/constructor-arg&gt;
  &lt;/bean&gt;
&lt;/beans&gt;</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>&lt;security-domain&gt;</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>&lt;jboss-web&gt;
  &lt;security-domain&gt;java:/jaas/SpringPoweredRealm&lt;/security-domain&gt;
&lt;/jboss-web&gt;</programlisting></para>
      </sect2>

      <sect2 id="security-container-adapters-resin">
        <title>Resin Installation</title>

        <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>&lt;web-app&gt;
  &lt;authenticator&gt;
    &lt;type&gt;net.sf.acegisecurity.adapters.resin.ResinAcegiAuthenticator&lt;/type&gt;
    &lt;init&gt;
      &lt;app-context-location&gt;WEB-INF/resin-acegisecurity.xml&lt;/app-context-location&gt;
      &lt;key&gt;my_password&lt;/key&gt;
    &lt;/init&gt;
  &lt;/authenticator&gt;
&lt;/web-app&gt;</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>&lt;authenticator&gt;</literal> setting.</para>
      </sect2>
    </sect1>

    <sect1 id="security-cas">
      <title>Yale Central Authentication Service (CAS) Single Sign On</title>

      <sect2 id="security-cas-overview">
        <title>Overview</title>

        <para>Yale University produces an enterprise-wide single sign on
        system known as CAS. Unlike other initiatives, Yale's Central
        Authentication Service is open source, widely used, simple to
        understand, platform independent, and supports proxy capabilities. The
        Acegi Security System for Spring fully supports CAS, and provides an
        easy migration path from single-application deployments of Acegi
        Security through to multiple-application deployments secured by an
        enterprise-wide CAS server.</para>

        <para>You can learn more about CAS at
        <literal>http://www.yale.edu/tp/auth/</literal>. You will need to
        visit this URL to download the CAS Server files. Whilst the Acegi
        Security System for Spring includes two CAS libraries in the
        "-with-dependencies" ZIP file, you will still need the CAS Java Server
        Pages and <literal>web.xml</literal> to customise and deploy your CAS
        server.</para>
      </sect2>

      <sect2 id="security-cas-how-cas-works">
        <title>How CAS Works</title>

        <para>Whilst the CAS web site above contains two documents that detail
        the architecture of CAS, we present the general overview again here
        within the context of the Acegi Security System for Spring. The
        following refers to CAS 2.0, being the version of CAS that Acegi
        Security System for Spring supports.</para>

        <para>Somewhere in your enterprise you will need to setup a CAS
        server. The CAS server is simply a standard WAR file, so there isn't
        anything difficult about setting up your server. Inside the WAR file
        you will customise the login and other single sign on pages displayed
        to users. You will also need to specify in the web.xml a
        <literal>PasswordHandler</literal>. The
        <literal>PasswordHandler</literal> has a simple method that returns a
        boolean as to whether a given username and password is valid. Your
        <literal>PasswordHandler</literal> implementation will need to link
        into some type of backend authentication repository, such as an LDAP
        server or database.</para>

        <para>If you are already running an existing CAS server instance, you
        will have already established a <literal>PasswordHandler</literal>. If
        you do not already have a <literal>PasswordHandler</literal>, you
        might prefer to use the Acegi Security System for Spring
        <literal>CasPasswordHandler</literal> class. This class delegates
        through to the standard Acegi Security
        <literal>AuthenticationManager</literal>, enabling you to use a
        security configuration you might already have in place. You do not
        need to use the <literal>CasPasswordHandler</literal> class on your
        CAS server if you do not wish. The Acegi Security System for Spring
        will function as a CAS client successfully irrespective of the
        <literal>PasswordHandler</literal> you've chosen for your CAS
        server.</para>

        <para>Apart from the CAS server itself, the other key player is of
        course the secure web applications deployed throughout your
        enterprise. These web applications are known as "services". There are
        two types of services: standard services and proxy services. A proxy
        service is able to request resources from other services on behalf of
        the user. This will be explained more fully later.</para>

        <para>Services can be developed in a large variety of languages, due
        to CAS 2.0's very light XML-based protocol. The Yale CAS home page
        contains a clients archive which demonstrates CAS clients in Java,
        Active Server Pages, Perl, Python and others. Naturally, Java support
        is very strong given the CAS server is written in Java. You do not
        need to use any of CAS' client classes in applications secured by the
        Acegi Security System for Spring. This is handled transparently for
        you.</para>

        <para>The basic interaction between a web browser, CAS server and an
        Acegi Security for System Spring secured service is as follows:</para>

        <orderedlist>
          <listitem>
            <para>The web user is browsing the service's public pages. CAS or
            Acegi Security is not involved.</para>
          </listitem>

          <listitem>
            <para>The user eventually requests a page that is either secure or
            one of the beans it uses is secure. Acegi Security's
            <literal>SecurityEnforcementFilter</literal> will detect the
            <literal>AuthenticationException</literal>.</para>
          </listitem>

          <listitem>
            <para>Because the user's <literal>Authentication</literal> object
            (or lack thereof) caused an
            <literal>AuthenticationException</literal>, the
            <literal>SecurityEnforcementFilter</literal> will call the
            configured <literal>AuthenticationEntryPoint</literal>. If using
            CAS, this will be the
            <literal>CasProcessingFilterEntryPoint</literal> class.</para>
          </listitem>

          <listitem>
            <para>The <literal>CasProcessingFilterEntry</literal> point will
            redirect the user's browser to the CAS server. It will also
            indicate a <literal>service</literal> parameter, which is the
            callback URL for the Acegi Security service. For example, the URL
            to which the browser is redirected might be
            <literal>https://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_acegi_cas_security_check</literal>.</para>
          </listitem>

          <listitem>
            <para>After the user's browser redirects to CAS, they will be
            prompted for their username and password. If the user presents a
            session cookie which indicates they've previously logged on, they
            will not be prompted to login again (there is an exception to this
            procedure, which we'll cover later). CAS will use the
            <literal>PasswordHandler</literal> discussed above to decide
            whether the username and password is valid.</para>
          </listitem>

          <listitem>
            <para>Upon successful login, CAS will redirect the user's browser
            back to the original service. It will also include a
            <literal>ticket</literal> parameter, which is an opaque string
            representing the "service ticket". Continuing our earlier example,
            the URL the browser is redirected to might be
            <literal>https://server3.company.com/webapp/j_acegi_cas_security_check?ticket=ST-0-ER94xMJmn6pha35CQRoZ</literal>.</para>
          </listitem>

          <listitem>
            <para>Back in the service web application, the
            <literal>CasProcessingFilter</literal> is always listening for
            requests to <literal>/j_acegi_cas_security_check</literal> (this
            is configurable, but we'll use the defaults in this introduction).
            The processing filter will construct a
            <literal>UsernamePasswordAuthenticationToken</literal>
            representing the service ticket. The principal will be equal to
            <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>,
            whilst the credentials will be the service ticket opaque value.
            This authentication request will then be handed to the configured
            <literal>AuthenticationManager</literal>.</para>
          </listitem>

          <listitem>
            <para>The <literal>AuthenticationManager</literal> implementation
            will be the <literal>ProviderManager</literal>, which is in turn
            configured with the <literal>CasAuthenticationProvider</literal>.
            The <literal>CasAuthenticationProvider</literal> only responds to
            <literal>UsernamePasswordAuthenticationToken</literal>s containing
            the CAS-specific principal (such as
            <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>)
            and <literal>CasAuthenticationToken</literal>s (discussed
            later).</para>
          </listitem>

          <listitem>
            <para><literal>CasAuthenticationProvider</literal> will validate
            the service ticket using a <literal>TicketValidator</literal>
            implementation. Acegi Security includes one implementation, the
            <literal>CasProxyTicketValidator</literal>. This implementation a
            ticket validation class included in the CAS client library. The
            <literal>CasProxyTicketValidator</literal> makes a HTTPS request
            to the CAS server in order to validate the service ticket. The
            <literal>CasProxyTicketValidator</literal> may also include a
            proxy callback URL, which is included in this example:
            <literal>https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_acegi_cas_security_check&amp;ticket=ST-0-ER94xMJmn6pha35CQRoZ&amp;pgtUrl=https://server3.company.com/webapp/casProxy/receptor</literal>.</para>
          </listitem>

          <listitem>
            <para>Back on the CAS server, the proxy validation request will be
            received. If the presented service ticket matches the service URL
            the ticket was issued to, CAS will provide an affirmative response
            in XML indicating the username. If any proxy was involved in the
            authentication (discussed below), the list of proxies is also
            included in the XML response.</para>
          </listitem>

          <listitem>
            <para>[OPTIONAL] If the request to the CAS validation service
            included the proxy callback URL (in the <literal>pgtUrl</literal>
            parameter), CAS will include a <literal>pgtIou</literal> string in
            the XML response. This <literal>pgtIou</literal> represents a
            proxy-granting ticket IOU. The CAS server will then create its own
            HTTPS connection back to the <literal>pgtUrl</literal>. This is to
            mutually authenticate the CAS server and the claimed service URL.
            The HTTPS connection will be used to send a proxy granting ticket
            to the original web application. For example,
            <literal>https://server3.company.com/webapp/casProxy/receptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&amp;pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH</literal>.
            We suggest you use CAS' <literal>ProxyTicketReceptor</literal>
            servlet to receive these proxy-granting tickets, if they are
            required.</para>
          </listitem>

          <listitem>
            <para>The <literal>CasProxyTicketValidator</literal> will parse
            the XML received from the CAS server. It will return to the
            <literal>CasAuthenticationProvider</literal> a
            <literal>TicketResponse</literal>, which includes the username
            (mandatory), proxy list (if any were involved), and proxy-granting
            ticket IOU (if the proxy callback was requested).</para>
          </listitem>

          <listitem>
            <para>Next <literal>CasAuthenticationProvider</literal> will call
            a configured <literal>CasProxyDecider</literal>. The
            <literal>CasProxyDecider</literal> indicates whether the proxy
            list in the <literal>TicketResponse</literal> is acceptable to the
            service. Several implementations are provided with the Acegi
            Security System: <literal>RejectProxyTickets</literal>,
            <literal>AcceptAnyCasProxy</literal> and
            <literal>NamedCasProxyDecider</literal>. These names are largely
            self-explanatory, except <literal>NamedCasProxyDecider</literal>
            which allows a <literal>List</literal> of trusted proxies to be
            provided.</para>
          </listitem>

          <listitem>
            <para><literal>CasAuthenticationProvider</literal> will next
            request a <literal>CasAuthoritiesPopulator</literal> to advise the
            <literal>GrantedAuthority</literal> objects that apply to the user
            contained in the <literal>TicketResponse</literal>. Acegi Security
            includes a <literal>DaoCasAuthoritiesPopulator</literal> which
            simply uses the <literal>AuthenticationDao</literal>
            infrastructure to find the <literal>UserDetails</literal> and
            their associated <literal>GrantedAuthority</literal>s. Note that
            the password and enabled/disabled status of
            <literal>UserDetails</literal> returned by the
            <literal>AuthenticationDao</literal> are ignored, as the CAS
            server is responsible for authentication decisions.
            <literal>DaoCasAuthoritiesPopulator</literal> is only concerned
            with retrieving the <literal>GrantedAuthority</literal>s.</para>
          </listitem>

          <listitem>
            <para>If there were no problems,
            <literal>CasAuthenticationProvider</literal> constructs a
            <literal>CasAuthenticationToken</literal> including the details
            contained in the <literal>TicketResponse</literal> and the
            <literal>GrantedAuthority</literal>s. The
            <literal>CasAuthenticationToken</literal> contains the hash of a
            key, so that the <literal>CasAuthenticationProvider</literal>
            knows it created it.</para>
          </listitem>

          <listitem>
            <para>Control then returns to
            <literal>CasProcessingFilter</literal>, which places the created
            <literal>CasAuthenticationToken</literal> into the
            <literal>HttpSession</literal> attribute named
            <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.</para>
          </listitem>

          <listitem>
            <para>The user's browser is redirected to the original page that
            caused the <literal>AuthenticationException</literal>.</para>
          </listitem>

          <listitem>
            <para>As the <literal>Authentication</literal> object is now in
            the well-known location, it is handled like any other
            authentication approach. Usually the
            <literal>HttpSessionIntegrationFilter</literal> will be used to
            associate the <literal>Authentication</literal> object with the
            <literal>ContextHolder</literal> for the duration of each
            request.</para>
          </listitem>
        </orderedlist>

        <para>It's good that you're still here! It might sound involved, but
        you can relax as the Acegi Security System for Spring classes hide
        much of the complexity. Let's now look at how this is
        configured.</para>
      </sect2>

      <sect2 id="security-cas-install-server">
        <title>CAS Server Installation (Optional)</title>

        <para>As mentioned above, the Acegi Security System for Spring
        includes a <literal>PasswordHandler</literal> that bridges your
        existing <literal>AuthenticationManager</literal> into CAS. You do not
        need to use this <literal>PasswordHandler</literal> to use Acegi
        Security on the client side (any CAS
        <literal>PasswordHandler</literal> will do).</para>

        <para>To install, you will need to download and extract the CAS server
        archive. We used version 2.0.12. There will be a
        <literal>/web</literal> directory in the root of the deployment. Copy
        an <literal>applicationContext.xml</literal> containing your
        <literal>AuthenticationManager</literal> as well as the
        <literal>CasPasswordHandler</literal> into the
        <literal>/web/WEB-INF</literal> directory. A sample
        <literal>applicationContext.xml</literal> is included below:</para>

        <programlisting>&lt;bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl"&gt;
  &lt;property name="userMap"&gt;
    &lt;value&gt;
      marissa=koala,ROLES_IGNORED_BY_CAS
      dianne=emu,ROLES_IGNORED_BY_CAS
      scott=wombat,ROLES_IGNORED_BY_CAS
      peter=opal,disabled,ROLES_IGNORED_BY_CAS
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
  &lt;property name="providers"&gt;
    &lt;list&gt;
      &lt;ref bean="daoAuthenticationProvider"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="casPasswordHandler" class="net.sf.acegisecurity.adapters.cas.CasPasswordHandler"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting>

        <para>Note the granted authorities are ignored by CAS because it has
        no way of communicating the granted authorities to calling
        applications. CAS is only concerned with username and passwords (and
        the enabled/disabled status).</para>

        <para>Next you will need to edit the existing
        <literal>/web/WEB-INF/web.xml</literal> file. Add (or edit in the case
        of the <literal>authHandler</literal> property) the following
        lines:</para>

        <para><programlisting>&lt;context-param&gt;
  &lt;param-name&gt;edu.yale.its.tp.cas.authHandler&lt;/param-name&gt;
  &lt;param-value&gt;net.sf.acegisecurity.adapters.cas.CasPasswordHandlerProxy&lt;/param-value&gt;
&lt;/context-param&gt;

&lt;context-param&gt;
  &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
  &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
&lt;/context-param&gt;

&lt;listener&gt;
  &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
&lt;/listener&gt;</programlisting></para>

        <para>Copy the <literal>spring.jar</literal> and
        <literal>acegi-security.jar</literal> files into
        <literal>/web/WEB-INF/lib</literal>. Now use the <literal>ant
        dist</literal> task in the <literal>build.xml</literal> in the root of
        the directory structure. This will create
        <literal>/lib/cas.war</literal>, which is ready for deployment to your
        servlet container.</para>

        <para>Note CAS heavily relies on HTTPS. You can't even test the system
        without a HTTPS certificate. Whilst you should refer to your web
        container's documentation on setting up HTTPS, if you need some
        additional help or a test certificate you might like to check the
        <literal>samples/contacts/etc/ssl</literal> directory.</para>
      </sect2>

      <sect2 id="security-cas-install-client">
        <title>CAS Acegi Security System Client Installation</title>

        <para>The web application side of CAS is made easy due to the Acegi
        Security System for Spring. It is assumed you already know the basics
        of using the Acegi Security System for Spring, so these are not
        covered again below. Only the CAS-specific beans are mentioned.</para>

        <para>You will need to add a <literal>ServiceProperties</literal> bean
        to your application context. This represents your service:</para>

        <para><programlisting>&lt;bean id="serviceProperties" class="net.sf.acegisecurity.ui.cas.ServiceProperties"&gt;
  &lt;property name="service"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
  &lt;property name="sendRenew"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>The <literal>service</literal> must equal a URL that will be
        monitored by the <literal>CasProcessingFilter</literal>. The
        <literal>sendRenew</literal> defaults to false, but should be set to
        true if your application is particularly sensitive. What this
        parameter does is tell the CAS login service that a single sign on
        login is unacceptable. Instead, the user will need to re-enter their
        username and password in order to gain access to the service.</para>

        <para>The following beans should be configured to commence the CAS
        authentication process:</para>

        <para><programlisting>&lt;bean id="casProcessingFilter" class="net.sf.acegisecurity.ui.cas.CasProcessingFilter"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/casfailed.jsp&lt;/value&gt;&lt;/property&gt;
  &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
  &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
  &lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
  &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="casProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="casProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.cas.CasProcessingFilterEntryPoint"&gt;
  &lt;property name="loginUrl"&gt;&lt;value&gt;https://localhost:8443/cas/login&lt;/value&gt;&lt;/property&gt;
  &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>You will also need to add the
        <literal>CasProcessingFilter</literal> to web.xml:</para>

        <para><programlisting>&lt;filter&gt;
  &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;net.sf.acegisecurity.ui.cas.CasProcessingFilter&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>

        <para>The <literal>CasProcessingFilter</literal> has very similar
        properties to the <literal>AuthenticationProcessingFilter</literal>
        (used for form-based logins). Each property is
        self-explanatory.</para>

        <para>For CAS to operate, the
        <literal>SecurityEnforcementFilter</literal> must have its
        <literal>authenticationEntryPoint</literal> property set to the
        <literal>CasProcessingFilterEntryPoint</literal> bean.</para>

        <para>The <literal>CasProcessingFilterEntryPoint</literal> must refer
        to the <literal>ServiceProperties</literal> bean (discussed above),
        which provides the URL to the enterprise's CAS login server. This is
        where the user's browser will be redirected.</para>

        <para>Next you need to add an <literal>AuthenticationManager</literal>
        that uses <literal>CasAuthenticationProvider</literal> and its
        collaborators:</para>

        <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
  &lt;property name="providers"&gt;
    &lt;list&gt;
      &lt;ref bean="casAuthenticationProvider"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="casAuthenticationProvider" class="net.sf.acegisecurity.providers.cas.CasAuthenticationProvider"&gt;
  &lt;property name="casAuthoritiesPopulator"&gt;&lt;ref bean="casAuthoritiesPopulator"/&gt;&lt;/property&gt;
  &lt;property name="casProxyDecider"&gt;&lt;ref bean="casProxyDecider"/&gt;&lt;/property&gt;
  &lt;property name="ticketValidator"&gt;&lt;ref bean="casProxyTicketValidator"/&gt;&lt;/property&gt;
  &lt;property name="statelessTicketCache"&gt;&lt;ref bean="statelessTicketCache"/&gt;&lt;/property&gt;
  &lt;property name="key"&gt;&lt;value&gt;my_password_for_this_auth_provider_only&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="casProxyTicketValidator" class="net.sf.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator"&gt;
  &lt;property name="casValidate"&gt;&lt;value&gt;https://localhost:8443/cas/proxyValidate&lt;/value&gt;&lt;/property&gt;
  &lt;property name="proxyCallbackUrl"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/casProxy/receptor&lt;/value&gt;&lt;/property&gt;
  &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
  &lt;!-- &lt;property name="trustStore"&gt;&lt;value&gt;/some/path/to/your/lib/security/cacerts&lt;/value&gt;&lt;/property&gt; --&gt;
&lt;/bean&gt;

&lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"&gt;
  &lt;property name="configLocation"&gt;
    &lt;value&gt;classpath:/ehcache-failsafe.xml&lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;
    
&lt;bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
  &lt;property name="cacheManager"&gt;
    &lt;ref local="cacheManager"/&gt;
  &lt;/property&gt;
  &lt;property name="cacheName"&gt;
    &lt;value&gt;ticketCache&lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;
   
&lt;bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"&gt;
  &lt;property name="cache"&gt;&lt;ref local="ticketCacheBackend"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
  &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="casProxyDecider" class="net.sf.acegisecurity.providers.cas.proxy.RejectProxyTickets"/&gt;</programlisting></para>

        <para>The beans are all reasonable self-explanatory if you refer back
        to the "How CAS Works" section. Careful readers might notice one
        surprise: the <literal>statelessTicketCache</literal> property of the
        <literal>CasAuthenticationProvider</literal>. This is discussed in
        detail in the "Advanced CAS Usage" section.</para>

        <para>Note the <literal>CasProxyTicketValidator</literal> has a
        remarked out <literal>trustStore</literal> property. This property
        might be helpful if you experience HTTPS certificate issues. Also note
        the <literal>proxyCallbackUrl</literal> is set so the service can
        receive a proxy-granting ticket. As mentioned above, this is optional
        and unnecessary if you do not require proxy-granting tickets. If you
        do use this feature, you will need to configure a suitable servlet to
        receive the proxy-granting tickets. We suggest you use CAS'
        <literal>ProxyTicketReceptor</literal> by adding the following to your
        web application's <literal>web.xml</literal>:</para>

        <para><programlisting>&lt;servlet&gt;
  &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
  &lt;servlet-class&gt;edu.yale.its.tp.cas.proxy.ProxyTicketReceptor&lt;/servlet-class&gt;
&lt;/servlet&gt;

&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/casProxy/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</programlisting></para>

        <para>This completes the configuration of CAS. If you haven't made any
        mistakes, your web application should happily work within the
        framework of CAS single sign on. No other parts of the Acegi Security
        System for Spring need to be concerned about the fact CAS handled
        authentication.</para>

        <para>There is also a <literal>contacts-cas.war</literal> file in the
        sample applications directory. This sample application uses the above
        settings and can be deployed to see CAS in operation.</para>
      </sect2>

      <sect2 id="security-cas-advanced-usage">
        <title>Advanced CAS Usage</title>

        <para>The <literal>CasAuthenticationProvider</literal> distinguishes
        between stateful and stateless clients. A stateful client is
        considered any that originates via the
        <literal>CasProcessingFilter</literal>. A stateless client is any that
        presents an authentication request via the
        <literal>UsernamePasswordAuthenticationToken</literal> with a
        principal equal to
        <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>.</para>

        <para>Stateless clients are likely to be via remoting protocols such
        as Hessian and Burlap. The <literal>BasicProcessingFilter</literal> is
        still used in this case, but the remoting protocol client is expected
        to present a username equal to the static string above, and a password
        equal to a CAS service ticket. Clients should acquire a CAS service
        ticket directly from the CAS server.</para>

        <para>Because remoting protocols have no way of presenting themselves
        within the context of a <literal>HttpSession</literal>, it isn't
        possible to rely on the <literal>HttpSession</literal>'s
        <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>
        attribute to locate the <literal>CasAuthenticationToken</literal>.
        Furthermore, because the CAS server invalidates a service ticket after
        it has been validated by the <literal>TicketValidator</literal>,
        presenting the same service ticket on subsequent requests will not
        work. It is similarly very difficult to obtain a proxy-granting ticket
        for a remoting protocol client, as they are often deployed on client
        machines which rarely have HTTPS URLs that would be accessible to the
        CAS server.</para>

        <para>One obvious option is to not use CAS at all for remoting
        protocol clients. However, this would eliminate many of the desirable
        features of CAS.</para>

        <para>As a middle-ground, the
        <literal>CasAuthenticationProvider</literal> uses a
        <literal>StatelessTicketCache</literal>. This is used solely for
        requests with a principal equal to
        <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>. What
        happens is the <literal>CasAuthenticationProvider</literal> will store
        the resulting <literal>CasAuthenticationToken</literal> in the
        <literal>StatelessTicketCache</literal>, keyed on the service ticket.
        Accordingly, remoting protocol clients can present the same service
        ticket and the <literal>CasAuthenticationProvider</literal> will not
        need to contact the CAS server for validation (aside from the first
        request).</para>

        <para>The other aspect of advanced CAS usage involves creating proxy
        tickets from the proxy-granting ticket. As indicated above, we
        recommend you use CAS' <literal>ProxyTicketReceptor</literal> to
        receive these tickets. The <literal>ProxyTicketReceptor</literal>
        provides a static method that enables you to obtain a proxy ticket by
        presenting the proxy-granting IOU ticket. You can obtain the
        proxy-granting IOU ticket by calling
        <literal>CasAuthenticationToken.getProxyGrantingTicketIou()</literal>.</para>

        <para>It is hoped you find CAS integration easy and useful with the
        Acegi Security System for Spring classes. Welcome to enterprise-wide
        single sign on!</para>
      </sect2>
    </sect1>

    <sect1 id="security-x509">
      <title>X509 Authentication</title>

      <sect2 id="security-x509-overview">
        <title>Overview</title>

        <para>The most common use of X509 certificate authentication is in
        verifying the identity of a server when using SSL, most commonly when
        using HTTPS from a browser. The browser will automatically check that
        the certificate presented by a server has been issued (ie digitally
        signed) by one of a list of trusted certificate authorities which it
        maintains.</para>

        <para>You can also use SSL with <quote>mutual authentication</quote>;
        the server will then request a valid certificate from the client as
        part of the SSL handshake. The server will authenticate the client by
        checking that it's certificate is signed by an acceptable authority.
        If a valid certificate has been provided, it can be obtained through
        the servlet API in an application. The Acegi Security X509 module
        extracts the certificate using a filter and passes it to the
        configured X509 authentication provider to allow any additional
        application-specific checks to be applied. It also maps the
        certificate to an application user and loads that user's set of
        granted authorities for use with the standard Acegi Security
        infrastructure.</para>

        <para>You should be familiar with using certificates and setting up
        client authentication for your servlet container before attempting to
        use it with Acegi Security. Most of the work is in creating and
        installing suitable certificates and keys. For example, if you're
        using Tomcat then read the instructions here <ulink
        url="http://jakarta.apache.org/tomcat/tomcat-5.0-doc/ssl-howto.html"></ulink>.
        It's important that you get this working before trying it out with
        Acegi Security.</para>
      </sect2>

      <sect2 id="security-x509-details">
        <title>X509 with Acegi Security</title>

        <para>With X509 authentication, there is no explicit login procedure
        so the implementation is relatively simple; there is no need to
        redirect requests in order to interact with the user. As a result,
        some of the classes behave slightly differently from their equivalents
        in other packages. For example, the default <quote>entry point</quote>
        class, which is normally responsible for starting the authentication
        process, is only invoked if the certificate is rejected and it always
        returns an error to the user. With a suitable bean configuration, the
        normal sequence of events is as follows <orderedlist>
             

            <listitem>
              <para>The <classname>X509ProcessingFilter</classname> extracts
              the certificate from the request and uses it as the credentials
              for an authentication request. The generated authentication
              request is an <classname>X509AuthenticationToken</classname>.
              The request is passed to the authentication manager.</para>
            </listitem>

             

            <listitem>
              <para>The <classname>X509AuthenticationProvider</classname>
              receives the token. Its main concern is to obtain the user
              information (in particular the user's granted authorities) that
              matches the certificate. It delegates this responsibility to an
              <interfacename>X509AuthoritiesPopulator</interfacename>.</para>
            </listitem>

             . 

            <listitem>
              <para>The populator's single method,
              <methodname>getUserDetails(X509Certificate
              userCertificate)</methodname> is invoked. Implementations should
              return a <classname>UserDetails</classname> instance containing
              the array of <classname>GrantedAuthority</classname> objects for
              the user. This method can also choose to reject the certificate
              (for example if it doesn't contain a matching user name). In
              such cases it should throw a
              <exceptionname>BadCredentialsException</exceptionname>. A
              DAO-based implementation,
              <classname>DaoX509AuthoritiesPopulator</classname>, is provided
              which extracts the user's name from the subject <quote>common
              name</quote> (CN) in the certificate. It also allows you to set
              your own regular expression to match a different part of the
              subject's distinguished name. An
              <classname>AuthenticationDao</classname> is used to load the
              user information.<!-- TODO: Give email matching as an example --></para>
            </listitem>

             

            <listitem>
              <para>If everything has gone smoothly then there should be a
              valid <classname>Authentication</classname> object in the secure
              context and the invocation will procede as normal. If no
              certificate was found, or the certificate was rejected, then the
              <classname>SecurityEnforcementFilter</classname> will invoke the
              <classname>X509ProcessingFilterEntryPoint</classname> which
              returns a 403 error (forbidden) to the user.</para>
            </listitem>

             
          </orderedlist></para>
      </sect2>

      <sect2 id="security-x509-config">
        <title>Configuring the X509 Provider</title>

        <para>There is a version of the <link
        linkend="security-sample">contacts sample application</link> which
        uses X509. Copy the beans and filter setup from this as a starting
        point for configuring your own application. A set of example
        certificates is also included which you can use to configure your
        server. These are <itemizedlist>
            <listitem>
              <para><filename>marissa.p12</filename>: A PKCS12 format file
              containing the client key and certificate. These should be
              installed in your browser. It maps to the user
              <quote>marissa</quote> in the application.</para>
            </listitem>

            <listitem>
              <para><filename>server.p12</filename>: The server certificate
              and key for HTTPS connections.</para>
            </listitem>

            <listitem>
              <para><filename>ca.jks</filename>: A Java keystore containing
              the certificate for the authority which issued marissa's
              certificate. This will be used by the container to validate
              client certificates.</para>
            </listitem>
          </itemizedlist> For JBoss 3.2.7 (with Tomcat 5.0), the SSL
        configuration in the <filename>server.xml</filename> file looks like
        this <programlisting>&lt;!-- SSL/TLS Connector configuration --&gt;
&lt;Connector port="8443" address="${jboss.bind.address}"
  maxThreads="100" minSpareThreads="5" maxSpareThreads="15"
  scheme="https" secure="true"
  sslProtocol = "TLS"
  clientAuth="true" keystoreFile="${jboss.server.home.dir}/conf/server.p12"
  keystoreType="PKCS12" keystorePass="password"
  truststoreFile="${jboss.server.home.dir}/conf/ca.jks"
  truststoreType="JKS" truststorePass="password"
/&gt;</programlisting><parameter>clientAuth</parameter> can also be set to
        <parameter>want</parameter> if you still want SSL connections to
        succeed even if the client doesn't provide a certificate. Obviously
        these clients won't be able to access any objects secured by Acegi
        Security (unless you use a non-X509 authentication mechanism, such as
        BASIC authentication, to authenticate the user).</para>
      </sect2>
    </sect1>

    <sect1 id="security-channels">
      <title>Channel Security</title>

      <sect2 id="security-channels-overview">
        <title>Overview</title>

        <para>In addition to coordinating the authentication and authorization
        requirements of your application, the Acegi Security System for Spring
        is also able to ensure unauthenticated web requests have certain
        properties. These properties may include being of a particular
        transport type, having a particular <literal>HttpSession</literal>
        attribute set and so on. The most common requirement is for your web
        requests to be received using a particular transport protocol, such as
        HTTPS.</para>

        <para>An important issue in considering transport security is that of
        session hijacking. Your web container manages a
        <literal>HttpSession</literal> by reference to a
        <literal>jsessionid</literal> that is sent to user agents either via a
        cookie or URL rewriting. If the <literal>jsessionid</literal> is ever
        sent over HTTP, there is a possibility that session identifier can be
        intercepted and used to impersonate the user after they complete the
        authentication process. This is because most web containers maintain
        the same session identifier for a given user, even after they switch
        from HTTP to HTTPS pages.</para>

        <para>If session hijacking is considered too significant a risk for
        your particular application, the only option is to use HTTPS for every
        request. This means the <literal>jsessionid</literal> is never sent
        across an insecure channel. You will need to ensure your
        <literal>web.xml</literal>-defined
        <literal>&lt;welcome-file&gt;</literal> points to a HTTPS location,
        and the application never directs the user to a HTTP location. The
        Acegi Security System for Spring provides a solution to assist with
        the latter.</para>
      </sect2>

      <sect2 id="security-channels-installation">
        <title>Configuration</title>

        <para>To utilise Acegi Security's channel security services, add the
        following lines to <literal>web.xml</literal>:</para>

        <para><programlisting>&lt;filter&gt;
  &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;net.sf.acegisecurity.securechannel.ChannelProcessingFilter&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
  &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</programlisting></para>

        <para>As usual when running <literal>FilterToBeanProxy</literal>, you
        will also need to configure the filter in your application
        context:</para>

        <para><programlisting>&lt;bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter"&gt;
  &lt;property name="channelDecisionManager"&gt;&lt;ref bean="channelDecisionManager"/&gt;&lt;/property&gt;
  &lt;property name="filterInvocationDefinitionSource"&gt;
    &lt;value&gt;
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      \A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
      \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
      \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL	
      \A.*\Z=REQUIRES_INSECURE_CHANNEL
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"&gt;
  &lt;property name="channelProcessors"&gt;
    &lt;list&gt;
      &lt;ref bean="secureChannelProcessor"/&gt;
      &lt;ref bean="insecureChannelProcessor"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/&gt;
&lt;bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/&gt;</programlisting></para>

        <para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
        style paths are also supported by the
        <literal>ChannelProcessingFilter</literal>.</para>

        <para>The <literal>ChannelProcessingFilter</literal> operates by
        filtering all web requests and determining the configuration
        attributes that apply. It then delegates to the
        <literal>ChannelDecisionManager</literal>. The default implementation,
        <literal>ChannelDecisionManagerImpl</literal>, should suffice in most
        cases. It simply delegates through the list of configured
        <literal>ChannelProcessor</literal> instances. A
        <literal>ChannelProcessor</literal> will review the request, and if it
        is unhappy with the request (eg it was received across the incorrect
        transport protocol), it will perform a redirect, throw an exception or
        take whatever other action is appropriate.</para>

        <para>Included with the Acegi Security System for Spring are two
        concrete <literal>ChannelProcessor</literal> implementations:
        <literal>SecureChannelProcessor</literal> ensures requests with a
        configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
        are received over HTTPS, whilst
        <literal>InsecureChannelProcessor</literal> ensures requests with a
        configuration attribute of
        <literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
        Both implementations delegate to a
        <literal>ChannelEntryPoint</literal> if the required transport
        protocol is not used. The two <literal>ChannelEntryPoint</literal>
        implementations included with Acegi Security simply redirect the
        request to HTTP and HTTPS as appropriate. Appropriate defaults are
        assigned to the <literal>ChannelProcessor</literal> implementations
        for the configuration attribute keywords they respond to and the
        <literal>ChannelEntryPoint</literal> they delegate to, although you
        have the ability to override these using the application
        context.</para>

        <para>Note that the redirections are absolute (eg
        http://www.company.com:8080/app/page), not relative (eg /app/page).
        During testing it was discovered that Internet Explorer 6 Service Pack
        1 has a bug whereby it does not respond correctly to a redirection
        instruction which also changes the port to use. Accordingly, absolute
        URLs are used in conjunction with bug detection logic in the
        <literal>PortResolverImpl</literal> that is wired up by default to
        many Acegi Security beans. Please refer to the JavaDocs for
        <literal>PortResolverImpl</literal> for further details.</para>
      </sect2>

      <sect2 id="security-channels-usage">
        <title>Usage</title>

        <para>Once configured, using the channel security filter is very easy.
        Simply request pages without regard to the protocol (ie HTTP or HTTPS)
        or port (eg 80, 8080, 443, 8443 etc). Obviously you'll still need a
        way of making the initial request (probably via the
        <literal>web.xml</literal> <literal>&lt;welcome-file&gt;</literal> or
        a well-known home page URL), but once this is done the filter will
        perform redirects as defined by your application context.</para>

        <para>You can also add your own <literal>ChannelProcessor</literal>
        implementations to the <literal>ChannelDecisionManagerImpl</literal>.
        For example, you might set a <literal>HttpSession</literal> attribute
        when a human user is detected via a "enter the contents of this
        graphic" procedure. Your <literal>ChannelProcessor</literal> would
        respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration
        attributes and redirect to an appropriate entry point to start the
        human user validation process if the <literal>HttpSession</literal>
        attribute is not currently set.</para>

        <para>To decide whether a security check belongs in a
        <literal>ChannelProcessor</literal> or an
        <literal>AccessDecisionVoter</literal>, remember that the former is
        designed to handle unauthenticated requests, whilst the latter is
        designed to handle authenticated requests. The latter therefore has
        access to the granted authorities of the authenticated principal. In
        addition, problems detected by a <literal>ChannelProcessor</literal>
        will generally cause a HTTP/HTTPS redirection so its requirements can
        be met, whilst problems detected by an
        <literal>AccessDecisionVoter</literal> will ultimately result in an
        <literal>AccessDeniedException</literal> (depending on the governing
        <literal>AccessDecisionManager</literal>).</para>
      </sect2>
    </sect1>

    <sect1 id="acls">
      <title>Instance-Based Access Control List (ACL) Security</title>

      <sect2 id="acls-overview">
        <title>Overview</title>

        <para>Complex applications often will find the need to define access
        permissions not simply at a web request or method invocation level.
        Instead, security decisions need to comprise both who
        (<literal>Authentication</literal>), where
        (<literal>MethodInvocation</literal>) and what
        (<literal>SomeDomainObject</literal>). In other words, authorization
        decisions also need to consider the actual domain object instance
        subject of a method invocation.</para>

        <para>Imagine you're designing an application for a pet clinic. There
        will be two main groups of users of your Spring-based application:
        staff of the pet clinic, as well as the pet clinic's customers. The
        staff will have access to all of the data, whilst your customers will
        only be able to see their own customer records. To make it a little
        more interesting, your customers can allow other users to see their
        customer records, such as their "puppy preschool "mentor or president
        of their local "Pony Club". Using Acegi Security System for Spring as
        the foundation, you have several approaches that can be
        used:<orderedlist>
            <listitem>
              <para>Write your business methods to enforce the security. You
              could consult a collection within the
              <literal>Customer</literal> domain object instance to determine
              which users have access. By using the
              <literal>ContextHolder.getContext()</literal> and casting it to
              <literal>SecureContext</literal>, you'll be able to access the
              <literal>Authentication</literal> object.</para>
            </listitem>

            <listitem>
              <para>Write an <literal>AccessDecisionVoter</literal> to enforce
              the security from the <literal>GrantedAuthority[]</literal>s
              stored in the <literal>Authentication</literal> object. This
              would mean your <literal>AuthenticationManager</literal> would
              need to populate the <literal>Authentication</literal> with
              custom <literal>GrantedAuthority</literal>[]s representing each
              of the <literal>Customer</literal> domain object instances the
              principal has access to.</para>
            </listitem>

            <listitem>
              <para>Write an <literal>AccessDecisionVoter</literal> to enforce
              the security and open the target <literal>Customer</literal>
              domain object directly. This would mean your voter needs access
              to a DAO that allows it to retrieve the
              <literal>Customer</literal> object. It would then access the
              <literal>Customer</literal> object's collection of approved
              users and make the appropriate decision.</para>
            </listitem>
          </orderedlist></para>

        <para>Each one of these approaches is perfectly legitimate. However,
        the first couples your authorization checking to your business code.
        The main problems with this include the enhanced difficulty of unit
        testing and the fact it would be more difficult to reuse the
        <literal>Customer</literal> authorization logic elsewhere. Obtaining
        the <literal>GrantedAuthority[]</literal>s from the
        <literal>Authentication</literal> object is also fine, but will not
        scale to large numbers of <literal>Customer</literal>s. If a user
        might be able to access 5,000 <literal>Customer</literal>s (unlikely
        in this case, but imagine if it were a popular vet for a large Pony
        Club!) the amount of memory consumed and time required to construct
        the <literal>Authentication</literal> object would be undesirable. The
        final method, opening the <literal>Customer</literal> directly from
        external code, is probably the best of the three. It achieves
        separation of concerns, and doesn't misuse memory or CPU cycles, but
        it is still inefficient in that both the
        <literal>AccessDecisionVoter</literal> and the eventual business
        method itself will perform a call to the DAO responsible for
        retrieving the <literal>Customer</literal> object. Two accesses per
        method invocation is clearly undesirable. In addition, with every
        approach listed you'll need to write your own access control list
        (ACL) persistence and business logic from scratch.</para>

        <para>Fortunately, there is another alternative, which we'll talk
        about below.</para>
      </sect2>

      <sect2 id="acls-acl-package">
        <title>The net.sf.acegisecurity.acl Package</title>

        <para>The <literal>net.sf.acegisecurity.acl</literal> package is very
        simple, comprising only a handful of interfaces and a single class, as
        shown in Figure 6. It provides the basic foundation for access control
        list (ACL) lookups.</para>

        <para><mediaobject>
            <imageobject role="html">
              <imagedata align="center" fileref="images/ACLSecurity.gif"
                         format="GIF" />
            </imageobject>

            <caption>
              <para>Figure 6: Access Control List Manager</para>
            </caption>
          </mediaobject></para>

        <para>The central interface is <literal>AclManager</literal>, which is
        defined by two methods:</para>

        <para><programlisting>public AclEntry[] getAcls(java.lang.Object domainInstance);
public AclEntry[] getAcls(java.lang.Object domainInstance, Authentication authentication);</programlisting></para>

        <para><literal>AclManager</literal> is intended to be used as a
        collaborator against your business objects, or, more desirably,
        <literal>AccessDecisionVoter</literal>s. This means you use Spring's
        normal <literal>ApplicationContext</literal> features to wire up your
        <literal>AccessDecisionVoter</literal> (or business method) with an
        <literal>AclManager</literal>. Consideration was given to placing the
        ACL information in the <literal>ContextHolder</literal>, but it was
        felt this would be inefficient both in terms of memory usage as well
        as the time spent loading potentially unused ACL information. The
        trade-off of needing to wire up a collaborator for those objects
        requiring ACL information is rather minor, particularly in a
        Spring-managed application.</para>

        <para>The first method of the <literal>AclManager</literal> will
        return all ACLs applying to the domain object instance passed to it.
        The second method does the same, but only returns those ACLs which
        apply to the passed <literal>Authentication</literal> object.</para>

        <para>The <literal>AclEntry</literal> interface returned by
        <literal>AclManager</literal> is merely a marker interface. You will
        need to provide an implementation that reflects that ACL permissions
        for your application.</para>

        <para>Rounding out the <literal>net.sf.acegisecurity.acl</literal>
        package is an <literal>AclProviderManager</literal> class, with a
        corresponding <literal>AclProvider</literal> interface.
        <literal>AclProviderManager</literal> is a concrete implementation of
        <literal>AclManager</literal>, which iterates through registered
        <literal>AclProvider</literal>s. The first
        <literal>AclProvider</literal> that indicates it can authoritatively
        provide ACL information for the presented domain object instance will
        be used. This is very similar to the
        <literal>AuthenticationProvider</literal> interface used for
        authentication.</para>

        <para>With this background, let's now look at a usable ACL
        implementation.</para>
      </sect2>

      <sect2 id="acls-masking">
        <title>Integer Masked ACLs</title>

        <para>Acegi Security System for Spring includes a production-quality
        ACL provider implementation, which is shown in Figure 7.</para>

        <para><mediaobject>
            <imageobject role="html">
              <imagedata align="center" fileref="images/BasicAclProvider.gif"
                         format="GIF" />
            </imageobject>

            <caption>
              <para>Figure 7: Basic ACL Manager</para>
            </caption>
          </mediaobject></para>

        <para>The implementation is based on integer masking, which is
        commonly used for ACL permissions given its flexibility and speed.
        Anyone who has used Unix's <literal>chmod</literal> command will know
        all about this type of permission masking (eg <literal>chmod
        777</literal>). You'll find the classes and interfaces for the integer
        masking ACL package under
        <literal>net.sf.acegisecurity.acl.basic</literal>.</para>

        <para>Extending the <literal>AclEntry</literal> interface is a
        <literal>BasicAclEntry</literal> interface, with the main methods
        shown below:</para>

        <para><programlisting>public AclObjectIdentity getAclObjectIdentity();
public AclObjectIdentity getAclObjectParentIdentity();
public int getMask();
public java.lang.Object getRecipient();</programlisting></para>

        <para>As shown, each <literal>BasicAclEntry</literal> has four main
        properties. The <literal>mask</literal> is the integer that represents
        the permissions granted to the <literal>recipient</literal>. The
        <literal>aclObjectIdentity</literal> is able to identify the domain
        object instance for which the ACL applies, and the
        <literal>aclObjectParentIdentity</literal> optionally specifies the
        parent of the domain object instance. Multiple
        <literal>BasicAclEntry</literal>s usually exist against a single
        domain object instance, and as suggested by the parent identity
        property, permissions granted higher in the object hierarchy will
        trickle down and be inherited (unless blocked by integer zero).</para>

        <para><literal>BasicAclEntry</literal> implementations typically
        provide convenience methods, such as
        <literal>isReadAllowed()</literal>, to avoid application classes
        needing to perform bit masking themselves. The
        <literal>SimpleAclEntry</literal> and
        <literal>AbstractBasicAclEntry</literal> demonstrate and provide much
        of this bit masking logic.</para>

        <para>The <literal>AclObjectIdentity</literal> itself is merely a
        marker interface, so you need to provide implementations for your
        domain objects. However, the package does include a
        <literal>NamedEntityObjectIdentity</literal> implementation which will
        suit many needs. The <literal>NamedEntityObjectIdentity</literal>
        identifies a given domain object instance by the classname of the
        instance and the identity of the instance. A
        <literal>NamedEntityObjectIdentity</literal> can be constructed
        manually (by calling the constructor and providing the classname and
        identity <literal>String</literal>s), or by passing in any domain
        object that contains a <literal>getId()</literal> method.</para>

        <para>The actual <literal>AclProvider</literal> implementation is
        named <literal>BasicAclProvider</literal>. It has adopted a similar
        design to that used by the authentication-related
        <literal>DaoAuthenticationProvder</literal>. Specifically, you define
        a <literal>BasicAclDao</literal> against the provider, so different
        ACL repository types can be accessed in a pluggable manner. The
        <literal>BasicAclProvider</literal> also supports pluggable cache
        providers (with Acegi Security System for Spring including an
        implementation that fronts EH-CACHE).</para>

        <para>The <literal>BasicAclDao</literal> interface is very simple to
        implement:</para>

        <para><programlisting>public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);</programlisting></para>

        <para>A <literal>BasicAclDao</literal> implementation needs to
        understand the presented <literal>AclObjectIdentity</literal> and how
        it maps to a storage repository, find the relevant records, and create
        appropriate <literal>BasicAclEntry</literal> objects and return
        them.</para>

        <para>Acegi Security includes a single <literal>BasicAclDao</literal>
        implementation called <literal>JdbcDaoImpl</literal>. As implied by
        the name, <literal>JdbcDaoImpl</literal> accesses ACL information from
        a JDBC database. There is also an extended version of this DAO,
        <literal>JdbcExtendedDaoImpl</literal>, which provides CRUD operations
        on the JDBC database, although we won't discuss these features here.
        The default database schema and some sample data will aid in
        understanding its function:</para>

        <para><programlisting>CREATE TABLE acl_object_identity (
     id IDENTITY NOT NULL,
     object_identity VARCHAR_IGNORECASE(250) NOT NULL,
     parent_object INTEGER,
     acl_class VARCHAR_IGNORECASE(250) NOT NULL,
     CONSTRAINT unique_object_identity UNIQUE(object_identity),
     FOREIGN KEY (parent_object) REFERENCES acl_object_identity(id)
);

CREATE TABLE acl_permission (
     id IDENTITY NOT NULL,
     acl_object_identity INTEGER NOT NULL,
     recipient VARCHAR_IGNORECASE(100) NOT NULL,
     mask INTEGER NOT NULL,
     CONSTRAINT unique_recipient UNIQUE(acl_object_identity, recipient),
     FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id)
);

INSERT INTO acl_object_identity VALUES (1, 'corp.DomainObject:1', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (2, 'corp.DomainObject:2', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (3, 'corp.DomainObject:3', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (4, 'corp.DomainObject:4', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (5, 'corp.DomainObject:5', 3, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (6, 'corp.DomainObject:6', 3, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');

INSERT INTO acl_permission VALUES (null, 1, 'ROLE_SUPERVISOR', 1);
INSERT INTO acl_permission VALUES (null, 2, 'ROLE_SUPERVISOR', 0);
INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);
INSERT INTO acl_permission VALUES (null, 3, 'scott', 14);
INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>

        <para>As can be seen, database-specific constraints are used
        extensively to ensure the integrity of the ACL information. If you
        need to use a different database (Hypersonic SQL statements are shown
        above), you should try to implement equivalent constraints.</para>

        <para>The <literal>JdbcDaoImpl</literal> will only respond to requests
        for <literal>NamedEntityObjectIdentity</literal>s. It converts such
        identities into a single <literal>String</literal>, comprising
        the<literal> NamedEntityObjectIdentity.getClassname()</literal> +
        <literal>":"</literal> +
        <literal>NamedEntityObjectIdentity.getId()</literal>. This yields the
        type of <literal>object_identity</literal> values shown above. As
        indicated by the sample data, each database row corresponds to a
        single <literal>BasicAclEntry</literal>. As stated earlier and
        demonstrated by <literal>corp.DomainObject:2</literal> in the above
        sample data, each domain object instance will often have multiple
        <literal>BasicAclEntry</literal>[]s.</para>

        <para>As <literal>JdbcDaoImpl</literal> is required to return concrete
        <literal>BasicAclEntry</literal> classes, it needs to know which
        <literal>BasicAclEntry</literal> implementation it is to create and
        populate. This is the role of the <literal>acl_class</literal> column.
        <literal>JdbcDaoImpl</literal> will create the indicated class and set
        its <literal>mask</literal>, <literal>recipient</literal>,
        <literal>aclObjectIdentity</literal> and
        <literal>aclObjectParentIdentity</literal> properties.</para>

        <para>As you can probably tell from the sample data, the
        <literal>parent_object_identity</literal> value can either be null or
        in the same format as the <literal>object_identity</literal>. If
        non-null, <literal>JdbcDaoImpl</literal> will create a
        <literal>NamedEntityObjectIdentity</literal> to place inside the
        returned <literal>BasicAclEntry</literal> class.</para>

        <para>Returning to the <literal>BasicAclProvider</literal>, before it
        can poll the <literal>BasicAclDao</literal> implementation it needs to
        convert the domain object instance it was passed into an
        <literal>AclObjectIdentity</literal>.
        <literal>BasicAclProvider</literal> has a <literal>protected
        AclObjectIdentity obtainIdentity(Object domainInstance)</literal>
        method that is responsible for this. As a protected method, it enables
        subclasses to easily override. The normal implementation checks
        whether the passed domain object instance implements the
        <literal>AclObjectIdentityAware</literal> interface, which is merely a
        getter for an <literal>AclObjectIdentity</literal>. If the domain
        object does implement this interface, that is the identity returned.
        If the domain object does not implement this interface, the method
        will attempt to create an <literal>AclObjectIdentity</literal> by
        passing the domain object instance to the constructor of a class
        defined by the
        <literal>BasicAclProvider.getDefaultAclObjectIdentity()</literal>
        method. By default the defined class is
        <literal>NamedEntityObjectIdentity</literal>, which was described in
        more detail above. Therefore, you will need to either (i) provide a
        <literal>getId()</literal> method on your domain objects, (ii)
        implement <literal>AclObjectIdentityAware</literal> on your domain
        objects, (iii) provide an alternative
        <literal>AclObjectIdentity</literal> implementation that will accept
        your domain object in its constructor, or (iv) override the
        <literal>obtainIdentity(Object)</literal> method.</para>

        <para>Once the <literal>AclObjectIdentity</literal> of the domain
        object instance is determined, the <literal>BasicAclProvider</literal>
        will poll the DAO to obtain its <literal>BasicAclEntry</literal>[]s.
        If any of the entries returned by the DAO indicate there is a parent,
        that parent will be polled, and the process will repeat until there is
        no further parent. The permissions assigned to a
        <literal>recipient</literal> closest to the domain object instance
        will always take priority and override any inherited permissions. From
        the sample data above, the following inherited permissions would
        apply:</para>

        <para><programlisting>--- Mask integer 0  = no permissions
--- Mask integer 1  = administer
--- Mask integer 2  = read
--- Mask integer 6  = read and write permissions
--- Mask integer 14 = read and write and create permissions

---------------------------------------------------------------------
--- *** INHERITED RIGHTS FOR DIFFERENT INSTANCES AND RECIPIENTS ***
--- INSTANCE  RECIPIENT         PERMISSION(S) (COMMENT #INSTANCE)
---------------------------------------------------------------------
---    1      ROLE_SUPERVISOR   Administer
---    2      ROLE_SUPERVISOR   None (overrides parent #1)
---           marissa           Read
---    3      ROLE_SUPERVISOR   Administer (from parent #1)
---           scott             Read, Write, Create
---    4      ROLE_SUPERVISOR   Administer (from parent #1)
---    5      ROLE_SUPERVISOR   Administer (from parent #3)
---           scott             Read, Write, Create (from parent #3)
---    6      ROLE_SUPERVISOR   Administer (from parent #3)
---           scott             Administer (overrides parent #3)</programlisting></para>

        <para>So the above explains how a domain object instance has its
        <literal>AclObjectIdentity</literal> discovered, and the
        <literal>BasicAclDao</literal> will be polled successively until an
        array of inherited permissions is constructed for the domain object
        instance. The final step is to determine the
        <literal>BasicAclEntry</literal>[]s that are actually applicable to a
        given <literal>Authentication</literal> object.</para>

        <para>As you would recall, the <literal>AclManager</literal> (and all
        delegates, up to and including <literal>BasicAclProvider</literal>)
        provides a method which returns only those
        <literal>BasicAclEntry</literal>[]s applying to a passed
        <literal>Authentication</literal> object.
        <literal>BasicAclProvider</literal> delivers this functionality by
        delegating the filtering operation to an
        <literal>EffectiveAclsResolver</literal> implementation. The default
        implementation,
        <literal>GrantedAuthorityEffectiveAclsResolver</literal>, will iterate
        through the <literal>BasicAclEntry</literal>[]s and include only those
        where the <literal>recipient</literal> is equal to either the
        <literal>Authentication</literal>'s <literal>principal</literal> or
        any of the <literal>Authentication</literal>'s
        <literal>GrantedAuthority</literal>[]s. Please refer to the JavaDocs
        for more information.</para>

        <mediaobject>
          <imageobject role="html">
            <imagedata align="center" fileref="images/Permissions.gif"
                       format="GIF" />
          </imageobject>

          <caption>
            <para>Figure 8: ACL Instantiation Approach</para>
          </caption>
        </mediaobject>
      </sect2>

      <sect2 id="acls-conclusion">
        <title>Conclusion</title>

        <para>Acegi Security's instance-specific ACL packages shield you from
        much of the complexity of developing your own ACL approach. The
        interfaces and classes detailed above provide a scalable, customisable
        ACL solution that is decoupled from your application code. Whilst the
        reference documentation may suggest complexity, the basic
        implementation is able to support most typical applications
        out-of-the-box.</para>
      </sect2>
    </sect1>

    <sect1 id="security-filters">
      <title>Filters</title>

      <sect2 id="security-filters-overview">
        <title>Overview</title>

        <para>The Acegi Security System for Spring uses filters extensively.
        Each filter is covered in detail in a respective section of this
        document. This section includes information that applies to all
        filters.</para>
      </sect2>

      <sect2 id="security-filters-filtertobeanproxy">
        <title>FilterToBeanProxy</title>

        <para>Most filters are configured using the
        <literal>FilterToBeanProxy</literal>. An example configuration from
        <literal>web.xml</literal> follows:</para>

        <para><programlisting>&lt;filter&gt;
  &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;net.sf.acegisecurity.ClassThatImplementsFilter&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/filter&gt;</programlisting></para>

        <para>Notice that the filter in <literal>web.xml</literal> is actually
        a <literal>FilterToBeanProxy</literal>, and not the filter that will
        actually implements the logic of the filter. What
        <literal>FilterToBeanProxy</literal> does is delegate the
        <literal>Filter</literal>'s methods through to a bean which is
        obtained from the Spring application context. This enables the bean to
        benefit from the Spring application context lifecycle support and
        configuration flexibility. The bean must implement
        <literal>javax.servlet.Filter</literal>.</para>

        <para>The <literal>FilterToBeanProxy</literal> only requires a single
        initialization parameter, <literal>targetClass</literal> or
        <literal>targetBean</literal>. The <literal>targetClass</literal>
        parameter locates the first object in the application context of the
        specified class, whilst <literal>targetBean</literal> locates the
        object by bean name. Like standard Spring web applications, the
        <literal>FilterToBeanProxy</literal> accesses the application context
        via<literal>
        WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>,
        so you should configure a <literal>ContextLoaderListener</literal> in
        <literal>web.xml</literal>.</para>

        <para>There is a lifecycle issue to consider when hosting
        <literal>Filter</literal>s in an IoC container instead of a servlet
        container. Specifically, which container should be responsible for
        calling the <literal>Filter</literal>'s "startup" and "shutdown"
        methods? It is noted that the order of initialization and destruction
        of a <literal>Filter</literal> can vary by servlet container, and this
        can cause problems if one <literal>Filter</literal> depends on
        configuration settings established by an earlier initialized
        <literal>Filter</literal>. The Spring IoC container on the other hand
        has more comprehensive lifecycle/IoC interfaces (such as
        <literal>InitializingBean</literal>,
        <literal>DisposableBean</literal>, <literal>BeanNameAware</literal>,
        <literal>ApplicationContextAware</literal> and many others) as well as
        a well-understood interface contract, predictable method invocation
        ordering, autowiring support, and even options to avoid implementing
        Spring interfaces (eg the <literal>destroy-method</literal> attribute
        in Spring XML). For this reason we recommend the use of Spring
        lifecycle services instead of servlet container lifecycle services
        wherever possible. By default <literal>FilterToBeanProxy</literal>
        will not delegate <literal>init(FilterConfig)</literal> and
        <literal>destroy()</literal> methods through to the proxied bean. If
        you do require such invocations to be delegated, set the
        <literal>lifecycle</literal> initialization parameter to
        <literal>servlet-container-managed</literal>.</para>
      </sect2>

      <sect2 id="security-filters-filterchainproxy">
        <title>FilterChainProxy</title>

        <para>Whilst <literal>FilterToBeanProxy</literal> is a very useful
        class, the problem is that the lines of code required for
        <literal>&lt;filter&gt;</literal> and
        <literal>&lt;filter-mapping&gt;</literal> entries in
        <literal>web.xml</literal> explodes when using more than a few
        filters. To overcome this issue, Acegi Security provides a
        <literal>FilterChainProxy</literal> class. It is wired using a
        <literal>FilterToBeanProxy</literal> (just like in the example above),
        but the target class is
        <literal>net.sf.acegisecurity.util.FilterChainProxy</literal>. The
        filter chain is then declared in the application context, using code
        such as this:</para>

        <para><programlisting>&lt;bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy"&gt;
  &lt;property name="filterInvocationDefinitionSource"&gt;
    &lt;value&gt;
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      PATTERN_TYPE_APACHE_ANT
      /webServices/**=httpSessionContextIntegrationFilterWithASCFalse,basicProcessingFilter,securityEnforcementFilter
      /**=httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,securityEnforcementFilter
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>You may notice similarities with the way
        <literal>SecurityEnforcementFilter</literal> is declared. Both regular
        expressions and Ant Paths are supported, and the most specific URIs
        appear first. At runtime the <literal>FilterChainProxy</literal> will
        locate the first URI pattern that matches the current web request.
        Each of the corresponding configuration attributes represent the name
        of a bean defined in the application context. The filters will then be
        invoked in the order they are specified, with standard
        <literal>FilterChain</literal> behaviour being respected (a
        <literal>Filter</literal> can elect not to proceed with the chain if
        it wishes to end processing).</para>

        <para>As you can see, <literal>FitlerChainProxy</literal> requires the
        duplication of filter names for different request patterns (in the
        above example, <literal>httpSessionContextIntegrationFilter</literal>
        and <literal>securityEnforcementFilter</literal> are duplicated). This
        design decision was made to enable <literal>FilterChainProxy</literal>
        to specify different <literal>Filter</literal> invocation orders for
        different URI patterns, and also to improve both the expressiveness
        (in terms of regular expressions, Ant Paths, and any custom
        <literal>FilterInvocationDefinitionSource</literal> implementations)
        and clarity of which <literal>Filter</literal>s should be
        invoked.</para>

        <para>You may have noticed we have declared two
        <literal>HttpSessionContextIntegrationFilter</literal>s in the filter
        chain (<literal>ASC</literal> is short for
        <literal>allowSessionCreation</literal>, a property of
        <literal>HttpSessionContextIntegrationFilter</literal>). As web
        services will never present a <literal>jsessionid</literal> on future
        requests, creating <literal>HttpSession</literal>s for such user
        agents would be wasteful. If you had a high-volume application which
        required maximum scalability, we recommend you use the approach shown
        above. For smaller applications, using a single
        <literal>HttpSessionContextIntegrationFilter</literal> (with its
        default <literal>allowSessionCreation</literal> as
        <literal>true</literal>) would likely be sufficient.</para>

        <para>In relation to lifecycle issues, the
        <literal>FilterChainProxy</literal> will always delegate
        <literal>init(FilterConfig)</literal> and <literal>destroy()</literal>
        methods through to the underlaying <literal>Filter</literal>s if such
        methods are called against <literal>FilterChainProxy</literal> itself.
        In this case, <literal>FilterChainProxy</literal> guarantees to only
        initialize and destroy each <literal>Filter</literal> once,
        irrespective of how many times it is declared by the
        <literal>FilterInvocationDefinitionSource</literal>. You control the
        overall choice as to whether these methods are called or not via the
        <literal>lifecycle</literal> initialization parameter of the
        <literal>FilterToBeanProxy</literal> that proxies
        <literal>FilterChainProxy</literal>. As discussed above, by default
        any servlet container lifecycle invocations are not delegated through
        to <literal>FilterChainProxy</literal>.</para>
      </sect2>

      <sect2 id="security-filters-order">
        <title>Filter Ordering</title>

        <para>The order that filters are defined in <literal>web.xml</literal>
        is important. NB: THE FILTER ORDER CHANGED FROM VERSION 0.8.0.</para>

        <para>Irrespective of which filters you are actually using, the order
        of the <literal>&lt;filter-mapping&gt;</literal>s should be as
        follows:</para>

        <orderedlist>
          <listitem>
            <para><literal>ChannelProcessingFilter</literal>, because it might
            need to redirect to a different protocol</para>
          </listitem>

          <listitem>
            <para><literal>HttpSessionContextIntegrationFilter</literal>, so a
            <literal>Context</literal> can be setup in the
            <literal>ContextHolder</literal> at the beginning of a web
            request, and any changes to the Context can be copied to the
            <literal>HttpSession</literal> when the web request ends (ready
            for use with the next web request)</para>
          </listitem>

          <listitem>
            <para>Authentication processing mechanisms -
            <literal>AuthenticationProcessingFilter</literal>,
            <literal>CasProcessingFilter</literal>,
            <literal>BasicProcessingFilter, HttpRequestIntegrationFilter,
            JbossIntegrationFilter</literal> etc - so that the
            <literal>ContextHolder</literal> can be modified to contain a
            valid <literal>Authentication</literal> request token</para>
          </listitem>

          <listitem>
            <para>The <literal>ContextHolderAwareRequestFilter</literal>, if
            you are using it to install an Acegi Security aware
            <literal>HttpServletRequestWrapper</literal> into your servlet
            container</para>
          </listitem>

          <listitem>
            <para><literal>RememberMeProcessingFilter</literal>, so that if no
            earlier authentication processing mechanism updated the
            <literal>ContextHolder</literal>, and the request presents a
            cookie that enables remember-me services to take place, a suitable
            remembered <literal><literal>Authentication</literal></literal>
            object will be put there</para>
          </listitem>

          <listitem>
            <para><literal>AnonymousProcessingFilter</literal>, so that if no
            earlier authentication processing mechanism updated the
            <literal>ContextHolder</literal>, an anonymous
            <literal>Authentication</literal> object will be put there</para>
          </listitem>

          <listitem>
            <para><literal>SecurityEnforcementFilter</literal>, to protect web
            URIs and catch any Acegi Security exceptions so that an
            appropriate <literal>AuthenticationEntryPoint</literal> can be
            launched</para>
          </listitem>
        </orderedlist>

        <para>All of the above filters use
        <literal>FilterToBeanProxy</literal> or
        <literal>FilterChainProxy</literal>, which is discussed in the
        previous sections. It is recommended that a single
        <literal>FilterToBeProxy</literal> proxy through to a single
        <literal>FilterChainProxy</literal> for each application, with that
        <literal>FilterChainProxy</literal> defining all of the Acegi Security
        <literal>Filter</literal>s.</para>

        <para>If you're using SiteMesh, ensure the Acegi Security filters
        execute before the SiteMesh filters are called. This enables the
        <literal>ContextHolder</literal> to be populated in time for use by
        SiteMesh decorators.</para>
      </sect2>
    </sect1>

    <sect1 id="security-sample">
      <title>Contacts Sample Application</title>

      <para>Included with the Acegi Security System for Spring is a very
      simple application that can demonstrate the basic security facilities
      provided by the system (and confirm your Container Adapter is properly
      configured if you're using one).</para>

      <para>If you build from CVS, the Contacts sample application includes
      three deployable versions:
      <literal>acegi-security-sample-contacts-filter.war</literal> is
      configured with the HTTP Session Authentication approach. The
      <literal><literal>acegi-security-sample-contacts-ca.war</literal></literal>
      is configured to use a Container Adapter. Finally,
      <literal>acegi-security-sample-contacts-cas.war</literal> is designed to
      work with a Yale CAS server. If you're just wanting to see how the
      sample application works, please use
      <literal><literal>acegi-security-sample-contacts-filter.war</literal></literal>
      as it does not require special configuration of your container. This is
      also the artifact included in ofiical release ZIPs.</para>

      <para>To deploy, simply copy the relevant WAR file from the Acegi
      Security System for Spring distribution into your container’s
      <literal>webapps</literal> directory.</para>

      <para>After starting your container, check the application can load.
      Visit
      <literal>http://localhost:</literal><literal><literal>8080/</literal>acegi-security-sample-contacts-filter</literal>
      (or whichever URL is appropriate for your web container and the WAR you
      deployed). A random contact should be displayed. Click "Refresh" several
      times and you will see different contacts. The business method that
      provides this random contact is not secured.</para>

      <para>Next, click "Debug". You will be prompted to authenticate, and a
      series of usernames and passwords are suggested on that page. Simply
      authenticate with any of these and view the resulting page. It should
      contain a success message similar to the following:</para>

      <blockquote>
        <para>Context on ContextHolder is of type:
        net.sf.acegisecurity.context.secure.SecureContextImpl</para>

        <para>The Context implements SecureContext.</para>

        <para>Authentication object is of type:
        net.sf.acegisecurity.adapters.PrincipalAcegiUserToken</para>

        <para>Authentication object as a String:
        net.sf.acegisecurity.adapters.PrincipalAcegiUserToken@e9a7c2:
        Username: marissa; Password: [PROTECTED]; Authenticated: true; Granted
        Authorities: ROLE_TELLER, ROLE_SUPERVISOR</para>

        <para>Authentication object holds the following granted
        authorities:</para>

        <para>ROLE_TELLER (getAuthority(): ROLE_TELLER)</para>

        <para>ROLE_SUPERVISOR (getAuthority(): ROLE_SUPERVISOR)</para>

        <para>SUCCESS! Your [container adapter|web filter] appears to be
        properly configured!</para>
      </blockquote>

      <para>If you receive a different message, and deployed
      <literal>acegi-security-sample-contacts-ca.war</literal>, check you have
      properly configured your Container Adapter as described elsewhere in
      this reference guide.</para>

      <para>Once you successfully receive the above message, return to the
      sample application's home page and click "Manage". You can then try out
      the application. Notice that only the contacts available to the
      currently logged on user are displayed, and only users with
      <literal>ROLE_SUPERVISOR</literal> are granted access to delete their
      contacts. Behind the scenes, the
      <literal>MethodSecurityInterceptor</literal> is securing the business
      objects. If you're using
      <literal><literal>acegi-security-sample-contacts-filter.war</literal></literal>
      or <literal>acegi-security-sample-contacts-cas.war</literal>, the
      <literal>FilterSecurityInterceptor</literal> is also securing the HTTP
      requests. If using either of these WARs, be sure to try visiting
      <literal>http://localhost:8080/contacts/secure/super</literal>, which
      will demonstrate access being denied by the
      <literal>SecurityEnforcementFilter</literal>. Note the sample
      application enables you to modify the access control lists associated
      with different contacts. Be sure to give this a try and understand how
      it works by reviewing the sample application's application context XML
      files.</para>

      <para>The Contacts sample application also include a
      <literal>client</literal> directory. Inside you will find a small
      application that queries the backend business objects using several web
      services protocols. This demonstrates how to use the Acegi Security
      System for Spring for authentication with Spring remoting protocols. To
      try this client, ensure your servlet container is still running the
      Contacts sample application, and then execute <literal>client marissa
      koala</literal>. The command-line parameters respectively represent the
      username to use, and the password to use. Note that you may need to edit
      <literal>client.properties</literal> to use a different target
      URL.</para>

      <para>Please note the sample application's <literal>client</literal>
      does not currently support CAS. You can still give it a try, though, if
      you're ambitious: try <literal>client _cas_stateless_
      YOUR-SERVICE-TICKET-ID</literal>.</para>
    </sect1>

    <sect1 id="security-become-involved">
      <title>Become Involved</title>

      <para>We welcome you to become involved in the Acegi Security System for
      Spring project. There are many ways of contributing, including reading
      the mailing list and responding to questions from other people, writing
      new code, improving existing code, assisting with documentation, or
      simply making suggestions.</para>

      <para>SourceForge provides CVS services for the project, allowing
      anybody to access the latest code. If you wish to contribute new code,
      please observe the following requirements. These exist to maintain the
      quality and consistency of the project:</para>

      <itemizedlist>
        <listitem>
          <para>Use a suitable IDE Jalopy plug-in to convert your code into
          the project's consistent style</para>
        </listitem>

        <listitem>
          <para>Ensure your code does not break any unit tests (run the Maven
          <literal>test:test</literal> goal)</para>
        </listitem>

        <listitem>
          <para>If you have added new code, please provide suitable unit tests
          (use the Maven <literal>clover:html-report</literal> to view
          coverage)</para>
        </listitem>

        <listitem>
          <para>Join the acegisecurity-developer and acegisecurity-cvs mailing
          lists so you're in the loop</para>
        </listitem>

        <listitem>
          <para>Use CamelCase</para>
        </listitem>

        <listitem>
          <para>Add a CVS <literal>$Id: index.xml,v 1.3 2004/04/02 21:12:25
          fbos Exp $</literal> tag to the JavaDocs for any new class you
          create</para>
        </listitem>
      </itemizedlist>
    </sect1>

    <sect1 id="security-further">
      <title>Further Information</title>

      <para>Questions and comments on the Acegi Security System for Spring are
      welcome. Please use the Spring Community Forum web site at
      <literal>http://forum.springframework.org</literal>. You're also welcome
      to join the acegisecurity-developer mailing list. Our project home page
      (where you can obtain the latest release of the project and access to
      CVS, mailing lists, forums etc) is at
      <literal>http://acegisecurity.sourceforge.net</literal>.</para>
    </sect1>
  </chapter>
</book>