<?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</title>

    <subtitle>Reference Documentation</subtitle>

    <releaseinfo>1.0.0</releaseinfo>

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

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

  <toc></toc>

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

    <para>Acegi Security provides a comprehensive security solution for
    J2EE-based enterprise software applications. As you will discover as you
    venture through this reference guide, we have tried to provide you a
    useful and highly configurable security system.</para>

    <para>Security is an ever-moving target, and it's important to pursue a
    comprehensive, system-wide approach. In security circles we encourage you
    to adopt "layers of security", so that each layer tries to be as secure as
    possible in its own right, with successive layers providing additional
    security. The "tighter" the security of each layer, the more robust and
    safe your application will be. At the bottom level you'll need to deal
    with issues such as transport security and system identification, in order
    to mitigate man-in-the-middle attacks. Next you'll generally utilise
    firewalls, perhaps with VPNs or IP security to ensure only authorised
    systems can attempt to connect. In corporate environments you may deploy a
    DMZ to separate public-facing servers from backend database and
    application servers. Your operating system will also play a critical part,
    addressing issues such as running processes as non-privileged users and
    maximising file system security. An operating system will usually also be
    configured with its own firewall. Hopefully somewhere along the way you'll
    be trying to prevent denial of service and brute force attacks against the
    system. An intrusion detection system will also be especially useful for
    monitoring and responding to attacks, with such systems able to take
    protective action such as blocking offending TCP/IP addresses in
    real-time. Moving to the higher layers, your Java Virtual Machine will
    hopefully be configured to minimize the permissions granted to different
    Java types, and then your application will add its own problem
    domain-specific security configuration. Acegi Security makes this latter
    area - application security - much easier.</para>

    <para>Of course, you will need to properly address all security layers
    mentioned above, together with managerial factors that encompass every
    layer. A non-exhaustive list of such managerial factors would include
    security bulletin monitoring, patching, personnel vetting, audits, change
    control, engineering management systems, data backup, disaster recovery,
    performance benchmarking, load monitoring, centralised logging, incident
    response procedures etc.</para>

    <para>With Acegi Security being focused on helping you with the enterprise
    application security layer, you will find that there are as many different
    requirements as there are business problem domains. A banking application
    has different needs from an ecommerce application. An ecommerce
    application has different needs from a corporate sales force automation
    tool. These custom requirements make application security interesting,
    challenging and rewarding.</para>

    <para>This reference guide has been largely restructured for the 1.0.0
    release of Acegi Security. Please read Part I, <link
    linkend="overall-architecture">Overall Architecture</link>, in its
    entirety. The remaining parts of the reference guide are structured in a
    more traditional reference style, designed to be read on an as-required
    basis.</para>

    <para>We hope that you find this reference guide useful, and we welcome
    your feedback and <link linkend="jira">suggestions</link>.</para>

    <para>Finally, welcome to the Acegi Security <link
    linkend="community">community</link>.</para>
  </preface>

  <part id="overall-architecture">
    <title>Overall Architecture</title>

    <partintro>
      <para>Like most software, Acegi Security has certain central interfaces,
      classes and conceptual abstractions that are commonly used throughout
      the framework. In this part of the reference guide we will introduce
      Acegi Security, before examining these central elements that are
      necessary to successfully planning and executing an Acegi Security
      integration.</para>
    </partintro>

    <chapter id="introduction">
      <title>Introduction</title>

      <sect1 id="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="what-is-acegi-security">
        <title>What is Acegi Security?</title>

        <para>Acegi Security provides comprehensive security services for
        J2EE-based enterprise software applications. There is a particular
        emphasis on supporting projects built using The Spring Framework,
        which is the leading J2EE solution for enterprise software
        development. If you're not using Spring for developing enterprise
        applications, we warmly encourage you to take a closer look at it.
        Some familiarity with Spring - and in particular dependency injection
        principles - will help you get up to speed with Acegi Security more
        easily.</para>

        <para>People use Acegi Security for many reasons, but most are drawn
        to the project after finding the security features of J2EE's Servlet
        Specification or EJB Specification lack the depth required for typical
        enterprise application scenarios. Whilst mentioning these standards,
        it's important to recognise that they are not portable at a WAR or EAR
        level. Therefore, if you switch server environments, it is typically a
        lot of work to reconfigure your application's security in the new
        target environment. Using Acegi Security overcomes these problems, and
        also brings you dozens of other useful, entirely customisable security
        features.</para>

        <para>As you probably know, security comprises two major operations.
        The first is known as "authentication", which is the process of
        establishing a principal is who they claim to be. A "principal"
        generally means a user, device or some other system which can perform
        an action in your application. "Authorization" refers to the process
        of deciding whether a principal is allowed to perform an action in
        your application. To arrive at the point where an authorization
        decision is needed, the identity of the principal has already been
        established by the authentication process. These concepts are common,
        and not at all specific to Acegi Security.</para>

        <para>At an authentication level, Acegi Security supports a wide range
        of authentication models. Most of these authentication models are
        either provided by third parties, or are developed by relevant
        standards bodies such as the Internet Engineering Task Force. In
        addition, Acegi Security provides its own set of authentication
        features. Specifically, Acegi Security currently supports
        authentication with all of these technologies:</para>

        <itemizedlist spacing="compact">
          <listitem>
            <para>HTTP BASIC authentication headers (an IEFT RFC-based
            standard)</para>
          </listitem>

          <listitem>
            <para>HTTP Digest authentication headers (an IEFT RFC-based
            standard)</para>
          </listitem>

          <listitem>
            <para>HTTP X.509 client certificate exchange (an IEFT RFC-based
            standard)</para>
          </listitem>

          <listitem>
            <para>LDAP (a very common approach to cross-platform
            authentication needs, especially in large environments)</para>
          </listitem>

          <listitem>
            <para>Form-based authentication (for simple user interface
            needs)</para>
          </listitem>

          <listitem>
            <para>Computer Associates Siteminder</para>
          </listitem>

          <listitem>
            <para>JA-SIG Central Authentication Service (otherwise known as
            CAS, which is a popular open source single sign on system)</para>
          </listitem>

          <listitem>
            <para>Transparent authentication context propagation for Remote
            Method Invocation (RMI) and HttpInvoker (a Spring remoting
            protocol)</para>
          </listitem>

          <listitem>
            <para>Automatic "remember-me" authentication (so you can tick a
            box to avoid re-authentication for a predetermined period of
            time)</para>
          </listitem>

          <listitem>
            <para>Anonymous authentication (allowing every call to
            automatically assume a particular security identity)</para>
          </listitem>

          <listitem>
            <para>Run-as authentication (which is useful if one call should
            proceed with a different security identity)</para>
          </listitem>

          <listitem>
            <para>Java Authentication and Authorization Service (JAAS)</para>
          </listitem>

          <listitem>
            <para>Container integration with JBoss, Jetty, Resin and Tomcat
            (so you can still use Container Manager Authentication if
            desired)</para>
          </listitem>

          <listitem>
            <para>Your own authentication systems (see below)</para>
          </listitem>
        </itemizedlist>

        <para>Many independent software vendors (ISVs) adopt Acegi Security
        because of this rich choice of authentication models. Doing so allows
        them to quickly integrate their solutions with whatever their end
        clients need, without undertaking a lot of engineering or requiring
        the client to change their environment. If none of the above
        authentication mechanisms suit your needs, Acegi Security is an open
        platform and it is quite simple to write your own authentication
        mechanism. Many corporate users of Acegi Security need to integrate
        with "legacy" systems that don't follow any particular security
        standards, and Acegi Security is happy to "play nicely" with such
        systems.</para>

        <para>Sometimes the mere process of authentication isn't enough.
        Sometimes you need to also differentiate security based on the way a
        principal is interacting with your application. For example, you might
        want to ensure requests only arrive over HTTPS, in order to protect
        passwords from eavesdropping or end users from man-in-the-middle
        attacks. Or, you might want to ensure that an actual human being is
        making the requests and not some robot or other automated process.
        This is especially helpful to protect password recovery processes from
        brute force attacks, or simply to make it harder for people to
        duplicate your application's key content. To help you achieve these
        goals, Acegi Security fully supports automatic "channel security",
        together with JCaptcha integration for human user detection.</para>

        <para>Irrespective of how authentication was undertaken, Acegi
        Security provides a deep set of authorization capabilities. There are
        three main areas of interest in respect of authorization, these being
        authorizing web requests, authorizing methods can be invoked, and
        authorizing access to individual domain object instances. To help you
        understand the differences, consider the authorization capabilities
        found in the Servlet Specification web pattern security, EJB Container
        Managed Security and file system security respectively. Acegi Security
        provides deep capabilities in all of these important areas, which
        we'll explore later in this reference guide.</para>
      </sect1>

      <sect1 id="history">
        <title>History</title>

        <para>Acegi Security began in late 2003, when a question was posed on
        the Spring Developers' mailing list asking whether there had been any
        consideration given to a Spring-based security implementation. At the
        time the Spring community was relatively small (especially by today's
        size!), and indeed Spring itself had only existed as a SourceForge
        project from early 2003. The response to the question was that it was
        a worthwhile area, although a lack of time currently prevented its
        exploration.</para>

        <para>With that in mind, a simple security implementation was built
        and not released. A few weeks later another member of the Spring
        community inquired about security, and at the time this code was
        offered to them. Several other requests followed, and by January 2004
        around twenty people were using the code. These pioneering users were
        joined by others who suggested a SourceForge project was in order,
        which was duly established in March 2004.</para>

        <para>In those early days, the project didn't have any of its own
        authentication modules. Container Managed Security was relied upon for
        the authentication process, with Acegi Security instead focusing on
        authorization. This was suitable at first, but as more and more users
        requested additional container support, the fundamental limitation of
        container-specific authentication realm interfaces was experienced.
        There was also a related issue of adding new JARs to the container's
        classpath, which was a common source of end user confusion and
        misconfiguration.</para>

        <para>Acegi Security-specific authentication services were
        subsequently introduced. Around a year later, the Acegi Security
        became an official Spring Framework subproject. The 1.0.0 final
        release was published in May 2006 - after more than two and a half
        years of active use in numerous production software projects and many
        hundreds of improvements and community contributions.</para>

        <para>Today Acegi Security enjoys a strong and active open source
        community. There are thousands of messages about Acegi Security on the
        support forums. Fourteen developers work on the code itself, with an
        active community who also regularly share patches and support their
        peers.</para>
      </sect1>

      <sect1 id="release-numbering">
        <title>Release Numbering</title>

        <para>It is useful to understand how Acegi Security release numbers
        work, as it will help you identify the effort (or lack thereof)
        involved in migrating to future releases of the project. Officially,
        we use the Apache Portable Runtime Project versioning guidelines,
        which can be viewed at
        <literal>http://apr.apache.org/versioning.html</literal>. We quote the
        introduction contained on that page for your convenience:</para>

        <para><quote>Versions are denoted using a standard triplet of
        integers: MAJOR.MINOR.PATCH. The basic intent is that MAJOR versions
        are incompatible, large-scale upgrades of the API. MINOR versions
        retain source and binary compatibility with older minor versions, and
        changes in the PATCH level are perfectly compatible, forwards and
        backwards.</quote></para>
      </sect1>
    </chapter>

    <chapter id="technical-overview">
      <title>Technical Overview</title>

      <sect1 id="runtime-environment">
        <title>Runtime Environment</title>

        <para>Acegi Security is written to execute within a standard Java 1.3
        Runtime Environment. It also supports Java 5.0, although the Java
        types which are specific to this release are packaged in a separate
        package with the suffix "tiger" in their JAR filename. As Acegi
        Security aims to operate in a self-contained manner, there is no need
        to place any special configuration files into your Java Runtime
        Environment. In particular, there is no need to configure a special
        Java Authentication and Authorization Service (JAAS) policy file or
        place Acegi Security into common classpath locations.</para>

        <para>Similarly, if you are using an EJB Container or Servlet
        Container there is no need to put any special configuration files
        anywhere, nor include Acegi Security in a server classloader.</para>

        <para>This above design offers maximum deployment time flexibility, as
        you can simply copy your target artifact (be it a JAR, WAR or EAR)
        from one system to another and it will immediately work.</para>
      </sect1>

      <sect1 id="shared-components">
        <title>Shared Components</title>

        <para>Let's explore some of the most important shared components in
        Acegi Security. Components are considered "shared" if they are central
        to the framework and the framework cannot operate without them. These
        Java types represent the building blocks of the remaining system, so
        it's important to understand that they're there, even if you don't
        need to directly interact with them.</para>

        <para>The most fundamental object is
        <literal>SecurityContextHolder</literal>. This is where we store
        details of the present security context of the application, which
        includes details of the principal currently using the application. By
        default the <literal>SecurityContextHolder</literal> uses a
        <literal>ThreadLocal</literal> to store these details, which means
        that the security context is always available to methods in the same
        thread of execution, even if the security context is not explicitly
        passed around as an argument those methods. Using a
        <literal>ThreadLocal</literal> in this way is quite safe if care is
        taken to clear the thread after the present principal's request is
        processed. Of course, Acegi Security takes care of for you
        automatically so there is no need to worry about it.</para>

        <para>Some applications aren't entirely suitable for using a
        <literal>ThreadLocal</literal>, because of the specific way they work
        with threads. For example, a Swing client might want all threads in a
        Java Virtual Machine to use the same security context. For this
        situation you would use the
        <literal>SecurityContextHolder.MODE_GLOBAL</literal>. Other
        applications might want to have threads spawned by the secure thread
        also assume the same security identity. This is achieved by using
        <literal>SecurityContextHolder.MODE_INHERITABLETHREADLOCAL</literal>.
        You can change the mode from the default
        <literal>SecurityContextHolder.MODE_THREADLOCAL</literal> in two ways.
        The first is to set a system property. Alternatively, call a static
        method on <literal>SecurityContextHolder</literal>. Most applications
        won't need to change from the default, but if you do, take a look at
        the JavaDocs for <literal>SecurityContextHolder</literal> to learn
        more.</para>

        <para>Inside the <literal>SecurityContextHolder</literal> we store
        details of the principal currently interacting with the application.
        Acegi Security uses an <literal>Authentication</literal> object to
        represent this information. Whilst you won't normally need to create
        an <literal>Authentication</literal> object yourself, it is fairly
        common for users to query the <literal>Authentication</literal>
        object. You can use the following code block - from anywhere in your
        application - to do this:</para>

        <programlisting>Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (obj instanceof UserDetails) {
  String username = ((UserDetails)obj).getUsername();
} else {
  String username = obj.toString();
}</programlisting>

        <para>The above code introduces a number of interesting relationships
        and key objects. First, you will notice that there is an intermediate
        object between <literal>SecurityContextHolder</literal> and
        <literal>Authentication</literal>. The
        <literal>SecurityContextHolder.getContext()</literal> method is
        actually returning a <literal>SecurityContext</literal>. Acegi
        Security uses a few different <literal>SecurityContext</literal>
        implementations, such as if we need to store special information
        related to a request that is not principal-specific. A good example of
        this is our JCaptcha integration, which needs to know whether the
        current request came from a human user or not. Because such a decision
        has nothing at all to do with the principal the request may or may not
        be authenticated as, we store it in the
        <literal>SecurityContext</literal>.</para>

        <para>Another item to note from the above code fragment is that you
        can obtain a principal from the <literal>Authentication</literal>
        object. The principal is just an <literal>Object</literal>. Most of
        the time this can be cast into a <literal>UserDetails</literal>
        object. <literal>UserDetails</literal> is a central interface in Acegi
        Security. It represents a principal, but in an extensible and
        application-specific way. Think of <literal>UserDetails</literal> as
        the adapter between your own user database and what Acegi Security
        needs inside the <literal>SecurityContextHolder</literal>. Being a
        representation of something from your own user database, quite often
        you will cast the <literal>UserDetails</literal> to the original
        object that your application provided, so you can call
        business-specific methods (like <literal>getEmail()</literal>,
        <literal>getEmployeeNumber()</literal> and so on).</para>

        <para>By now you're probably wondering, so when do I provide a
        <literal>UserDetails</literal> object? How do I do that? I thought you
        said this thing was declarative and I didn't need to write any Java
        code - what gives? The short answer is that there is a special
        interface called <literal>UserDetailsService</literal>. The only
        method on this interface accepts a <literal>String</literal>-based
        username argument and returns a <literal>UserDetails</literal>. Most
        authentication providers that ship with Acegi Security delegate to a
        <literal>UserDetailsService</literal> as part of the authentication
        process. The <literal>UserDetailsService</literal> is used to build
        the <literal>Authentication</literal> object that is stored in the
        <literal>SecurityContextHolder</literal>. The good news is that we
        provide a number of <literal>UserDetailsService</literal>
        implementations, including one that uses an in-memory map and another
        that uses JDBC. Most users tends to write their own, though, with such
        implementations often simply sitting on top of an existing Data Access
        Object (DAO) that represents their employees, customers, or other
        users of the enterprise application. Remember the advantage that
        whatever your UserDetailsService returns can always be obtained from
        the <literal>SecurityContextHolder</literal>, as per the above code
        fragment.</para>

        <para>Besides the principal, another important method provided by
        <literal>Authentication</literal> is
        <literal>getAuthorities(</literal>). This method provides an array of
        <literal>GrantedAuthority</literal> objects. A
        <literal>GrantedAuthority</literal> is, not surprisingly, an authority
        that is granted to the principal. Such authorities are usually
        "roles", such as <literal>ROLE_ADMINISTRATOR</literal> or
        <literal>ROLE_HR_SUPERVISOR</literal>. These roles are later on
        configured for web authorization, method authorization and domain
        object authorization. Other parts of Acegi Security are capable of
        interpreting these authorities, and expect them to be present. You
        will usually return <literal>GrantedAuthority</literal> objects from
        the <literal>UserDetailsService</literal>.</para>

        <para>Usually the <literal>GrantedAuthority</literal> objects are
        application-wide permissions. They are not specific to a given domain
        object. Thus, you wouldn't likely have a
        <literal>GrantedAuthority</literal> to represent a permission to
        <literal>Employee</literal> object number 54, because if there are
        thousands of such authorities you would quickly run out of memory (or,
        at the very least, cause the application to take a long time to
        authenticate a user). Of course, Acegi Security is expressly designed
        to handle this common requirement, but you'd instead use the project's
        domain object security capabilities for this purpose.</para>

        <para>Last but not least, sometimes you will need to store the
        <literal>SecurityContext</literal> between HTTP requests. Other times
        the principal will re-authenticate on every request, although most of
        the time it will be stored. The
        <literal>HttpSessionContextIntegrationFilter</literal> is responsible
        for storing a <literal>SecurityContext</literal> between HTTP
        requests. As suggested by the name of the class, the
        <literal>HttpSession</literal> is used to store this information. You
        should never interact directly with the <literal>HttpSession</literal>
        for security purposes. There is simply no justification for doing so -
        always use the <literal>SecurityContextHolder</literal>
        instead.</para>

        <para>Just to recap, the major building blocks of Acegi Security
        are:</para>

        <itemizedlist spacing="compact">
          <listitem>
            <para><literal>SecurityContextHolder</literal>, to provide any
            type access to the <literal>SecurityContext</literal>.</para>
          </listitem>

          <listitem>
            <para><literal>SecurityContext</literal>, to hold the
            <literal>Authentication</literal> and possibly request-specific
            security information.</para>
          </listitem>

          <listitem>
            <para><literal>HttpSessionContextIntegrationFilter</literal>, to
            store the <literal>SecurityContext</literal> in the
            <literal>HttpSession</literal> between web requests.</para>
          </listitem>

          <listitem>
            <para><literal>Authentication</literal>, to represent the
            principal in an Acegi Security-specific manner.</para>
          </listitem>

          <listitem>
            <para><literal>GrantedAuthority</literal>, to reflect the
            application-wide permissions granted to a principal.</para>
          </listitem>

          <listitem>
            <para><literal>UserDetails</literal>, to provide the necessary
            information to build an Authentication object from your
            application's DAOs.</para>
          </listitem>

          <listitem>
            <para><literal>UserDetailsService</literal>, to create a
            <literal>UserDetails</literal> when passed in a
            <literal>String</literal>-based username (or certificate ID or
            alike).</para>
          </listitem>
        </itemizedlist>

        <para>Now that you've gained an understanding of these repeatedly-used
        components, let's take a closer look at the process of
        authentication.</para>
      </sect1>

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

        <para>As mentioned in the beginning of this reference guide, Acegi
        Security can participate in many different authentication
        environments. Whilst we recommend people use Acegi Security for
        authentication and not integrate with existing Container Managed
        Authentication, it is nevertheless supported - as is integrating with
        your own proprietary authentication system. Let's first explore
        authentication from the perspective of Acegi Security managing web
        security entirely on its own, which is illustrative of the most
        complex and most common situation.</para>

        <para>Consider a typical web application's authentication
        process:</para>

        <orderedlist>
          <listitem>
            <para>You visit the home page, and click on a link.</para>
          </listitem>

          <listitem>
            <para>A request goes to the server, and the server decides that
            you've asked for a protected resource.</para>
          </listitem>

          <listitem>
            <para>As you're not presently authenticated, the server sends back
            a response indicating that you must authenticate. The response
            will either be a HTTP response code, or a redirect to a particular
            web page.</para>
          </listitem>

          <listitem>
            <para>Depending on the authentication mechanism, your browser will
            either redirect to the specific web page so that you can fill out
            the form, or the browser will somehow retrieve your identity (eg a
            BASIC authentication dialogue box, a cookie, a X509 certificate
            etc).</para>
          </listitem>

          <listitem>
            <para>The browser will send back a response to the server. This
            will either be a HTTP POST containing the contents of the form
            that you filled out, or a HTTP header containing your
            authentication details.</para>
          </listitem>

          <listitem>
            <para>Next the server will decide whether or not the presented
            credentials are valid. If they're valid, the next step will
            happen. If they're invalid, usually your browser will be asked to
            try again (so you return to step two above).</para>
          </listitem>

          <listitem>
            <para>The original request that you made to cause the
            authentication process will be retried. Hopefully you've
            authenticated with sufficient granted authorities to access the
            protected resource. If you have sufficient access, the request
            will be successful. Otherwise, you'll receive back a HTTP error
            code 403, which means "forbidden".</para>
          </listitem>
        </orderedlist>

        <para>Acegi Security has distinct classes responsible for most of the
        steps described above. The main participants (in the order that they
        are used) are the <literal>ExceptionTranslationFilter</literal>, an
        <literal>AuthenticationEntryPoint</literal>, an authentication
        mechanism, and an <literal>AuthenticationProvider</literal>.</para>

        <para><literal>ExceptionTranslationFilter</literal> is an Acegi
        Security filter that has responsibility for detecting any Acegi
        Security exceptions that are thrown. Such exceptions will generally be
        thrown by an <literal>AbstractSecurityInterceptor</literal>, which is
        the main provider of authorization services. We will discuss
        <literal>AbstractSecurityInterceptor</literal> in the next section,
        but for now we just need to know that it produces Java exceptions and
        knows nothing about HTTP or how to go about authenticating a
        principal. Instead the <literal>ExceptionTranslationFilter</literal>
        offers this service, with specific responsibility for either returning
        error code 403 (if the principal has been authenticated and therefore
        simply lacks sufficient access - as per step seven above), or
        launching an <literal>AuthenticationEntryPoint</literal> (if the
        principal has not been authenticated and therefore we need to go
        commence step three).</para>

        <para>The <literal>AuthenticationEntryPoint</literal> is responsible
        for step three in the above list. As you can imagine, each web
        application will have a default authentication strategy (well, this
        can be configured like nearly everything else in Acegi Security, but
        let's keep it simple for now). Each major authentication system will
        have its own <literal>AuthenticationEntryPoint</literal>
        implementation, which takes actions such as described in step
        three.</para>

        <para>After your browser decides to submit your authentication
        credentials (either as a HTTP form post or HTTP header) there needs to
        be something on the server that "collects" these authentication
        details. By now we're at step six in the above list. In Acegi Security
        was have a special name for the function of collecting authentication
        details from a user agent (usually a web browser), and that name is
        "authentication mechanism". After the authentication details are
        collected from the user agent, an "<literal>Authentication</literal>
        request" object is built and then presented to an
        AuthenticationProvider.</para>

        <para>The last played in the Acegi Security authentication process is
        an <literal>AuthenticationProvider</literal>. Quite simply, it is
        responsible for taking an <literal>Authentication</literal> request
        object and deciding whether or not it is valid. The provider will
        either throw an exception, or return a fully populated
        <literal>Authentication</literal> object. Remember our good friends,
        <literal>UserDetails</literal> and
        <literal>UserDetailsService</literal>? If not, head back to the
        previous section and refresh your memory. Most
        <literal>AuthenticationProvider</literal>s will ask a
        <literal>UserDetailsService</literal> to provide a
        <literal>UserDetails</literal> object. As mentioned earlier, most
        application will provide their own
        <literal>UserDetailsService</literal>, although some will be able to
        use the JDBC or in-memory implementation that ships with Acegi
        Security. The resultant <literal>UserDetails</literal> object - and
        particularly the <literal>GrantedAuthority[]</literal>s contained
        within the <literal>UserDetails</literal> object - will be used when
        building the fully populated <literal>Authentication</literal>
        object.</para>

        <para>After the authentication mechanism receives back the
        fully-populated <literal>Authentication</literal> object, it will deem
        the request valid, put the <literal>Authentication</literal> into the
        <literal>SecurityContextHolder</literal>, and cause the original
        request to be retried (step seven above). If, on the other hand, the
        <literal>AuthenticationProvider</literal> rejected the request, the
        authentication mechanism will ask the user agent to retry (step two
        above).</para>

        <para>Whilst this describes the typical authentication workflow, the
        good news is that Acegi Security doesn't mind how you put an
        <literal>Authentication</literal> inside the
        <literal>SecurityContextHolder</literal>. The only critical
        requirement is that the <literal>SecurityContextHolder</literal>
        contains an <literal>Authentication</literal> that represents a
        principal before the <literal>AbstractSecurityInterceptor</literal>
        needs to authorize a request.</para>

        <para>You can (and many users do) write their own filters or MVC
        controllers to provide interoperability with authentication systems
        that are not based on Acegi Security. For example, you might be using
        Container Managed Authentication which makes the current user
        available from a ThreadLocal or JNDI location. Or you might work for a
        company that has a legacy proprietary authentication system, which is
        a corporate "standard" over which you have little control. In such
        situations it's quite easy to get Acegi Security to work, and still
        provide authorization capabilities. All you need to do is write a
        filter (or equivalent) that reads the third-party user information
        from a location, build an Acegi Security-specific Authentication
        object, and put it onto the SecurityContextHolder. It's quite easy to
        do this, and a fully-supported integration approach.</para>
      </sect1>

      <sect1 id="secure-objects">
        <title>Secure Objects</title>

        <para>If you're familiar with AOP, you'd be aware there are different
        types of advice available: before, after, throws and around. An around
        advice is very useful, because an advisor can elect whether or not to
        proceed with a method invocation, whether or not to modify the
        response, and whether or not to throw an exception. Acegi Security
        provides an around advice for method invocations as well as web
        requests. We achieve an around advice for method invocations using AOP
        Alliance, and we achieve an around advice for web requests using a
        standard Filter.</para>

        <para>For those not familiar with AOP, the key point to understand is
        that Acegi Security can help you protect method invocations as well as
        web requests. Most people are interested in securing method
        invocations on their services layer. This is because the services
        layer is where most business logic resides in current-generation J2EE
        applications (for clarification, the author disapproves of this design
        and instead advocates properly encapsulated domain objects together
        with the DTO, assembly, facade and transparent persistence patterns,
        but as anemic domain objects is the present mainstream approach, we'll
        talk about it here). If you just need to secure method invocations to
        the services layer, using the Spring's standard AOP platform
        (otherwise known as AOP Alliance) will be adequate. If you need to
        secure domain objects directly, you will likely find that AspectJ is
        worth considering.</para>

        <para>You can elect to perform method authorization using AspectJ or
        AOP Alliance, or you can elect to perform web request authorization
        using filters. You can use zero, one, two or three of these approaches
        together. The mainstream usage is to perform some web request
        authorization, coupled with some AOP Alliance method invocation
        authorization on the services layer.</para>

        <para>Acegi Security uses the term "secure object" to refer to any
        object that can have security applies to it. Each secure object
        supported by Acegi Security has its own class, which is a subclass of
        <literal>AbstractSecurityInterceptor</literal>. Importantly, by the
        time the <literal>AbstractSecurityInterceptor</literal> is run, the
        <literal>SecurityContextHolder</literal> will contain a valid
        <literal>Authentication</literal> if the principal has been
        authenticated.</para>

        <para>The <literal>AbstractSecurityInterceptor</literal> provides a
        consistent workflow for handling secure object requests. This workflow
        includes looking up the "configuration attributes" associated with the
        present request. A "configuration attribute" can be thought of as a
        String that has special meaning to the classes used by
        <literal>AbstractSecurityInterceptor</literal>. They're normally
        configured against your AbstractSecurityInterceptor using XML. Anyway,
        the <literal>AbstractSecurityInterceptor</literal> will ask an
        <literal>AccessDecisionManager</literal> "here's the configuration
        attributes, here's the current <literal>Authentication</literal>
        object, and here's details of the current request - is this particular
        principal allowed to perform this particular operation?".</para>

        <para>Assuming <literal>AccessDecisionManager</literal> decides to
        allow the request, the <literal>AbstractSecurityInterceptor</literal>
        will normally just proceed with the request. Having said that, on rare
        occasions users may want to replace the
        <literal>Authentication</literal> inside the
        <literal>SecurityContext</literal> with a different
        <literal>Authentication</literal>, which is handled by the
        <literal>AccessDecisionManager</literal> calling a
        <literal>RunAsManager</literal>. This might be useful in reasonably
        unusual situations, such as if a services layer method needs to call a
        remote system and present a different identity. Because Acegi Security
        automatically propagates security identity from one server to another
        (assuming you're using a properly-configured RMI or HttpInvoker
        remoting protocol client), this may be useful.</para>

        <para>Following the secure object proceeding and then returning -
        which may mean a method invocation completing or a filter chain
        proceeding - the <literal>AbstractSecurityInterceptor</literal> gets
        one final chance to handle the invocation. At this stage the
        <literal>AbstractSecurityInterceptor</literal> is interested in
        possibly modifying the return object. We might want this to happen
        because an authorization decision couldn't be made "on the way in" to
        a secure object invocation. Being highly pluggable,
        <literal>AbstractSecurityInterceptor</literal> will pass control to an
        <literal>AfterInvocationManager</literal> to actually modify the
        object if needed. This class even can entirely replace the object, or
        throw an exception, or not change it in any way.</para>

        <para>Because <literal>AbstractSecurityInterceptor</literal> is the
        central template class, it seems fitting that the first figure should
        be devoted to it.</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>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. Anything that requires
        security and also provides a way of intercepting a call (like the AOP
        around advice semantics) is capable of being made into a secure
        object. Having said that, 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>
      </sect1>

      <sect1 id="common-conclusion">
        <title>Conclusion</title>

        <para>Congratulations! You have enough of a high-level picture of
        Acegi Security to embark on your project. We've explored the shared
        components, how authentication works, and reviewed the common
        authorization concept of a "secure object". Everything that follows in
        this reference guide may or may not apply to your particular needs,
        and can be read in any order.</para>
      </sect1>
    </chapter>

    <chapter id="supporting-infrastructure">
      <title>Supporting Infrastructure</title>

      <para>This chapter introduces some of the supplementary and supporting
      infrastructure used by Acegi Security. If a capability is not directly
      related to security, yet included in the Acegi Security project, we will
      discuss it in this chapter.</para>

      <sect1 id="localization">
        <title>Localization</title>

        <para>Acegi Security supports localization of exception messages that
        end users are likely to see. If your application is designed for
        English users, you don't need to do anything as by default all Acegi
        Security messages are in English. If you need to support other
        locales, everything you need to know is contained in this
        section.</para>

        <para>All exception messages can be localized, including messages
        related to authentication failures and access being denied
        (authorization failures). Exceptions and logging that is focused on
        developers or system deployers (including incorrect attributes,
        interface contract violations, using incorrect constructors, startup
        time validation, debug-level logging) etc are not localized and
        instead are hard-coded in English within Acegi Security's code.</para>

        <para>Shipping in the <literal>acegi-security-xx.jar</literal> you
        will find an <literal>org.acegisecurity</literal> package that in turn
        contains a <literal>messages.properties</literal> file. This should be
        referred to by your <literal>ApplicationContext</literal>, as Acegi
        Security classes implement Spring's
        <literal>MessageSourceAware</literal> interface and expect the message
        resolver to be dependency injected at application context startup
        time. Usually all you need to do is register a bean inside your
        application context to refer to the messages. An example is shown
        below:</para>

        <para><programlisting>&lt;bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"&gt;
  &lt;property name="basename"&gt;&lt;value&gt;org/acegisecurity/messages&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;        </programlisting></para>

        <para>The <literal>messages.properties</literal> is named in
        accordance with standard resource bundles and represents the default
        language supported by Acegi Securtiy messages. This default file is in
        English. If you do not register a message source, Acegi Security will
        still work correctly and fallback to hard-coded English versions of
        the messages.</para>

        <para>If you wish to customize the
        <literal>messages.properties</literal> file, or support other
        languages, you should copy the file, rename it accordingly, and
        register it inside the above bean definition. There are not a large
        number of message keys inside this file, so localization should not be
        considered a major initiative. If you do perform localization of this
        file, please consider sharing your work with the community by logging
        a JIRA task and attaching your appropriately-named localized version
        of <literal>messages.properties</literal>.</para>

        <para>Rounding out the discussion on localization is the Spring
        <literal>ThreadLocal</literal> known as
        <literal>org.springframework.context.i18n.LocaleContextHolder</literal>.
        You should set the <literal>LocaleContextHolder</literal> to represent
        the preferred <literal>Locale</literal> of each user. Acegi Security
        will attempt to locate a message from the message source using the
        <literal>Locale</literal> obtained from this
        <literal>ThreadLocal</literal>. Please refer to Spring documentation
        for further details on using <literal>LocaleContextHolder</literal>
        and the helper classes that can automatically set it for you (eg
        <literal>AcceptHeaderLocaleResolver</literal>,
        <literal>CookieLocaleResolver</literal>,
        <literal>FixedLocaleResolver</literal>,
        <literal>SessionLocaleResolver</literal> etc)</para>
      </sect1>

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

        <para>Acegi Security uses many filters, as referred to throughout the
        remainder of this reference guide. You have a choice in how these
        filters are added to your web application, in that you can use either
        <literal>FilterToBeanProxy</literal> or
        <literal>FilterChainProxy</literal>. We'll look at both below.</para>

        <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;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;org.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 implement 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>

        <para>Rather than using <literal>FilterToBeanProxy</literal>, we
        strongly recommend to use <literal>FilterChainProxy</literal> instead.
        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>org.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="org.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,exceptionTranslationFilter,filterSecurityInterceptor
      /**=httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;        </programlisting></para>

        <para>You may notice similarities with the way
        <literal>FilterSecurityInterceptor</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>FilterChainProxy</literal> requires the
        duplication of filter names for different request patterns (in the
        above example, <literal>exceptionTranslationFilter</literal> and
        <literal>filterSecurityInterceptor</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>

        <para>The order that filters are defined in <literal>web.xml</literal>
        is very important. 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>ConcurrentSessionFilter</literal>, because it
            doesn't use any <literal>SecurityContextHolder</literal>
            functionality but needs to update the
            <literal>SessionRegistry</literal> to reflect ongoing requests
            from the principal</para>
          </listitem>

          <listitem>
            <para><literal>HttpSessionContextIntegrationFilter</literal>, so a
            <literal>SecurityContext</literal> can be setup in the
            <literal>SecurityContextHolder</literal> at the beginning of a web
            request, and any changes to the <literal>SecurityContext</literal>
            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>SecurityContextHolder</literal> can be modified to
            contain a valid <literal>Authentication</literal> request
            token</para>
          </listitem>

          <listitem>
            <para>The
            <literal>SecurityContextHolderAwareRequestFilter</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>SecurityContextHolder</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>SecurityContextHolder</literal>, an anonymous
            <literal>Authentication</literal> object will be put there</para>
          </listitem>

          <listitem>
            <para><literal>ExceptionTranslationFilter</literal>, to catch any
            Acegi Security exceptions so that either a HTTP error response can
            be returned or an appropriate
            <literal>AuthenticationEntryPoint</literal> can be launched</para>
          </listitem>

          <listitem>
            <para><literal>FilterSecurityInterceptor</literal>, to protect web
            URIs</para>
          </listitem>
        </orderedlist>

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

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

    <chapter id="channel-security">
      <title>Channel Security</title>

      <sect1 id="channel-security-overview">
        <title>Overview</title>

        <para>In addition to coordinating the authentication and authorization
        requirements of your application, Acegi Security 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. Acegi
        Security provides a solution to assist with the latter.</para>
      </sect1>

      <sect1 id="channel-security-config">
        <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;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;org.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="org.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="org.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="org.acegisecurity.securechannel.SecureChannelProcessor"/&gt;
&lt;bean id="insecureChannelProcessor" class="org.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 Acegi Security 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
        <literal>http://www.company.com:8080/app/page</literal>), not relative
        (eg <literal>/app/page</literal>). 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>
      </sect1>

      <sect1 id="channel-security-conclusion">
        <title>Conclusion</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>
      </sect1>
    </chapter>

    <chapter id="taglib">
      <title>Tag Libraries</title>

      <sect1 id="taglib-overview">
        <title>Overview</title>

        <para>Acegi Security 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>
      </sect1>

      <sect1 id="taglib-config">
        <title>Configuration</title>

        <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.org/authz&lt;/taglib-uri&gt;
  &lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
&lt;/taglib&gt;       </programlisting></para>
      </sect1>

      <sect1 id="taglib-usage">
        <title>Usage</title>

        <para>Now that you've configured the tag libraries, refer to the
        individual reference guide sections for details on how to use
        them.</para>
      </sect1>
    </chapter>
  </part>

  <part id="authentication">
    <title>Authentication</title>

    <partintro>
      <para>In this part of the reference guide we will examine individual
      authentication mechanisms and their corresponding
      <literal>AuthenticationProvider</literal>s. We'll also look at how to
      configure authentication more generally, including if you have several
      authentication approaches that need to be chained together.</para>
    </partintro>

    <chapter id="authentication-common-auth-services">
      <title>Common Authentication Services</title>

      <sect1 id="mechanisms-providers-entry-points">
        <title>Mechanisms, Providers and Entry Points</title>

        <para>If you're using Acegi Security-provided authentication
        approaches, you'll usually need to configure a web filter, together
        with an <literal>AuthenticationProvider</literal> and
        <literal>AuthenticationEntryPoint</literal>. In this section we are
        going to explore an example application that needs to support both
        form-based authentication (ie so a nice HTML page is presented to a
        user for them to login) plus BASIC authentication (ie so a web service
        or similar can access protected resources).</para>

        <para>In the web.xml, this application will need a single Acegi
        Security filter in order to use the FilterChainProxy. Nearly every
        Acegi Security application will have such an entry, and it looks like
        this:</para>

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

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

        <para>The above declarations will cause every web request to be passed
        through to Acegi Security's FilterChainProxy. As explained in the
        filters section of this reference guide, the FilterChainProxy is a
        generally-useful class that enables web requests to be passed to
        different filters based on the URL patterns. Those delegated filters
        are managed inside the application context, so they can benefit from
        dependency injection. Let's have a look at what the FilterChainProxy
        bean definition would look like inside your application
        context:</para>

        <para><programlisting>&lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt;
  &lt;property name="filterInvocationDefinitionSource"&gt;
    &lt;value&gt;
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      PATTERN_TYPE_APACHE_ANT
      /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,switchUserProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>Internally Acegi Security will use a
        <literal>PropertyEditor</literal> to convert the string presented in
        the above XML fragment into a
        <literal>FilterInvocationDefinitionSource</literal> object. What's
        important to note at this stage is that a series of filters will be
        run - in the order specified by the declaration - and each of those
        filters are actually the <literal>&lt;bean id&gt;</literal> of another
        bean inside the application context. So, in our case some extra beans
        will also appear in the application context, and they'll be named
        <literal>httpSessionContextIntegrationFilter</literal>,
        <literal>logoutFilter</literal> and so on. The order that the filters
        should appear is discussed in the filters section of the reference
        guide - although they are correct in the above example.</para>

        <para>In our example we have the
        <literal>AuthenticationProcessingFilter</literal> and
        <literal>BasicProcessingFilter</literal> being used. These are the
        "authentication mechanisms" that respond to form-based authentication
        and BASIC HTTP header-based authentication respectively (we discussed
        the role of authentication mechanisms earlier in this reference
        guide). If you weren't using form or BASIC authentication, neither of
        these beans would be defined. You'd instead define filters applicable
        to your desired authentication environment, such as
        <literal>DigestProcessingFilter</literal> or
        <literal>CasProcessingFilter</literal>. Refer to the individual
        chapters of this part of the reference guide to learn how to configure
        each of these authentication mechanisms.</para>

        <para>Recall that
        <literal>HttpSessionContextIntegrationFilter</literal> keeps the
        contents of the <literal>SecurityContext</literal> between invocations
        inside a HTTP session. This means the authentication mechanisms are
        only used once, being when the principal initially tries to
        authenticate. The rest of the time the authentication mechanisms sit
        there and silently pass the request through to the next filter in the
        chain. That is a practical requirement due to the fact that few
        authentication approaches present credentials on each and every call
        (BASIC authentication being a notable exception), but what happens if
        a principal's account gets cancelled or disabled or otherwise changed
        (eg an increase or decrease in <literal>GrantedAuthority[]</literal>s)
        after the initial authentication step? Let's look at how that is
        handled now.</para>

        <para>The major authorization provider for secure objects has
        previously been introduced as
        <literal>AbstractSecurityInterceptor</literal>. This class needs to
        have access to an <literal>AuthenticationManager</literal>. It also
        has configurable settings to indicate whether an
        <literal>Authentication</literal> object should be re-authenticated on
        each secure object invocation. By default it just accepts any
        <literal>Authentication</literal> inside the
        <literal>SecurityContextHolder</literal> is authenticated if
        <literal>Authentication.isAuthenticated()</literal> returns true. This
        is great for performance, but not ideal if you want to ensure
        up-to-the-moment authentication validity. For such cases you'll
        probably want to set the
        <literal>AbstractSecurityInterceptor.alwaysReauthenticate</literal>
        property to true.</para>

        <para>You might be asking yourself, "what's this
        <literal>AuthenticationManager</literal>?". We haven't explored it
        before, but we have discussed the concept of an
        <literal>AuthenticationProvider</literal>. Quite simply, an
        AuthenticationManager is responsible for passing requests through a
        chain of AuthenticationProviders. It's a little like the filter chain
        we discussed earlier, although there are some differences. There is
        only one AuthenticationManager implementation shipped with Acegi
        Security, so let's look at how it's configured for the example we're
        using in this chapter:</para>

        <para><programlisting>&lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;
  &lt;property name="providers"&gt;
    &lt;list&gt;
      &lt;ref local="daoAuthenticationProvider"/&gt;
      &lt;ref local="anonymousAuthenticationProvider"/&gt;
      &lt;ref local="rememberMeAuthenticationProvider"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>It's probably worth mentioning at this point that your
        authentication mechanisms (which are usually filters) are also
        injected with a reference to the
        <literal>AuthenticationManager</literal>. So both
        <literal>AbstractSecurityInterceptor</literal> as well as the
        authentication mechanisms will use the above
        <literal>ProviderManager</literal> to poll a list of
        <literal>AuthenticationProvider</literal>s.</para>

        <para>In our example we have three providers. They are tried in the
        order shown (which is implied by the use of a <literal>List</literal>
        instead of a <literal>Set</literal>), with each provider able to
        attempt authentication, or skip authentication by simply returning
        <literal>null</literal>. If all implementations return null, the
        <literal>ProviderManager</literal> will throw a suitable exception. If
        you're interested in learning more about chaining providers, please
        refer to the <literal>ProviderManager</literal> JavaDocs.</para>

        <para>The providers to use will sometimes be interchangeable with the
        authentication mechanisms, whilst at other times they will depend on a
        specific authentication mechanism. For example, the
        <literal>DaoAuthenticationProvider</literal> just needs a string-based
        username and password. Various authentication mechanisms result in the
        collection of a string-based username and password, including (but not
        limited to) BASIC and form authentication. Equally, some
        authentication mechanisms create an authentication request object
        which can only be interpreted by a single type of
        <literal>AuthenticationProvider</literal>. An example of this
        one-to-one mapping would be JA-SIG CAS, which uses the notion of a
        service ticket which can therefore only be authenticated by
        <literal>CasAuthenticationProvider</literal>. A further example of a
        one-to-one mapping would be the LDAP authentication mechanism, which
        can only be processed an the
        <literal>LdapAuthenticationProvider</literal>. The specifics of such
        relationships are detailed in the JavaDocs for each class, plus the
        authentication approach-specific chapters of this reference guide. You
        need not be terribly concerned about this implementation detail,
        because if you forget to register a suitable provider, you'll simply
        receive a <literal>ProviderNotFoundException</literal> when an attempt
        to authenticate is made.</para>

        <para>After configuring the correct authentication mechanisms in the
        <literal>FilterChainProxy</literal>, and ensuring that a corresponding
        <literal>AuthenticationProvider</literal> is registered in the
        <literal>ProviderManager</literal>, your last step is to configure an
        <literal>AuthenticationEntryPoint</literal>. Recall that earlier we
        discussed the role of <literal>ExceptionTranslationFilter</literal>,
        which is used when HTTP-based requests should receive back a HTTP
        header or HTTP redirect in order to start authentication. Continuing
        on with our earlier example:</para>

        <para><programlisting>&lt;bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt;
  &lt;property name="authenticationEntryPoint"&gt;&lt;ref local="authenticationProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
  &lt;property name="accessDeniedHandler"&gt;
    &lt;bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl"&gt;
      &lt;property name="errorPage" value="/accessDenied.jsp"/&gt;
    &lt;/bean&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="authenticationProcessingFilterEntryPoint" class="org.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;</programlisting></para>

        <para>Notice that the <literal>ExceptionTranslationFilter</literal>
        requires two collaborators. The first,
        <literal>AccessDeniedHandlerImpl</literal>, uses a
        <literal>RequestDispatcher</literal> forward to display the specified
        access denied error page. We use a forward so that the
        <literal>SecurityContextHolder</literal> still contains details of the
        principal, which may be useful for display to the user (in old
        releases of Acegi Security we relied upon the servlet container to
        handle a 403 error message, which lacked this useful contextual
        information). <literal>AccessDeniedHandlerImpl</literal> will also set
        the HTTP header to 403, which is the official error code to indicate
        access denied. In the case of the
        <literal>AuthentionEntryPoint</literal>, here we're setting what
        action we would like taken when an unauthenticated principal attempts
        to perform a protected operation. Because in our example we're going
        to be using form-based authentication, we specify
        <literal>AuthenticationProcessinFilterEntryPoint</literal> and the URL
        of the login page. Your application will usually only have one entry
        point, and most authentication approaches define their own specific
        <literal>AuthenticationEntryPoint</literal>. Details of which entry
        point to use for each authentication approach is discussed in the
        authentication approach-specific chapters of this reference
        guide.</para>
      </sect1>

      <sect1 id="userdetails-and-associated-types">
        <title>UserDetails and Associated Types</title>

        <para>As mentioned in the first part of the reference guide, most
        authentication providers take advantage of the
        <literal>UserDetails</literal> and
        <literal>UserDetailsService</literal> interfaces. The contract for
        this latter interface consists of a single method:</para>

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

        <para>The returned <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. Most
        authentication providers will use a
        <literal>UserDetailsService</literal>, even if the username and
        password are not actually used as part of the authentication decision.
        Generally such provider will be using the returned
        <literal>UserDetails</literal> object just for its
        <literal>GrantedAuthority[]</literal> information, because some other
        system (like LDAP or X509 or CAS etc) has undertaken the
        responsibility of actually validating the credentials.</para>

        <para>A single concrete implementation of
        <literal>UserDetails</literal> is provided with Acegi Security, being
        the <literal>User</literal> class. Acegi Security users will need to
        decide when writing their <literal>UserDetailsService</literal> what
        concrete <literal>UserDetails</literal> class 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. This is not such an unusual situation, and users should
        not hesitate to simply return their normal domain object that
        represents a user of the system. This is especially common given that
        <literal>UserDetails</literal> is often used to store additional
        principal-related properties (such as their telephone number and email
        address), so that they can be easily used by web views.</para>

        <para>Given <literal>UserDetailsService</literal> is so simple to
        implement, it should be easy for users to retrieve authentication
        information using a persistence strategy of their choice. Having said
        that, Acegi Security does include a couple of useful base
        implementations, which we'll look at below.</para>

        <sect2 id="in-memory-service">
          <title>In-Memory Authentication</title>

          <para>Whilst it is easy to use create a custom
          <literal>UserDetailsService</literal> implementation that extracts
          information from a persistence engine of choice, many applications
          do not require such complexity. This is particularly true if you're
          undertaking a rapid prototype or just starting integrating Acegi
          Security, when you don't really want to spend time configuring
          databases or writing <literal>UserDetailsService</literal>
          implementations. For this sort of situation, a simple option is to
          configure the <literal>InMemoryDaoImpl</literal>
          implementation:</para>

          <para><programlisting>&lt;bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.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>In the above example, the <literal>userMap</literal> property
          contains each of the usernames, passwords, a list of granted
          authorities and an optional enabled/disabled keyword. Commas are
          used to 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 (this is just for
          your reference - most application don't need custom
          <literal>GrantedAuthority</literal> implementations, so using the
          default implementation in this manner is just fine). 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>

          <para><literal>InMemoryDaoImpl</literal> also offers a
          <literal>setUserProperties(Properties)</literal> method, which
          allows you to externalise the
          <literal>java.util.Properties</literal> in another Spring configured
          bean or an external properties file. You might like to use Spring's
          <literal>PropertiesFactoryBean</literal>, which is useful for
          loading such external properties files. This setter might prove
          useful for simple applications that have a larger number of users,
          or deployment-time configuration changes, but do not wish to use a
          full database for handling authentication details.</para>
        </sect2>

        <sect2 id="jdbc-service">
          <title>JDBC Authentication</title>

          <para>Acegi Security also includes a
          <literal>UserDetailsService</literal> that can obtain authentication
          information from a JDBC data source. Internally Spring JDBC is used,
          so it avoids the complexity of a fully-featured object relational
          mapper (ORM) just to store user details. If your application does
          use an ORM tool, you might prefer to write a custom
          <literal>UserDetailsService</literal> to reuse the mapping files
          you've probably already created. Returning to
          <literal>JdbcDaoImpl</literal>, an example configuration 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="org.acegisecurity.userdetails.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. You can also use a global data source obtained from JNDI, as
          per normal Spring options. Irrespective of the database used and how
          a <literal>DataSource</literal> is obtained, a standard schema must
          be used as indicated in <literal>dbinit.txt</literal>. You can
          download this file from the Acegi Security web site.</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, although please
          note that the class is not intended for complex custom subclasses.
          If you have complex needs (such as a special schema or would like a
          certain <literal>UserDetails</literal> implementation returned),
          you'd be better off writing your own
          <literal>UserDetailsService</literal>. The base implementation
          provided with Acegi Security is intended for typical situations, and
          does not offer infinite configuration flexibility.</para>
        </sect2>
      </sect1>

      <sect1 id="concurrent-sessions">
        <title>Concurrent Session Handling</title>

        <para>Acegi Security is able to prevent a principal from concurrently
        authenticating to the same application more than a specified number of
        times. Many ISVs take advantage of this to enforce licensing, whilst
        network administrators like this feature because it helps prevent
        people from sharing login names. You can, for example, stop user
        "Batman" from logging onto the web application from two different
        sessions.</para>

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

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

        <para>In addition, you will need to add the
        <literal>org.acegisecurity.concurrent.ConcurrentSessionFilter</literal>
        to your <literal>FilterChainProxy</literal>. The
        ConcurrentSessionFilter requires only one property,
        <literal>sessionRegistry</literal>, which generally points to an
        instance of <literal>SessionRegistryImpl</literal>.</para>

        <para>The <literal>web.xml</literal>
        <literal>HttpSessionEventPublisher</literal> 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>SessionRegistryImpl</literal> to
        be notified when a session ends.</para>

        <para>You will also need to wire up the
        <literal>ConcurrentSessionControllerImpl</literal> and refer to it
        from your <literal>ProviderManager</literal> bean:</para>

        <para><programlisting>&lt;bean id="authenticationManager" class="org.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="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl"&gt;
  &lt;property name="maximumSessions"&gt;&lt;value&gt;1&lt;/value&gt;&lt;/property&gt;
  &lt;property name="sessionRegistry"&gt;&lt;ref local="sessionRegistry"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl"/&gt;</programlisting></para>
      </sect1>

      <sect1 id="authentication-taglibs">
        <title>Authentication Tag Libraries</title>

        <para><literal>AuthenticationTag</literal> is used to simply output a
        property of the current principal's
        <literal>Authentication.getPrincipal()</literal> object 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="username"/&gt;</programlisting></para>

        <para>This tag would cause the principal's name to be output. Here we
        are assuming the <literal>Authentication.getPrincipal()</literal> is a
        <literal>UserDetails</literal> object, which is generally the case
        when using the typical
        <literal>DaoAuthenticationProvider</literal>.</para>
      </sect1>
    </chapter>

    <chapter id="dao-provider">
      <title>DAO Authentication Provider</title>

      <sect1 id="dao-provider-overview">
        <title>Overview</title>

        <para>Acegi Security includes a production-quality
        <literal>AuthenticationProvider</literal> implementation called
        <literal>DaoAuthenticationProvider</literal>. This authentication
        provider is compatible with all of the authentication mechanisms that
        generate a <literal>UsernamePasswordAuthenticationToken</literal>, and
        is probably the most commonly used provider in the framework. Like
        most of the other authentication providers, the
        DaoAuthenticationProvider leverages a UserDetailsService in order to
        lookup the username, password and GrantedAuthority[]s. Unlike most of
        the other authentication providers that leverage UserDetailsService,
        this authentication provider actually requires the password to be
        presented, and the provider will actually evaluate the validity or
        otherwise of the password presented in an authentication request
        object.</para>
      </sect1>

      <sect1 id="dao-provider-config">
        <title>Configuration</title>

        <para>Aside from adding DaoAuthenticationProvider to your
        ProviderManager list (as discussed at the start of this part of the
        reference guide), and ensuring a suitable authentication mechanism is
        configured to present a UsernamePasswordAuthenticationToken, the
        configuration of the provider itself is rather simple:</para>

        <para><programlisting>&lt;bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  &lt;property name="userDetailsService"&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 presented in the <literal>UserDetails</literal> object that
        is returned from the configured <literal>UserDetailsService</literal>.
        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 Acegi Security 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="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  &lt;property name="userDetailsService"&gt;&lt;ref bean="userDetailsService"/&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="org.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>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>UserDetailsService</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>UserDetailsService</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>
      </sect1>
    </chapter>

    <chapter id="jaas">
      <title>Java Authentication and Authorization Service (JAAS)
      Provider</title>

      <sect1 id="jaas-overview">
        <title>Overview</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>
      </sect1>

      <sect1 id="jaas-config">
        <title>Configuration</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="org.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="org.acegisecurity.providers.jaas.JaasNameCallbackHandler"/&gt;
      &lt;bean class="org.acegisecurity.providers.jaas.JaasPasswordCallbackHandler"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
  &lt;property name="authorityGranters"&gt;
    &lt;list&gt;
      &lt;bean class="org.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>

        <sect2 id="jaas-callbackhandler">
          <title id="jaas-callback-handler">JAAS CallbackHandler</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.</para>

          <para>In an Acegi Security deployment, Acegi Security is responsible
          for this user interaction (via the authentication mechanism). Thus,
          by the time the authentication request is delegated through to JAAS,
          Acegi Security's authentication mechanism will already have
          fully-populated an <literal>Authentication</literal> object
          containing all the information required by the JAAS
          <literal>LoginModule</literal>.</para>

          <para>Therefore, 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.</para>

          <para>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>
        </sect2>

        <sect2 id="jaas-authoritygranter">
          <title id="jaas-authority-granter">JAAS AuthorityGranter</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, Acegi
          Security's JAAS package includes an
          <literal>AuthorityGranter</literal> interface.</para>

          <para>An <literal>AuthorityGranter</literal> is responsible for
          inspecting a JAAS principal and returning a
          <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.</para>

          <para>Acegi Security does not include any production
          <literal>AuthorityGranter</literal>s given that every JAAS principal
          has an implementation-specific meaning. However, there is a
          <literal>TestAuthorityGranter</literal> in the unit tests that
          demonstrates a simple <literal>AuthorityGranter</literal>
          implementation.</para>
        </sect2>
      </sect1>
    </chapter>

    <chapter id="siteminder">
      <title>Siteminder Authentication Mechanism</title>

      <sect1 id="siteminder-overview">
        <title>Overview</title>

        <para>Siteminder is a commercial single sign on solution by Computer
        Associates.</para>

        <para>Acegi Security provides a filter,
        <literal>SiteminderAuthenticationProcessingFilter</literal>) that can
        be used to process requests that have been pre-authenticated by
        Siteminder. This filter assumes that you're using Siteminder for
        <emphasis>authentication</emphasis>, and that you're using Acegi
        Security for <emphasis>authorization</emphasis>. The use of Siteminder
        for <emphasis>authorization</emphasis> is not yet directly supported
        by Acegi Security.</para>

        <para>In Siteminder, an agent is setup on your web server to intercept
        a principal's first call to your application. The agent redirect the
        web request to a single sign on login page, and then your application
        receives the request. Inside the HTTP headers is a header - such as
        <literal>SM_USER</literal> - which identifies the authenticated
        principal. Please refer to your organization's "single sign-on" group
        for header details in your particular configuration.</para>
      </sect1>

      <sect1 id="siteminder-config">
        <title>Configuration</title>

        <para>The first step in setting up Acegi Security's Siteminder support
        is to define the authentication mechanism that will inspect the HTTP
        header discussed earlier. It will then generate a
        <literal>UsernamePasswordAuthenticationToken</literal> that can later
        on be sent to the <literal>DaoAuthenticationProvider</literal>. Let's
        look at an example:</para>

        <para><programlisting>&lt;bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.SiteminderAuthenticationProcessingFilter"&gt;
  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/login.jsp?login_error=1&lt;/value&gt;&lt;/property&gt;
  &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/security.do?method=getMainMenu&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;property name="siteminderUsernameHeaderKey"&gt;&lt;value&gt;SM_USER&lt;/value&gt;&lt;/property&gt;
  &lt;property name="siteminderPasswordHeaderKey"&gt;&lt;value&gt;SM_USER&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>

        <para>In our example above, the bean is being provided an
        <literal>AuthenticationManager</literal>, as is normally needed by
        authentication mechanisms. Several URLs are also specified, with the
        values being self-explanatory. It's important to also specify the HTTP
        headers that Acegi Security should inspect. Most people won't need the
        password value since Siteminder has already authenticated the user, so
        it's typical to use the same header for both.</para>

        <para>Note that you'll need a
        <literal><literal>DaoAuthenticationProvider</literal></literal>
        configured against your <literal>ProviderManager</literal> in order to
        use the Siteminder authentication mechanism. Normally a
        <literal>DaoAuthenticationProvider</literal> expects the password
        property to match what it retrieves from the
        <literal>UserDetailsSource</literal>. In this case, authentication has
        already been handled by Siteminder and you've specified the same HTTP
        header for both username and password. As such, you must modify the
        code of <literal>DaoAuthenticationProvider</literal> to simply make
        sure the username and password values match. This may sound like a
        security weakness, but remember that users have to authenticate with
        Siteminder before your application ever receives the requests, so the
        purpose of your custom <literal>DaoAuthenticationProvider</literal>
        should simply be to build the complete
        <literal>Authentication</literal> object (ie with suitable
        <literal>GrantedAuthority[]</literal>s).</para>

        <para>Advanced tip and word to the wise: the
        <literal>SiteminderAuthenticationProcessingFilter</literal> actually
        extends <literal>AuthenticationProcessingFilter</literal> and thus
        additionally supports form validation. If you configure the filter to
        support both, and code your
        <literal>daoAuthenticationProvider</literal> to match the username and
        passwords as described above, you'll potentially defeat any security
        you have in place if the web server's Siteminder agent is deactivated.
        Don't do this, especially in production!</para>

        <para>TODO: We should write a dedicated
        <literal>AuthenticationProvider</literal> rather than require users to
        modify their <literal>DaoAuthenticationProvider</literal>. Also review
        the mixed use of SiteminderAuthenticationProcessingFilter, as it's
        inconsistent with the rest of Acegi Security's authentication
        mechanisms which are high cohesion.</para>
      </sect1>
    </chapter>

    <chapter id="runas">
      <title>Run-As Authentication Replacement</title>

      <sect1 id="runas-overview">
        <title>Overview</title>

        <para>The <literal>AbstractSecurityInterceptor</literal> is able to
        temporarily replace the <literal>Authentication</literal> object in
        the <literal>SecurityContext</literal> and
        <literal>SecurityContextHolder</literal> during the secure object
        callback phase. 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 the secure object callback phase, 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>SecurityContextHolder</literal>, these run-as replacements
        are particularly useful when calling remote web services</para>
      </sect1>

      <sect1 id="runas-config">
        <title>Configuration</title>

        <para>A <literal>RunAsManager</literal> interface is provided by Acegi
        Security:</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 Acegi Security. 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="org.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;

&lt;bean id="runAsAuthenticationProvider" class="org.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>
      </sect1>
    </chapter>

    <chapter id="form">
      <title>Form Authentication Mechanism</title>

      <sect1 id="form-overview">
        <title>Overview</title>

        <para>HTTP Form Authentication involves using the
        <literal>AuthenticationProcessingFilter</literal> to process a login
        form. This is the most common way that application authenticate end
        users. Form-based authentication is entirely compatible with the DAO
        and JAAS authentication providers.</para>
      </sect1>

      <sect1 id="form-config">
        <title>Configuration</title>

        <para>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;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;org.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="org.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>SecurityContextHolder</literal>.</para>

        <para>Once the <literal>SecurityContextHolder</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>ExceptionTranslationFilter</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>
      </sect1>
    </chapter>

    <chapter id="basic">
      <title>BASIC Authentication Mechanism</title>

      <sect1 id="basic-overview">
        <title>Overview</title>

        <para>Acegi Security 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>
      </sect1>

      <sect1 id="basic-config">
        <title>Configuration</title>

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

        <para><programlisting>
&lt;bean id="basicProcessingFilter" class="org.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="org.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>SecurityContextHolder</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>
      </sect1>
    </chapter>

    <chapter id="digest">
      <title>Digest Authentication</title>

      <sect1 id="digest-overview">
        <title>Overview</title>

        <para>Acegi Security 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
        weaknesses 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. 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). Whist ever 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 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 immensely 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. Acegi Security
        filters therefore encapsulate all state information into the
        "<literal>nonce</literal>" token instead. In our testing, Acegi
        Security implementation works reliably with FireFox and Internet
        Explorer, correctly handling nonce timeouts etc.</para>
      </sect1>

      <sect1 id="digest-config">
        <title>Configuration</title>

        <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="org.acegisecurity.ui.digestauth.DigestProcessingFilter"&gt;
  &lt;property name="userDetailsService"&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="org.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>UserDetailsService</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>SecurityContextHolder</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, 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, Acegi Security implementation does comply with the minimum
        standards of this RFC.</para>
      </sect1>
    </chapter>

    <chapter id="anonymous">
      <title>Anonymous Authentication</title>

      <sect1 id="anonymous-overview">
        <title>Overview</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>SecurityContextHolder</literal> to identify which principal
        was responsible for a given operation. Such classes can be authored
        with more robustness if they know the
        <literal>SecurityContextHolder</literal> always contains an
        <literal>Authentication</literal> object, and never
        <literal>null</literal>.</para>
      </sect1>

      <sect1 id="anonymous-config">
        <title>Configuration</title>

        <para>Acegi Security provides three classes that together provide an
        anonymous 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>SecurityContextHolder</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="org.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="org.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="org.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>ExceptionTranslationFilter</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>
      </sect1>
    </chapter>

    <chapter id="remember-me">
      <title>Remember-Me Authentication</title>

      <sect1 id="remember-me-overview">
        <title>Overview</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>
      </sect1>

      <sect1 id="remember-me-config">
        <title>Configuration</title>

        <para>Remember-me authentication is not used with basic
        authentication, given it is 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>SecurityContextHolder</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.getUserDetailsService()
password:         That matches the relevant UserDetails retrieved from TokenBasedRememberMeServices.getUserDetailsService()
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 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 A
        UserDetailsService 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="org.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="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"&gt;
  &lt;property name="userDetailsService"&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="org.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>
      </sect1>
    </chapter>

    <chapter id="x509">
      <title>X509 Authentication</title>

      <sect1 id="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. 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>
      </sect1>

      <sect1 id="x509-with-acegi">
        <title>Using 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. A UserDetailsService 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>ExceptionTranslationFilter</classname> will invoke
              the <classname>X509ProcessingFilterEntryPoint</classname> which
              returns a 403 error (forbidden) to the user.</para>
            </listitem>
          </orderedlist></para>
      </sect1>

      <sect1 id="x509-config">
        <title>Configuration</title>

        <para>There is a version of the <link
        linkend="contacts-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>
      </sect1>
    </chapter>

    <chapter id="ldap">
      <title>LDAP Authentication</title>

      <sect1 id="ldap-overview">
        <title>Overview</title>

        <para>LDAP is often used by organizations as a central repository for
        user information and as an authentication service. It can also be used
        to store the role information for application users.</para>

        <para>There are many different scenarios for how an LDAP server may be
        configured so Acegi LDAP provider is fully configurable. It uses
        separate strategy interfaces for authentication and role retrieval and
        provides default implementations which can be configured to handle a
        wide range of situations.</para>

        <para>You should be familiar with LDAP before trying to use it with
        Acegi. The following link provides a good introduction to the concepts
        involved and a guide to setting up a directory using the free LDAP
        server OpenLDAP: <ulink
        url="http://www.zytrax.com/books/ldap/"></ulink>. Some familiarity
        with the JNDI APIs used to access LDAP from Java may also be useful.
        We don't use any third-party LDAP libraries (Mozilla/Netscape, JLDAP
        etc.) in the LDAP provider.</para>
      </sect1>

      <sect1 id="ldap-with-acegi">
        <title>Using LDAP with Acegi Security</title>

        <para>The main LDAP provider class is
        <classname>org.acegisecurity.providers.ldap.LdapAuthenticationProvider</classname>.
        This bean doesn't actually do much itself other than implement the
        <methodname>retrieveUser</methodname> method required by its base
        class,
        <classname>AbstractUserDetailsAuthenticationProvider</classname>. It
        delegates the work to two other beans, an
        <interfacename>LdapAuthenticator</interfacename> and an
        <interfacename>LdapAuthoritiesPopulator</interfacename> which are
        responsible for authenticating the user and retrieving the user's set
        of <interfacename>GrantedAuthority</interfacename>s
        respectively.</para>

        <sect2 id="ldap-ldap-authenticators">
          <title>LdapAuthenticator Implementations</title>

          <para>The authenticator is also responsible for retrieving any
          required user attributes. This is because the permissions on the
          attributes may depend on the type of authentication being used. For
          example, if binding as the user, it may be necessary to read them
          with the user's own permissions.</para>

          <para>There are currently two authentication strategies supplied
          with Acegi Security: <itemizedlist>
              <listitem>
                <para>Authentication directly to the LDAP server ("bind"
                authentication).</para>
              </listitem>

              <listitem>
                <para>Password comparison, where the password supplied by the
                user is compared with the one stored in the repository. This
                can either be done by retrieving the value of the password
                attribute and checking it locally or by performing an LDAP
                "compare" operation, where the supplied password is passed to
                the server for comparison and the real password value is never
                retrieved.</para>
              </listitem>
            </itemizedlist></para>

          <sect3 id="ldap-ldap-authenticators-common">
            <title>Common Functionality</title>

            <para>Before it is possible to authenticate a user (by either
            strategy), the distinguished name (DN) has to be obtained from the
            login name supplied to the application. This can be done either by
            simple pattern-matching (by setting the
            <property>setUserDnPatterns</property> array property) or by
            setting the <property>userSearch</property> property. For the DN
            pattern-matching approach, a standard Java pattern format is used,
            and the login name will be substituted for the parameter
            <parameter>{0}</parameter>. The pattern should be relative to the
            DN that the configured
            <interfacename>InitialDirContextFactory</interfacename> will bind
            to (see the section on <link
            linkend="ldap-dircontextfactory">connecting to the LDAP
            server</link> for more information on this). For example, if you
            are using an LDAP server specified by the URL
            <literal>ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org</literal>,
            and have a pattern <literal>uid={0},ou=greatapes</literal>, then a
            login name of "gorilla" will map to a DN
            <literal>uid=gorilla,ou=greatapes,dc=acegisecurity,dc=org</literal>.
            Each configured DN pattern will be tried in turn until a match is
            found. For information on using a search, see the section on <link
            linkend="ldap-searchobjects">search objects</link> below. A
            combination of the two approaches can also be used - the patterns
            will be checked first and if no matching DN is found, the search
            will be used.</para>
          </sect3>

          <sect3 id="ldap-ldap-authenticators-bind">
            <title>BindAuthenticator</title>

            <para>The class
            <classname>org.acegisecurity.providers.ldap.authenticator.BindAuthenticator</classname>
            implements the bind authentication strategy. It simply attempts to
            bind as the user.</para>
          </sect3>

          <sect3 id="ldap-ldap-authenticators-password">
            <title>PasswordComparisonAuthenticator</title>

            <para>The class
            <classname>org.acegisecurity.providers.ldap.authenticator.PasswordComparisonAuthenticator</classname>
            implements the password comparison authentication strategy.</para>
          </sect3>

          <sect3 id="ldap-ldap-authenticators-active-directory">
            <title>Active Directory Authentication</title>

            <para>In addition to standard LDAP authentication (binding with a
            DN), Active Directory has its own non-standard syntax for user
            authentication.</para>
          </sect3>
        </sect2>

        <sect2 id="ldap-dircontextfactory">
          <title>Connecting to the LDAP Server</title>

          <para>The beans discussed above have to be able to connect to the
          server. They both have to be supplied with an
          <interfacename>InitialDirContextFactory</interfacename> instance.
          Unless you have special requirements, this will usually be a
          <classname>DefaultInitialDirContextFactory</classname> bean, which
          can be configured with the URL of your LDAP server and optionally
          with the username and password of a "manager" user which will be
          used by default when binding to the server (instead of binding
          anonymously). It currently supports "simple" LDAP
          authentication.</para>

          <para><classname>DefaultInitialDirContextFactory</classname> uses
          Sun's JNDI LDAP implementation by default (the one that comes with
          the JDK). It also supports the built in connection pooling offered
          by Sun's provider. Connections which are obtained either anonymously
          or with the "manager" user's identity will be pooled automatically.
          Connections obtained with a specific user's identity will not be
          pooled. Connection pooling can be disabled completely by setting the
          <property>useConnectionPool</property> property to false.</para>

          <para>See the <ulink
          url="http://acegisecurity.org/multiproject/acegi-security/xref/org/acegisecurity/providers/ldap/DefaultInitialDirContextFactory.html">class
          Javadoc and source</ulink> for more information on this bean and its
          properties.</para>
        </sect2>

        <sect2 id="ldap-searchobjects">
          <title>LDAP Search Objects</title>

          <para>Often more a more complicated strategy than simple DN-matching
          is required to locate a user entry in the directory. This can be
          encapsulated in an <interfacename>LdapUserSearch</interfacename>
          instance which can be supplied to the authenticator implementations,
          for example, to allow them to locate a user. The supplied
          implementation is
          <classname>FilterBasedLdapUserSearch</classname>.</para>

          <sect3 id="ldap-searchobjects-filter">
            <title
            id="ldap-searchobjects-filter-based"><classname>FilterBasedLdapUserSearch</classname></title>

            <para>This bean uses an LDAP filter to match the user object in
            the directory. The process is explained in the Javadoc for the
            corresponding search method on the <ulink
            url="http://java.sun.com/j2se/1.4.2/docs/api/javax/naming/directory/DirContext.html#search(javax.naming.Name,%20java.lang.String,%20java.lang.Object[],%20javax.naming.directory.SearchControls)">JDK
            DirContext class</ulink>. As explained there, the search filter
            can be supplied with parameters. For this class, the only valid
            parameter is <parameter>{0}</parameter> which will be replaced
            with the user's login name.</para>
          </sect3>
        </sect2>
      </sect1>

      <sect1 id="ldap-config">
        <title>Configuration</title>

        <para>There is a version of the <link
        linkend="contacts-sample">Contacts Sample Application</link> which
        uses LDAP. You can copy the beans and filter setup from this as a
        starting point for configuring your own application.</para>

        <para>A typical configuration, using some of the beans we've discussed
        above, might look like this: <programlisting>
    &lt;bean id="initialDirContextFactory" 
            class="org.acegisecurity.ldap.DefaultInitialDirContextFactory"&gt;
      &lt;constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org"/&gt;
      &lt;property name="managerDn"&gt;&lt;value&gt;cn=manager,dc=acegisecurity,dc=org&lt;/value&gt;&lt;/property&gt;
      &lt;property name="managerPassword"&gt;&lt;value&gt;password&lt;/value&gt;&lt;/property&gt;
    &lt;/bean&gt;

    &lt;bean id="userSearch"
            class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch"&gt;
      &lt;constructor-arg index="0"&gt;
        &lt;value&gt;&lt;/value&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg index="1"&gt;
        &lt;value&gt;(uid={0})&lt;/value&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg index="2"&gt;
        &lt;ref local="initialDirContextFactory" /&gt;
      &lt;/constructor-arg&gt;            
      &lt;property name="searchSubtree"&gt;
        &lt;value&gt;true&lt;/value&gt;
      &lt;/property&gt;            
    &lt;/bean&gt;            
            
    &lt;bean id="ldapAuthProvider" 
            class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider"&gt;
      &lt;constructor-arg&gt;
        &lt;bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator"&gt;
           &lt;constructor-arg&gt;&lt;ref local="initialDirContextFactory"/&gt;&lt;/constructor-arg&gt;
           &lt;property name="userDnPatterns"&gt;&lt;list&gt;&lt;value&gt;uid={0},ou=people&lt;/value&gt;&lt;/list&gt;&lt;/property&gt;
        &lt;/bean&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg&gt;
        &lt;bean class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator"&gt;
           &lt;constructor-arg&gt;&lt;ref local="initialDirContextFactory"/&gt;&lt;/constructor-arg&gt;
           &lt;constructor-arg&gt;&lt;value&gt;ou=groups&lt;/value&gt;&lt;/constructor-arg&gt;
           &lt;property name="groupRoleAttribute"&gt;&lt;value&gt;ou&lt;/value&gt;&lt;/property&gt;
        &lt;/bean&gt;
      &lt;/constructor-arg&gt;
    &lt;/bean&gt;
  
          </programlisting> This would set up the provider to access an LDAP
        server with URL
        <literal>ldap://monkeymachine:389/dc=acegisecurity,dc=org</literal>.
        Authentication will be performed by attempting to bind with the DN
        <literal>uid=&lt;user-login-name&gt;,ou=people,dc=acegisecurity,dc=org</literal>.
        After successful authentication, roles will be assigned to the user by
        searching under the DN
        <literal>ou=groups,dc=acegisecurity,dc=org</literal> with the default
        filter <literal>(member=&lt;user's-DN&gt;)</literal>. The role name
        will be taken from the <quote>ou</quote> attribute of each
        match.</para>

        <para>We've also included the configuration for a user search object,
        which uses the filter
        <literal>(uid=&lt;user-login-name&gt;)</literal>. This could be used
        instead of the DN-pattern (or in addition to it), by setting the
        authenticator's <property>userSearch</property> property. The
        authenticator would then call the search object to obtain the correct
        user's DN before attempting to bind as this user.</para>
      </sect1>
    </chapter>

    <chapter id="cas">
      <title>CAS Authentication</title>

      <sect1 id="cas-overview">
        <title>Overview</title>

        <para>JA-SIG produces an enterprise-wide single sign on system known
        as CAS. Unlike other initiatives, JA-SIG's Central Authentication
        Service is open source, widely used, simple to understand, platform
        independent, and supports proxy capabilities. Acegi Security 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.ja-sig.org/products/cas/</literal>. You will need
        to visit this URL to download the CAS Server files. Whilst Acegi
        Security 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>
      </sect1>

      <sect1 id="cas-how-it-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 Acegi Security. The following refers to both CAS
        2.0 (produced by Yale) and CAS 3.0 (produced by JA-SIG), being the
        versions of CAS that Acegi Security 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.</para>

        <para>If you are deploying CAS 2.0, 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 2.0 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 Acegi
        Security <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. Acegi Security will function as a CAS
        client successfully irrespective of the
        <literal>PasswordHandler</literal> you've chosen for your CAS
        server.</para>

        <para>If you are deploying CAS 3.0, you will also need to specify an
        <literal>AuthenticationHandler</literal> in the
        deployerConfigContext.xml included with CAS. The
        <literal>AuthenticationHandler</literal> has a simple method that
        returns a boolean as to whether a given set of Credentials is valid.
        Your <literal>AuthenticationHandler</literal> implementation will need
        to link into some type of backend authentication repository, such as
        an LDAP server or database. CAS itself includes numerous
        <literal>AuthenticationHandler</literal>s out of the box to assist
        with this.</para>

        <para>If you are already running an existing CAS 3.0 server instance,
        you will have already established an
        <literal>AuthenticationHandler</literal>. If you do not already have
        an <literal>AuthenticationHandler</literal>, you might prefer to use
        Acegi Security <literal>CasAuthenticationHandler</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>CasAuthenticationHandler</literal> class on
        your CAS server if you do not wish. Acegi Security will function as a
        CAS client successfully irrespective of the
        <literal>AuthenticationHandler</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 JA-SIG 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
        Acegi Security. 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>ExceptionTranslationFilter</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>ExceptionTranslationFilter</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 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> (or
            <literal>AuthenticationHandler</literal> if using CAS 3.0)
            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 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>UserDetailsService</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>UserDetailsService</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>SecurityContextHolder</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 Acegi Security classes hide much of the complexity.
        Let's now look at how this is configured</para>
      </sect1>

      <sect1 id="cas-server">
        <title>Optional CAS Server Setup</title>

        <para>Acegi Security can even act as the backend which a CAS version
        2.0 or 3.0 server utilises. The configuration approach is described
        below. Of course, if you have an existing CAS environment you might
        just like to use it instead.</para>

        <sect2 id="cas-server-2">
          <title>CAS Version 2.0</title>

          <para>As mentioned above, Acegi Security includes a
          <literal>PasswordHandler</literal> that bridges your existing
          <literal>AuthenticationManager</literal> into CAS 2.0. 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="org.acegisecurity.userdetails.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="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  &lt;property name="userDetailsService"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="authenticationManager" class="org.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="org.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;org.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="cas-server-3">
          <title>CAS Version 3.0</title>

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

          <para>To install, you will need to download and extract the CAS
          server archive. We used version 3.0.4. There will be a
          <literal>/webapp</literal> directory in the root of the deployment.
          Edit the an <literal>deployerConfigContext.xml</literal> so that it
          contains your <literal>AuthenticationManager</literal> as well as
          the <literal>CasAuthenticationHandler</literal>. A sample
          <literal>applicationContext.xml</literal> is included below:</para>

          <programlisting>
	&lt;?xml version="1.0" encoding="UTF-8"?&gt;
	&lt;!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
	&lt;beans&gt;
		&lt;bean
			id="authenticationManager"
			class="org.jasig.cas.authentication.AuthenticationManagerImpl"&gt;
			&lt;property name="credentialsToPrincipalResolvers"&gt;
				&lt;list&gt;
					&lt;bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" /&gt;
					&lt;bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" /&gt;
				&lt;/list&gt;
			&lt;/property&gt;
	
			&lt;property name="authenticationHandlers"&gt;
				&lt;list&gt;
					&lt;bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" /&gt;
					&lt;bean class="org.acegisecurity.adapters.cas3.CasAuthenticationHandler"&gt;
						&lt;property name="authenticationManager" ref="acegiAuthenticationManager" /&gt;
					&lt;/bean&gt;
				&lt;/list&gt;
			&lt;/property&gt;
		&lt;/bean&gt;
		
		
		&lt;bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.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="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
	     	&lt;property name="userDetailsService"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
		&lt;/bean&gt;
	
		&lt;bean id="acegiAuthenticationManager" class="org.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;/beans&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>Copy Acegi<literal>-security.jar</literal> file into
          <literal>/localPlugins/lib</literal>. Now use the <literal>ant
          war</literal> task in the <literal>build.xml</literal> in the
          /localPlugins directory. This will create
          <literal>/localPlugins/target/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
          CAS documentation on setting up SSL:
          <literal>http://www.ja-sig.org/products/cas/server/ssl/index.html</literal></para>
        </sect2>
      </sect1>

      <sect1 id="cas-client">
        <title>Configuration of CAS Client</title>

        <para>The web application side of CAS is made easy due to Acegi
        Security. It is assumed you already know the basics of using Acegi
        Security, 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="org.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="org.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="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt;
  &lt;property name="authenticationEntryPoint"&gt;&lt;ref local="casProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
&lt;/bean&gt;          

&lt;bean id="casProcessingFilterEntryPoint" class="org.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;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;org.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>ExceptionTranslationFilter</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="org.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="org.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="org.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="org.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="org.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
  &lt;property name="userDetailsService"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="casProxyDecider" class="org.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 Acegi Security 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>
      </sect1>

      <sect1 id="cas-advanced">
        <title>Advanced Issues</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 Acegi
        Security classes. Welcome to enterprise-wide single sign on!</para>
      </sect1>
    </chapter>

    <chapter id="ca">
      <title>Container Adapter Authentication</title>

      <sect1 id="ca-overview">
        <title>Overview</title>

        <para>Very early versions of Acegi Security exclusively used Container
        Adapters for interfacing authentication with end users. Whilst this
        worked well, it required considerable time to support multiple
        container versions and the configuration itself was relatively
        time-consuming for developers. For this reason the HTTP Form
        Authentication and HTTP Basic Authentication approaches were
        developed, and are today recommended for almost all
        applications.</para>

        <para>Container Adapters enable Acegi Security to integrate directly
        with the containers used to host end user applications. This
        integration means that applications can continue to leverage the
        authentication and authorization capabilities built into containers
        (such as <literal>isUserInRole()</literal> and form-based or basic
        authentication), whilst benefiting from the enhanced security
        interception capabilities provided by Acegi Security (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 Acegi Security is
        achieved through an adapter. The adapter provides a
        container-compatible user authentication provider, and needs to return
        a container-compatible user object.</para>

        <para>The adapter is instantiated by the container and is defined in a
        container-specific configuration file. The adapter then loads a Spring
        application context which defines the normal authentication manager
        settings, such as the authentication providers that can be used to
        authenticate the request. The application context is usually named
        <literal>acegisecurity.xml</literal> and is placed in a
        container-specific location.</para>

        <para>Acegi Security currently supports Jetty, Catalina (Tomcat),
        JBoss and Resin. Additional container adapters can easily be
        written</para>
      </sect1>

      <sect1 id="ca-adapter">
        <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="org.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>SecurityContext</literal> in the
        <literal>SecurityContextHolder</literal> will be tested by the
        application's <literal>AuthByAdapterProvider</literal>. There is no
        requirement for additional authentication providers such as
        <literal>DaoAuthenticationProvider</literal> within the
        application-specific application context, as the only type of
        <literal>Authentication</literal> instance that will be presented by
        the application is from the container adapter.</para>

        <para>Classloader issues are frequent with containers and the use of
        container adapters illustrates this further. Each container requires a
        very specific configuration. The installation instructions are
        provided below. Once installed, please take the time to try the sample
        application to ensure your container adapter is properly
        configured.</para>

        <para>When using container adapters with the
        <literal>DaoAuthenticationProvider</literal>, ensure you set its
        <literal>forcePrincipalAsString</literal> property to
        <literal>true</literal>.</para>
      </sect1>

      <sect1 id="ca-jetty">
        <title>Jetty</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
        <literal>addRealm</literal> call:</para>

        <para><programlisting>
  &lt;Call name="addRealm"&gt;
    &lt;Arg&gt;
      &lt;New class="org.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>
      </sect1>

      <sect1 id="ca-jboss">
        <title>JBoss</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 = "org.acegisecurity.adapters.jboss.JbossAcegiLoginModule"
        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 = "org.acegisecurity.adapters.jboss.JbossAcegiLoginModule"
        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>

        <para>JBoss is a widely-used container adapter (mostly due to the need
        to support legacy EJBs), so please let us know if you have any
        difficulties.</para>
      </sect1>

      <sect1 id="ca-resin">
        <title>Resin</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;org.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>
      </sect1>

      <sect1 id="ca-tomcat">
        <title>Tomcat</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="org.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>

        <para>Finally, restart Tomcat.</para>
      </sect1>
    </chapter>
  </part>

  <part id="authorization">
    <title>Authorization</title>

    <partintro>
      <para>The advanced authorization capabilities within Acegi Security
      represent one of the most compelling reasons for its popularity.
      Irrespective of how you choose to authenticate - whether using an Acegi
      Security-provided mechanism and provider, or integrating with a
      container or other non-Acegi Security authentication authority - you
      will find the authorization services can be used within your application
      in a consistent and simple way.</para>

      <para>In this part we'll explore the different
      <literal>AbstractSecurityInterceptor</literal> implementations, which
      were introduced in Part I. We then move on to explore how to fine-tune
      authorization through use of domain access control lists.</para>
    </partintro>

    <chapter id="authorization-common">
      <title>Common Authorization Concepts</title>

      <sect1 id="authorities">
        <title>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>Acegi Security 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>
      </sect1>

      <sect1 id="pre-invocation">
        <title>Pre-Invocation Handling</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>

        <para>Whilst users can implement their own
        <literal>AccessDecisionManager</literal> to control all aspects of
        authorization, Acegi Security 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 Acegi Security
        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 Acegi Security. 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><literal>BasicAclEntryVoter</literal> 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="org.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="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="aclContactDeleteVoter" class="org.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="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="org.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 Acegi Security 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>

        <para>TODO: Remove references to the old ACL package when it's
        deprecated, and have all references to the replacement package limited
        to the chapter describing the new ACL implementation.</para>
      </sect1>

      <sect1 id="after-invocation">
        <title>After Invocation Handling</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 id="after-invocation-acl-aware">
          <title>ACL-Aware AfterInvocationProviders</title>

          <para>TODO: This section will be removed when we deprecate the
          existing ACL package. It should be discussed with the context of the
          ACL implementation chapter instead.</para>

          <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="org.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="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="org.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="org.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="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
      &lt;ref local="org.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="authorization-taglibs">
        <title>Authorization Tag Libraries</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>if
        AnyGranted</literal>.</para>

        <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 to
        the ACL section of this reference guide to understand more about the
        ACL capabilities of Acegi Security</para>
      </sect1>
    </chapter>

    <chapter id="secure-object-impls">
      <title>Secure Object Implementations</title>

      <sect1 id="aop-alliance">
        <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>

        <programlisting>&lt;bean id="bankManagerSecurity" class="org.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;
      org.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
      org.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;        </programlisting>

        <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 or Java 5 Annotations.
        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 you are using the Jakarta Commons Attributes approach, your
        bean context will be configured differently:</para>

        <programlisting>&lt;bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/&gt;
&lt;bean id="objectDefinitionSource" class="org.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="org.acegisecurity.intercept.method.aopalliance.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>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>

        <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>If you are using the Acegi Security Java 5 Annotations approach,
        your bean context will be configured as follows:</para>

        <programlisting>&lt;bean id="attributes" class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/&gt;
&lt;bean id="objectDefinitionSource" class="org.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="org.acegisecurity.intercept.method.aopalliance.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>In addition, your source code will contain Acegi Java 5 Security
        Annotations that represent the <literal>ConfigAttribute</literal>. The
        following example uses the <literal>@Secured</literal> annotations to
        represent the configuration attributes, and results in the same
        security configuration as provided by the property editor
        approach:</para>

        <programlisting>import org.acegisecurity.annotation.Secured;

public interface BankManager {

    /**
     * Delete something
     */
    @Secured({"ROLE_SUPERVISOR","RUN_AS_SERVER" })
    public void deleteSomething(int id);

    /**
     * Delete another
     */
    @Secured({"ROLE_SUPERVISOR","RUN_AS_SERVER" })
    public void deleteAnother(int id);

    /**
     * Get balance
     */
    @Secured({"ROLE_TELLER","ROLE_SUPERVISOR","BANKSECURITY_CUSTOMER","RUN_AS_SERVER" })
    public float getBalance(int id);
}</programlisting>

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

        <para>Please note that when using
        <literal>BeanNameAutoProxyCreator</literal> to create the required
        proxy for security, the configuration must contain the property
        <literal>proxyTargetClass</literal> set to <literal>true</literal>.
        Otherwise, the method passed to
        <literal>MethodSecurityInterceptor.invoke</literal> is the proxy's
        caller, not the proxy's target. Note that this introduces a
        requirement on CGLIB. See an example of using
        <literal>BeanNameAutoProxyCreator</literal> below:</para>

        <programlisting>&lt;bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"&gt;
  &lt;property name="interceptorNames"&gt;
    &lt;list&gt;&lt;value&gt;methodSecurityInterceptor&lt;/value&gt;&lt;/list&gt;
  &lt;/property&gt;
  &lt;property name="beanNames"&gt;
    &lt;list&gt;&lt;value&gt;targetObjectName&lt;/value&gt;&lt;/list&gt;
  &lt;/property&gt;
  &lt;property name="proxyTargetClass" value="true"/&gt;
&lt;/bean&gt;        </programlisting>
      </sect1>

      <sect1 id="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>

        <programlisting>&lt;bean id="bankManagerSecurity" class="org.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;
      org.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
      org.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
    &lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;        </programlisting>

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

        <programlisting>package org.acegisecurity.samples.aspectj;

import org.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor;
import org.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>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>

        <programlisting>
&lt;bean id="domainObjectInstanceSecurityAspect" 
    class="org.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>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>
      </sect1>

      <sect1 id="filter-invocation-authorization">
        <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>FilterSecurityInterceptor</literal>. A typical
        configuration example is provided below:</para>

        <programlisting>&lt;filter&gt;
  &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;targetClass&lt;/param-name&gt;
    &lt;param-value&gt;org.acegisecurity.intercept.web.FilterSecurityInterceptor&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>Notice that the filter is actually a
        <literal>FilterToBeanProxy</literal>. Most of the filters used by
        Acegi Security 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="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt;
  &lt;property name="authenticationEntryPoint"&gt;&lt;ref local="authenticationEntryPoint"/&gt;&lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="authenticationEntryPoint" class="org.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="filterSecurityInterceptor" class="org.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="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 <classname>ExceptionTranslationFilter</classname> provides
        the bridge between Java exceptions and HTTP responses. It is solely
        concerned with maintaining the user interface. This filter does not do
        any actual security enforcement. If an
        <exceptionname>AuthenticationException</exceptionname> is detected,
        the filter will call the AuthenticationEntryPoint to commence the
        authentication process (e.g. a user login).</para>

        <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 Acegi Security:
        <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
        JA-SIG 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><literal>FilterSecurityInterceptor</literal> is responsible for
        handling the security of HTTP resources. Like any other security
        interceptor, it requires a reference to an
        <literal>AuthenticationManager</literal> and an
        <literal>AccessDecisionManager</literal>, which are both 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>

        <programlisting>&lt;bean id="filterInvocationInterceptor" class="org.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>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>
      </sect1>
    </chapter>

    <chapter id="domain-acls">
      <title>Domain Object Security</title>

      <section id="domain-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 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>SecurityContextHolder.getContext().getAuthentication()</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>
      </section>

      <section id="domain-acls-basic">
        <title>Basic ACL Package</title>

        <para>Please note that our Basic ACL services are currently being
        refactored. We expect release 1.1.0 will contain this new code.
        Planned code is already in the Acegi Security Subversion sandbox, so
        please check there if you have a new application requiring ACLs or are
        in the planning stages. The Basic ACL services will be deprecated from
        release 1.1.0.</para>

        <para>The <literal>org.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>org.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>

        <para>Acegi Security 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>org.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 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, 'org.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (2, 'corp.DomainObject:2', 1, 'org.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (3, 'corp.DomainObject:3', 1, 'org.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (4, 'corp.DomainObject:4', 1, 'org.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (5, 'corp.DomainObject:5', 3, 'org.acegisecurity.acl.basic.SimpleAclEntry');
INSERT INTO acl_object_identity VALUES (6, 'corp.DomainObject:6', 3, 'org.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. The
        equivalent Oracle configuration is:</para>

        <para><programlisting>CREATE TABLE ACL_OBJECT_IDENTITY (
     ID number(19,0) not null,
     OBJECT_IDENTITY varchar2(255) NOT NULL,
     PARENT_OBJECT number(19,0),
     ACL_CLASS varchar2(255) NOT NULL,
     primary key (ID)
);
ALTER TABLE ACL_OBJECT_IDENTITY ADD CONTRAINT FK_PARENT_OBJECT foreign key (ID) references ACL_OBJECT_IDENTITY

CREATE SEQUENCE ACL_OBJECT_IDENTITY_SEQ;

CREATE OR REPLACE TRIGGER ACL_OBJECT_IDENTITY_ID
BEFORE INSERT ON ACL_OBJECT_IDENTITY
FOR EACH ROW
BEGIN
  SELECT ACL_OBJECT_IDENTITY_SEQ.NEXTVAL INTO :new.id FROM dual;
END;

CREATE TABLE ACL_PERMISSION (
     ID number(19,0) not null,
     ACL_OBJECT_IDENTITY number(19,0) NOT NULL,
     RECIPIENT varchar2(255) NOT NULL,
     MASK number(19,0) NOT NULL,
     primary key (ID)
);

ALTER TABLE ACL_PERMISSION ADD CONTRAINT UNIQUE_ID_RECIPIENT unique (acl_object_identity, recipient);

CREATE SEQUENCE ACL_PERMISSION_SEQ;

CREATE OR REPLACE TRIGGER ACL_PERMISSION_ID
BEFORE INSERT ON ACL_PERMISSION
FOR EACH ROW
BEGIN
  SELECT ACL_PERMISSION_SEQ.NEXTVAL INTO :new.id FROM dual;
END;

&lt;bean id="basicAclExtendedDao" class="org.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl"&gt;
    &lt;property name="dataSource"&gt;
        &lt;ref bean="dataSource"/&gt;
    &lt;/property&gt;
    &lt;property name="objectPropertiesQuery" value="${acegi.objectPropertiesQuery}"/&gt;
&lt;/bean&gt;

&lt;prop key="acegi.objectPropertiesQuery"&gt;SELECT CHILD.ID, CHILD.OBJECT_IDENTITY, CHILD.ACL_CLASS, PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY FROM acl_object_identity as CHILD LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id WHERE CHILD.object_identity = ?&lt;/prop&gt; </programlisting></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>

        <para>The above figure explains the key relationships between objects
        in the Basic ACL package.</para>
      </section>
    </chapter>
  </part>

  <part id="resources">
    <title>Other Resources</title>

    <partintro>
      <para>In addition to this reference guide, a number of other resources
      exist to help you learn how to use Acegi Security. These resources are
      discussed in this section.</para>
    </partintro>

    <chapter id="sample-apps">
      <title id="samples">Sample Applications</title>

      <sect1 id="contacts-sample">
        <title id="contacts">Contacts</title>

        <para>Included with Acegi Security 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 Subversion, the Contacts sample application
        includes three deployable versions:
        <literal>acegi-security-sample-contacts-filter.war</literal> is
        configured with the HTTP Session Authentication approach.
        Acegi<literal><literal>-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 JA-SIG 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 official release ZIPs.</para>

        <para>To deploy, simply copy the relevant WAR file from Acegi Security
        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 SecurityContextHolder is of type:
          org.acegisecurity.context.SecurityContextImpl</para>

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

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

          <para>Authentication object as a String:
          org.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>FilterSecurityInterceptor</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 Acegi Security
        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="tutorial-sample">
        <title>Tutorial Sample</title>

        <para>Whilst the <link linkend="contacts-sample">Contacts
        Sample</link> is quite advanced in that it illustrates the more
        powerful features of domain object access control lists and so on,
        sometimes you just want to start with a nice basic example. The
        tutorial sample is intended to provide this for you.</para>

        <para>The compiled tutorial is included in the distribution ZIP file,
        ready to be deployed into your web container. Authentication is
        handled by the <link
        linkend="dao-provider">DaoAuthenticationProvider</link>, using the
        <link linkend="in-memory-service">in-memory</link>
        <literal>UserDetailsService</literal> that sources information from
        the <literal>users.properties</literal> file located in the WAR's
        <literal>/WEB-INF</literal> directory. The <link
        linkend="form">form-based</link> authentication mechanism is used,
        with the commonly-used <link linkend="remember-me">remember-me</link>
        authentication provider used to automatically remember the login using
        cookies.</para>

        <para>In terms of authorization, to keep things simple we've
        configured the tutorial to only perform some basic <link
        linkend="filter-invocation-authorization">web filter
        authorization</link>. We've wired two common <link
        linkend="pre-invocation">pre-invocation access decision voters</link>,
        being the <literal>RoleVoter</literal> and
        <literal>AuthenticatedVoter</literal>, such that
        <literal>ROLE_*</literal> configuration attributes and
        <literal>IS_AUTHENTICATED_*</literal> configuration attributes may be
        used. Of course, it's extremely easy to add in other providers, with
        most users probably starting with some services-layer security using
        <link linkend="aop-alliance">MethodSecurityInterceptor</link>.</para>

        <para>We recommend you start with the tutorial sample, as the XML is
        minimal and easy to follow. All of the needed <link
        linkend="filters">filters</link> are configured properly, and using
        best practise. Most importantly, you can easily this one XML file (and
        its corresponding <literal>web.xml</literal> entries) to your existing
        application. Only when this basic integration is achieved do we
        suggest you attempt adding in method authorization or domain object
        security.</para>
      </sect1>
    </chapter>

    <chapter id="community">
      <title>Community Support</title>

      <sect1 id="jira">
        <title>Use JIRA for Issue Tracking</title>

        <para>Acegi Security uses JIRA to manage bug reports and enhancement
        requests. If you find a bug, please log a report using JIRA. Do not
        log it on the support forum, mailing list or by emailing the project's
        developers. Such approaches are ad-hoc and we prefer to manage bugs
        using a more formal process.</para>

        <para>If possible, in your JIRA report please provide a JUnit test
        that demonstrates any incorrect behaviour. Or, better yet, provide a
        patch that corrects the issue. Similarly, enhancements are welcome to
        be logged in JIRA, although we only accept commit enhancement requests
        if you include corresponding unit tests. This is necessary to ensure
        project test coverage is adequately maintained.</para>

        <para>You can access JIRA at <ulink
        url="http://opensource.atlassian.com/projects/spring/secure/BrowseProject.jspa?id=10040"></ulink>.</para>
      </sect1>

      <sect1 id="becoming-involved">
        <title>Becoming Involved</title>

        <para>We welcome you to become involved in Acegi Security 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, developing
        samples or tutorials, or simply making suggestions.</para>

        <para>Please read our project policies web page that is available on
        Acegi Security home page. This explains the path to become a
        committer, and the administration approaches we use within the
        project.</para>
      </sect1>

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

        <para>Questions and comments on Acegi Security are welcome. Please use
        the Spring Community Forum web site at <ulink
        url="http://forum.springframework.org"></ulink> for all support
        issues. Remember to use JIRA for bug reports, as explained above.
        Everyone is also welcome to join the Acegisecurity-developer mailing
        list and participate in design discussions. It's also a good way of
        finding out what's happening with regard to release timing, and the
        traffic volume is quite light. Finally, our project home page (where
        you can obtain the latest release of the project and convenient links
        to Subversion, JIRA, mailing lists, forums etc) is at <ulink
        url="http://acegisecurity.org"></ulink>.</para>
      </sect1>
    </chapter>
  </part>
</book>