Browse Source

Migrated reference docs to maven

Carlos Sanchez 21 năm trước cách đây
mục cha
commit
ef3cefee53
65 tập tin đã thay đổi với 4862 bổ sung0 xóa
  1. BIN
      docbook/images/admons/blank.png
  2. BIN
      docbook/images/admons/caution.gif
  3. BIN
      docbook/images/admons/caution.png
  4. BIN
      docbook/images/admons/caution.tif
  5. BIN
      docbook/images/admons/draft.png
  6. BIN
      docbook/images/admons/home.gif
  7. BIN
      docbook/images/admons/home.png
  8. BIN
      docbook/images/admons/important.gif
  9. BIN
      docbook/images/admons/important.png
  10. BIN
      docbook/images/admons/important.tif
  11. BIN
      docbook/images/admons/next.gif
  12. BIN
      docbook/images/admons/next.png
  13. BIN
      docbook/images/admons/note.gif
  14. BIN
      docbook/images/admons/note.png
  15. BIN
      docbook/images/admons/note.tif
  16. BIN
      docbook/images/admons/prev.gif
  17. BIN
      docbook/images/admons/prev.png
  18. BIN
      docbook/images/admons/tip.gif
  19. BIN
      docbook/images/admons/tip.png
  20. BIN
      docbook/images/admons/tip.tif
  21. BIN
      docbook/images/admons/toc-blank.png
  22. BIN
      docbook/images/admons/toc-minus.png
  23. BIN
      docbook/images/admons/toc-plus.png
  24. BIN
      docbook/images/admons/up.gif
  25. BIN
      docbook/images/admons/up.png
  26. BIN
      docbook/images/admons/warning.gif
  27. BIN
      docbook/images/admons/warning.png
  28. BIN
      docbook/images/admons/warning.tif
  29. BIN
      docbook/images/callouts/1.gif
  30. BIN
      docbook/images/callouts/1.png
  31. BIN
      docbook/images/callouts/10.gif
  32. BIN
      docbook/images/callouts/10.png
  33. BIN
      docbook/images/callouts/11.gif
  34. BIN
      docbook/images/callouts/11.png
  35. BIN
      docbook/images/callouts/12.gif
  36. BIN
      docbook/images/callouts/12.png
  37. BIN
      docbook/images/callouts/13.gif
  38. BIN
      docbook/images/callouts/13.png
  39. BIN
      docbook/images/callouts/14.gif
  40. BIN
      docbook/images/callouts/14.png
  41. BIN
      docbook/images/callouts/15.gif
  42. BIN
      docbook/images/callouts/15.png
  43. BIN
      docbook/images/callouts/2.gif
  44. BIN
      docbook/images/callouts/2.png
  45. BIN
      docbook/images/callouts/3.gif
  46. BIN
      docbook/images/callouts/3.png
  47. BIN
      docbook/images/callouts/4.gif
  48. BIN
      docbook/images/callouts/4.png
  49. BIN
      docbook/images/callouts/5.gif
  50. BIN
      docbook/images/callouts/5.png
  51. BIN
      docbook/images/callouts/6.gif
  52. BIN
      docbook/images/callouts/6.png
  53. BIN
      docbook/images/callouts/7.gif
  54. BIN
      docbook/images/callouts/7.png
  55. BIN
      docbook/images/callouts/8.gif
  56. BIN
      docbook/images/callouts/8.png
  57. BIN
      docbook/images/callouts/9.gif
  58. BIN
      docbook/images/callouts/9.png
  59. BIN
      docbook/images/logo.gif
  60. BIN
      docbook/images/logo.psd
  61. 4016 0
      docbook/index.xml
  62. 488 0
      docbook/styles/fo/docbook.xsl
  63. 168 0
      docbook/styles/html.css
  64. 94 0
      docbook/styles/html.xsl
  65. 96 0
      docbook/styles/html_chunk.xsl

BIN
docbook/images/admons/blank.png


BIN
docbook/images/admons/caution.gif


BIN
docbook/images/admons/caution.png


BIN
docbook/images/admons/caution.tif


BIN
docbook/images/admons/draft.png


BIN
docbook/images/admons/home.gif


BIN
docbook/images/admons/home.png


BIN
docbook/images/admons/important.gif


BIN
docbook/images/admons/important.png


BIN
docbook/images/admons/important.tif


BIN
docbook/images/admons/next.gif


BIN
docbook/images/admons/next.png


BIN
docbook/images/admons/note.gif


BIN
docbook/images/admons/note.png


BIN
docbook/images/admons/note.tif


BIN
docbook/images/admons/prev.gif


BIN
docbook/images/admons/prev.png


BIN
docbook/images/admons/tip.gif


BIN
docbook/images/admons/tip.png


BIN
docbook/images/admons/tip.tif


BIN
docbook/images/admons/toc-blank.png


BIN
docbook/images/admons/toc-minus.png


BIN
docbook/images/admons/toc-plus.png


BIN
docbook/images/admons/up.gif


BIN
docbook/images/admons/up.png


BIN
docbook/images/admons/warning.gif


BIN
docbook/images/admons/warning.png


BIN
docbook/images/admons/warning.tif


BIN
docbook/images/callouts/1.gif


BIN
docbook/images/callouts/1.png


BIN
docbook/images/callouts/10.gif


BIN
docbook/images/callouts/10.png


BIN
docbook/images/callouts/11.gif


BIN
docbook/images/callouts/11.png


BIN
docbook/images/callouts/12.gif


BIN
docbook/images/callouts/12.png


BIN
docbook/images/callouts/13.gif


BIN
docbook/images/callouts/13.png


BIN
docbook/images/callouts/14.gif


BIN
docbook/images/callouts/14.png


BIN
docbook/images/callouts/15.gif


BIN
docbook/images/callouts/15.png


BIN
docbook/images/callouts/2.gif


BIN
docbook/images/callouts/2.png


BIN
docbook/images/callouts/3.gif


BIN
docbook/images/callouts/3.png


BIN
docbook/images/callouts/4.gif


BIN
docbook/images/callouts/4.png


BIN
docbook/images/callouts/5.gif


BIN
docbook/images/callouts/5.png


BIN
docbook/images/callouts/6.gif


BIN
docbook/images/callouts/6.png


BIN
docbook/images/callouts/7.gif


BIN
docbook/images/callouts/7.png


BIN
docbook/images/callouts/8.gif


BIN
docbook/images/callouts/8.png


BIN
docbook/images/callouts/9.gif


BIN
docbook/images/callouts/9.png


BIN
docbook/images/logo.gif


BIN
docbook/images/logo.psd


+ 4016 - 0
docbook/index.xml

@@ -0,0 +1,4016 @@
+<?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">
+
+<book>
+  <bookinfo>
+    <title>Acegi Security System for Spring</title>
+
+    <subtitle>Reference Documentation</subtitle>
+
+    <releaseinfo>0.7</releaseinfo>
+
+    <authorgroup>
+      <author>
+        <firstname>Ben</firstname>
+
+        <surname>Alex</surname>
+      </author>
+    </authorgroup>
+  </bookinfo>
+
+  <toc></toc>
+
+  <preface id="preface">
+    <title>Preface</title>
+
+    <para>This document provides a reference guide to the Acegi Security
+    System for Spring, which is a series of classes that deliver
+    authentication and authorization services within the Spring
+    Framework.</para>
+
+    <para>I would like to acknowledge this reference was prepared using the
+    DocBook configuration included with the Spring Framework. The Spring team
+    in turn acknowledge Chris Bauer (Hibernate) for his assistance with their
+    DocBook.</para>
+  </preface>
+
+  <chapter id="security">
+    <title>Security</title>
+
+    <sect1 id="security-before-you-begin">
+      <title>Before You Begin</title>
+
+      <para>For your security, each official release JAR of Acegi Security has
+      been signed by the project leader. This does not in any way alter the
+      liability disclaimer contained in the License, but it does ensure you
+      are using a properly reviewed, official build of Acegi Security. Please
+      refer to the <literal>readme.txt</literal> file in the root of the
+      release distribution for instructions on how to validate the JARs are
+      correctly signed, and which certificate has been used to sign
+      them.</para>
+    </sect1>
+
+    <sect1 id="security-introduction">
+      <title>Introduction</title>
+
+      <para>The Acegi Security System for Spring provides authentication and
+      authorization capabilities for Spring-powered projects, with full
+      integration with popular web containers. The security architecture was
+      designed from the ground up using "The Spring Way" of development, which
+      includes using bean contexts, interceptors and interface-driven
+      programming. As a consequence, the Acegi Security System for Spring is
+      useful out-of-the-box for those seeking to secure their Spring-based
+      applications, and can be easily adapted to complex customized
+      requirements.</para>
+
+      <para>Security involves two distinct operations, authentication and
+      authorization. The former relates to resolving whether or not a caller
+      is who they claim to be. Authorization on the other hand relates to
+      determining whether or not an authenticated caller is permitted to
+      perform a given operation.</para>
+
+      <para>Throughout the Acegi Security System for Spring, the user, system
+      or agent that needs to be authenticated is referred to as a "principal".
+      The security architecture does not have a notion of roles or groups,
+      which you may be familiar with from other security
+      implementations.</para>
+
+      <sect2 id="security-introduction-status">
+        <title>Current Status</title>
+
+        <para>The Acegi Security System for Spring is widely used by members
+        of the Spring Community. The APIs are considered stable and only minor
+        changes are expected. Having said that, like many other projects we
+        need to strike a balance between backward compatibility and
+        improvement. Effective version 0.6.1, Acegi Security uses the Apache
+        Portable Runtime Project versioning guidelines, available from
+        <literal>http://apr.apache.org/versioning.html</literal>.</para>
+
+        <para>Some improvements are currently intended prior to the 1.0.0
+        release. These are:</para>
+
+        <itemizedlist spacing="compact">
+          <listitem>
+            <para>Replacing the Ant build with a Maven build. When this
+            happens the <literal>lib</literal> directory will no longer be
+            distributed in ZIP releases or hosted in CVS.</para>
+          </listitem>
+
+          <listitem>
+            <para>"Remember me" functionality. Some discussion on this can be
+            found at
+            <literal>http://sourceforge.net/mailarchive/forum.php?thread_id=5177499&amp;forum_id=40659</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>A sample web application which demonstrates the access
+            control list package.</para>
+          </listitem>
+
+          <listitem>
+            <para>Implementation of an
+            <literal>ObjectDefinitionSource</literal> that retrieves its
+            details from a database.</para>
+          </listitem>
+
+          <listitem>
+            <para>Deprecation of Acegi Security's various EH-CACHE-based cache
+            implementations. Instead Acegi Security will provide new cache
+            implementations which use Spring Framework's new (currently in
+            CVS) <literal>EhCacheManagerFactoryBean</literal> factory. The
+            deprecated classes may be removed from the 1.0.0 release.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Whilst this list is subject to change and not in any particular
+        order, none of the above improvements are likely to result in changes
+        to the API. The improvements are also relatively minor to implement.
+        Users of Acegi Security System for Spring should therefore be
+        comfortable depending on the current version of the project in their
+        applications.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-high-level-design">
+      <title>High Level Design</title>
+
+      <sect2 id="security-high-level-design-key-components">
+        <title>Key Components</title>
+
+        <para>The Acegi Security System for Spring essentially comprises seven
+        key functional parts:</para>
+
+        <itemizedlist spacing="compact">
+          <listitem>
+            <para>An <literal>Authentication</literal> object which holds the
+            principal, credentials and the authorities granted to the
+            principal. The object can also store additional information
+            associated with an authentication request, such as the source
+            TCP/IP address.</para>
+          </listitem>
+
+          <listitem>
+            <para>A <literal>ContextHolder</literal> which holds the
+            <literal>Authentication</literal> object in a
+            <literal>ThreadLocal</literal>-bound object.</para>
+          </listitem>
+
+          <listitem>
+            <para>An <literal>AuthenticationManager</literal> to authenticate
+            the <literal>Authentication</literal> object presented via the
+            <literal>ContextHolder</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>An <literal>AccessDecisionManager</literal> to authorize a
+            given operation.</para>
+          </listitem>
+
+          <listitem>
+            <para>A <literal>RunAsManager</literal> to optionally replace the
+            <literal>Authentication</literal> object whilst a given operation
+            is being executed.</para>
+          </listitem>
+
+          <listitem>
+            <para>A "secure object" interceptor, which coordinates the
+            authentication, authorization, run-as replacement and execution of
+            a given operation.</para>
+          </listitem>
+
+          <listitem>
+            <para>An acess control list (ACL) management package, which can be
+            used to obtain ACLs for domain object instances.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Secure objects refer to any type of object that can have
+        security applied to it. A secure object must provide some form of
+        callback, so that the security interceptor can transparently do its
+        work as required, and callback the object when it is time for it to
+        proceed with the requested operation. If secure objects cannot provide
+        a native callback approach, a wrapper needs to be written so this
+        becomes possible.</para>
+
+        <para>Each secure object has its own package under
+        <literal>net.sf.acegisecurity.intercept</literal>. Every other package
+        in the security system is secure object independent, in that it can
+        support any type of secure object presented.</para>
+
+        <para>Only developers contemplating an entirely new way of
+        intercepting and authorizing requests would need to use secure objects
+        directly. For example, it would be possible to build a new secure
+        object to secure calls to a messaging system that does not use
+        <literal>MethodInvocation</literal>s. Most Spring applications will
+        simply use the three currently supported secure object types
+        (<literal>MethodInvocation</literal>, <literal>JoinPoint</literal> and
+        <literal>FilterInterceptor</literal>) with complete
+        transparency.</para>
+
+        <para>Each of the seven key parts is discussed in detail throughout
+        this document.</para>
+      </sect2>
+
+      <sect2 id="security-high-level-design-supported-secure-objects">
+        <title>Supported Secure Objects</title>
+
+        <para>The Acegi Security System for Spring currently supports three
+        secure objects.</para>
+
+        <para>The first handles an AOP Alliance
+        <literal>MethodInvocation</literal>. This is the secure object type
+        used to protect Spring beans. Developers will generally use this
+        secure object type to secure their business objects. To make a
+        standard Spring-hosted bean available as a
+        <literal>MethodInvocation</literal>, the bean is simply published
+        through a <literal>ProxyFactoryBean</literal> or
+        <literal>BeanNameAutoProxyCreator</literal> or
+        <literal>DefaultAdvisorAutoProxyCreator</literal>. Most Spring
+        developers would already be familiar with these due to their use in
+        transactions and other areas of Spring.</para>
+
+        <para>The second type is an AspectJ <literal>JoinPoint</literal>.
+        AspectJ has a particular use in securing domain object instances, as
+        these are most often managed outside the Spring bean container. By
+        using AspectJ, standard constructs such as <literal>new
+        Person();</literal> can be used and full security will be applied to
+        them by Acegi Security. The
+        <literal>AspectJSecurityInterceptor</literal> is still managed by
+        Spring, which creates the aspect singleton and wires it with the
+        appropriate authentication managers, access decision managers and so
+        on.</para>
+
+        <para>The third type is a <literal>FilterInvocation</literal>. This is
+        an object included with the Acegi Security System for Spring. It is
+        created by an included filter and simply wraps the HTTP
+        <literal>ServletRequest</literal>, <literal>ServletResponse</literal>
+        and <literal>FilterChain</literal>. The
+        <literal>FilterInvocation</literal> enables HTTP resources to be
+        secured. Developers do not usually need to understand the mechanics of
+        how this works, because they just add the filters to their
+        <literal>web.xml</literal> and let the security system do its
+        work.</para>
+      </sect2>
+
+      <sect2 id="security-high-level-design-configuration-attributes">
+        <title>Configuration Attributes</title>
+
+        <para>Every secure object can represent an infinite number of
+        individual requests. For example, a
+        <literal>MethodInvocation</literal> can represent the invocation of
+        any method with any arguments, whilst a
+        <literal>FilterInvocation</literal> can represent any HTTP URL.</para>
+
+        <para>The Acegi Security System for Spring needs to record the
+        configuration that applies to each of these possible requests. The
+        security configuration of a request to
+        <literal>BankManager.getBalance(int accountNumber)</literal> needs to
+        be very different from the security configuration of a request to
+        <literal>BankManager.approveLoan(int applicationNumber)</literal>.
+        Similarly, the security configuration of a request to
+        <literal>http://some.bank.com/index.htm</literal> needs to be very
+        different from the security configuration of
+        <literal>http://some.bank.com/manage/timesheet.jsp</literal>.</para>
+
+        <para>To store the various security configurations associated with
+        different requests, a configuration attribute is used. At an
+        implementation level a configuration attribute is represented by the
+        <literal>ConfigAttribute</literal> interface. One concrete
+        implementation of <literal>ConfigAttribute</literal> is provided,
+        <literal>SecurityConfig</literal>, which simply stores a configuration
+        attribute as a <literal>String</literal>.</para>
+
+        <para>The collection of <literal>ConfigAttribute</literal>s associated
+        with a particular request is held in a
+        <literal>ConfigAttributeDefinition</literal>. This concrete class is
+        simply a holder of <literal>ConfigAttribute</literal>s and does
+        nothing special.</para>
+
+        <para>When a request is received by the security interceptor, it needs
+        to determine which configuration attributes apply. In other words, it
+        needs to find the <literal>ConfigAttributeDefinition</literal> which
+        applies to the request. This decision is handled by the
+        <literal>ObjectDefinitionSource</literal> interface. The main method
+        provided by this interface is <literal>public
+        ConfigAttributeDefinition getAttributes(Object object)</literal>, with
+        the <literal>Object</literal> being the secure object. Recall the
+        secure object contains details of the request, so the
+        <literal>ObjectDefinitionSource</literal> implementation will be able
+        to extract the details it requires to lookup the relevant
+        <literal>ConfigAttributeDefinition</literal>.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-request-contexts">
+      <title>Request Contexts</title>
+
+      <sect2 id="security-contexts">
+        <title>Contexts</title>
+
+        <para>Many applications require a way of sharing objects between
+        classes, but without resorting to passing them in method signatures.
+        This is commonly achieved by using a <literal>ThreadLocal</literal>.
+        The Acegi Security System for Spring uses
+        <literal>ThreadLocal</literal> functionality and introduces the
+        concept of "request contexts".</para>
+
+        <para>By placing an object into a request context, that object becomes
+        available to any other object on the current thread of execution. The
+        request context is not passed around as a method parameter, but is
+        held in a <literal>ThreadLocal</literal>. The Acegi Security System
+        for Spring uses the request context to pass around the authentication
+        request and response.</para>
+
+        <para>A request context is a concrete implementation of the
+        <literal>Context</literal> interface, which exposes a single
+        method:</para>
+
+        <programlisting>public void validate() throws ContextInvalidException;</programlisting>
+
+        <para>This <literal>validate()</literal> method is called to confirm
+        the <literal>Context</literal> is properly setup. An implementation
+        will typically use this method to check that the objects it holds are
+        properly setup.</para>
+
+        <para>The <literal>ContextHolder</literal> class makes the
+        <literal>Context</literal> available to the current thread of
+        execution using a <literal>ThreadLocal</literal>. A
+        <literal>ContextInterceptor</literal> is also provided, which is
+        intended to be chained into the bean context using
+        <literal>ProxyFactoryBean</literal>. The
+        <literal>ContextInterceptor</literal> simply calls
+        <literal>Context.validate()</literal>, which guarantees to business
+        methods that a valid <literal>Context</literal> is available from the
+        <literal>ContextHolder</literal>.</para>
+      </sect2>
+
+      <sect2 id="security-contexts-secure-contexts">
+        <title>Secure Contexts</title>
+
+        <para>The Acegi Security System for Spring requires the
+        <literal>ContextHolder</literal> to contain a request context that
+        implements the <literal>SecureContext</literal> interface. An
+        implementation is provided named <literal>SecureContextImpl</literal>.
+        The <literal>SecureContext</literal> simply extends the
+        <literal>Context</literal> discussed above and adds a holder and
+        validation for an <literal>Authentication</literal> object.</para>
+      </sect2>
+
+      <sect2 id="security-contexts-custom-contexts">
+        <title>Custom Contexts</title>
+
+        <para>Developers can create their own request context classes to store
+        application-specific objects. Such request context classes will need
+        to implement the <literal>Context</literal> interface. If the Acegi
+        Security System for Spring is to be used, developers must ensure any
+        custom request contexts implement the <literal>SecureContext</literal>
+        interface.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-interception">
+      <title>Security Interception</title>
+
+      <sect2 id="security-interception-all-secure-objects">
+        <title>All Secure Objects</title>
+
+        <para>As described in the High Level Design section, each secure
+        object has its own security interceptor which is responsible for
+        handling each request. Handling involves a number of
+        operations:</para>
+
+        <orderedlist>
+          <listitem>
+            <para>Store the configuration attributes that are associated with
+            each secure request.</para>
+          </listitem>
+
+          <listitem>
+            <para>Extract the <literal>ConfigAttributeDefinition</literal>
+            that applies to the request from the relevant
+            <literal>ObjectDefinitionSource</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Obtain the <literal>Authentication</literal> object from the
+            <literal>SecureContext</literal>, which is held in the
+            <literal>ContextHolder</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Pass the <literal>Authentication</literal> object to the
+            <literal>AuthenticationManager</literal>, update the
+            <literal>ContextHolder</literal> with the response.</para>
+          </listitem>
+
+          <listitem>
+            <para>Pass the <literal>Authentication</literal> object, the
+            <literal>ConfigAttributeDefinition</literal>, and the secure
+            object to the <literal>AccessDecisionManager</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Pass the <literal>Authentication</literal> object, the
+            <literal>ConfigAttributeDefinition</literal>, and the secure
+            object to the <literal>RunAsManager</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>If the <literal>RunAsManager</literal> returns a new
+            <literal>Authentication</literal> object, update the
+            <literal>ContextHolder</literal> with it.</para>
+          </listitem>
+
+          <listitem>
+            <para>Proceed with the request execution of the secure
+            object.</para>
+          </listitem>
+
+          <listitem>
+            <para>If the <literal>RunAsManager</literal> earlier returned a
+            new <literal>Authentication</literal> object, update the
+            <literal>ContextHolder</literal> with the
+            <literal>Authentication</literal> object that was previously
+            returned by the <literal>AuthenticationManager</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Return any result received from the secure object
+            execution.</para>
+          </listitem>
+        </orderedlist>
+
+        <para>Whilst this may seem quite involved, don't worry. Developers
+        interact with the security process by simply implementing basic
+        interfaces (such as <literal>AccessDecisionManager</literal>), which
+        are fully documented below.</para>
+
+        <para>The <literal>AbstractSecurityInterceptor</literal> handles the
+        majority of the flow listed above. Each secure object has its own
+        security interceptor which subclasses
+        <literal>AbstractSecurityInterceptor</literal>. Each of these secure
+        object-specific security interceptors are discussed below.</para>
+      </sect2>
+
+      <sect2 id="security-interception-aopalliance">
+        <title>AOP Alliance (MethodInvocation) Security Interceptor</title>
+
+        <para>To secure <literal>MethodInvocation</literal>s, developers
+        simply add a properly configured
+        <literal>MethodSecurityInterceptor</literal> into the application
+        context. Next the beans requiring security are chained into the
+        interceptor. This chaining is accomplished using Spring’s
+        <literal>ProxyFactoryBean</literal> or
+        <literal>BeanNameAutoProxyCreator</literal>, as commonly used by many
+        other parts of Spring (refer to the sample application for examples).
+        Alternatively, Acegi Security provides a
+        <literal>MethodDefinitionSourceAdvisor</literal> which may be used
+        with Spring's <literal>DefaultAdvisorAutoProxyCreator</literal> to
+        automatically chain the security interceptor in front of any beans
+        defined against the <literal>MethodSecurityInterceptor</literal>. The
+        <literal>MethodSecurityInterceptor</literal> itself is configured as
+        follows:</para>
+
+        <para><programlisting>&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"&gt;
+  &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
+  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
+  &lt;property name="objectDefinitionSource"&gt;
+    &lt;value&gt;
+      net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
+      net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
+    &lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>As shown above, the <literal>MethodSecurityInterceptor</literal>
+        is configured with a reference to an
+        <literal>AuthenticationManager</literal>,
+        <literal>AccessDecisionManager</literal> and
+        <literal>RunAsManager</literal>, which are each discussed in separate
+        sections below. The <literal>MethodSecurityInterceptor</literal> is
+        also configured with configuration attributes that apply to different
+        method signatures. A full discussion of configuration attributes is
+        provided in the High Level Design section of this document.</para>
+
+        <para>The <literal>MethodSecurityInterceptor</literal> can be
+        configured with configuration attributes in three ways. The first is
+        via a property editor and the application context, which is shown
+        above. The second is via defining the configuration attributes in your
+        source code using Jakarta Commons Attributes. The third is via writing
+        your own <literal>ObjectDefinitionSource</literal>, although this is
+        beyond the scope of this document. Irrespective of the approach used,
+        the <literal>ObjectDefinitionSource</literal> is responsible for
+        returning a <literal>ConfigAttributeDefinition</literal> object that
+        contains all of the configuration attributes associated with a single
+        secure method.</para>
+
+        <para>It should be noted that the
+        <literal>MethodSecurityInterceptor.setObjectDefinitionSource()</literal>
+        method actually expects an instance of
+        <literal>MethodDefinitionSource</literal>. This is a marker interface
+        which subclasses <literal>ObjectDefinitionSource</literal>. It simply
+        denotes the <literal>ObjectDefinitionSource</literal> understands
+        <literal>MethodInvocation</literal>s. In the interests of simplicity
+        we'll continue to refer to the
+        <literal>MethodDefinitionSource</literal> as an
+        <literal>ObjectDefinitionSource</literal>, as the distinction is of
+        little relevance to most users of the
+        <literal>MethodSecurityInterceptor</literal>.</para>
+
+        <para>If using the application context property editor approach (as
+        shown above), commas are used to delimit the different configuration
+        attributes that apply to a given method pattern. Each configuration
+        attribute is assigned into its own <literal>SecurityConfig</literal>
+        object. The <literal>SecurityConfig</literal> object is discussed in
+        the High Level Design section.</para>
+
+        <para>If using the Jakarta Commons Attributes approach, your bean
+        context will be configured differently:</para>
+
+        <para><programlisting>&lt;bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/&gt;
+&lt;bean id="objectDefinitionSource" class="net.sf.acegisecurity.intercept.method.MethodDefinitionAttributes"&gt;
+  &lt;property name="attributes"&gt;&lt;ref local="attributes"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor"&gt;
+  &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
+  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
+  &lt;property name="objectDefinitionSource"&gt;&lt;ref bean="objectDefinitionSource"/&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>In addition, your source code will contain Jakarta Commons
+        Attributes tags that refer to a concrete implementation of
+        <literal>ConfigAttribute</literal>. The following example uses the
+        <literal>SecurityConfig</literal> implementation to represent the
+        configuration attributes, and results in the same security
+        configuration as provided by the property editor approach
+        above:</para>
+
+        <para><programlisting>public interface BankManager {
+
+    /**
+     * @@SecurityConfig("ROLE_SUPERVISOR")
+     * @@SecurityConfig("RUN_AS_SERVER")
+     */
+    public void deleteSomething(int id);
+
+    /**
+     * @@SecurityConfig("ROLE_SUPERVISOR")
+     * @@SecurityConfig("RUN_AS_SERVER")
+     */
+    public void deleteAnother(int id);
+
+    /**
+     * @@SecurityConfig("ROLE_TELLER")
+     * @@SecurityConfig("ROLE_SUPERVISOR")
+     * @@SecurityConfig("BANKSECURITY_CUSTOMER")
+     * @@SecurityConfig("RUN_AS_SERVER")
+     */
+    public float getBalance(int id);
+}</programlisting></para>
+
+        <para>You might have noticed the
+        <literal>validateConfigAttributes</literal> property in the above
+        <literal>MethodSecurityInterceptor</literal> examples. When set to
+        <literal>true</literal> (the default), at startup time the
+        <literal>MethodSecurityInterceptor</literal> will evaluate if the
+        provided configuration attributes are valid. It does this by checking
+        each configuration attribute can be processed by either the
+        <literal>AccessDecisionManager</literal> or the
+        <literal>RunAsManager</literal>. If neither of these can process a
+        given configuration attribute, an exception is thrown. If using the
+        Jakarta Commons Attributes method of configuration, you should set
+        <literal>validateConfigAttributes</literal> to
+        <literal>false</literal>.</para>
+      </sect2>
+
+      <sect2 id="security-interception-aspectj">
+        <title>AspectJ (JoinPoint) Security Interceptor</title>
+
+        <para>The AspectJ security interceptor is very similar to the AOP
+        Alliance security interceptor discussed in the previous section.
+        Indeed we will only discuss the differences in this section.</para>
+
+        <para>The AspectJ interceptor is named
+        <literal>AspectJSecurityInterceptor</literal>. Unlike the AOP Alliance
+        security interceptor, which relies on the Spring application context
+        to weave in the security interceptor via proxying, the
+        <literal>AspectJSecurityInterceptor</literal> is weaved in via the
+        AspectJ compiler. It would not be uncommon to use both types of
+        security interceptors in the same application, with
+        <literal>AspectJSecurityInterceptor</literal> being used for domain
+        object instance security and the AOP Alliance
+        <literal>MethodSecurityInterceptor</literal> being used for services
+        layer security.</para>
+
+        <para>Let's first consider how the
+        <literal>AspectJSecurityInterceptor</literal> is configured in the
+        Spring application context:</para>
+
+        <para><programlisting>&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor"&gt;
+  &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
+  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
+  &lt;property name="objectDefinitionSource"&gt;
+    &lt;value&gt;
+      net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
+      net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
+    &lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>As you can see, aside from the class name, the
+        <literal>AspectJSecurityInterceptor</literal> is exactly the same as
+        the AOP Alliance security interceptor. Indeed the two interceptors can
+        share the same <literal>objectDefinitionSource</literal>, as the
+        <literal>ObjectDefinitionSource</literal> works with
+        <literal>java.lang.reflect.Method</literal>s rather than an AOP
+        library-specific class. Of course, your access decisions have access
+        to the relevant AOP library-specific invocation (ie
+        <literal>MethodInvocation</literal> or <literal>JoinPoint</literal>)
+        and as such can consider a range of addition criteria when making
+        access decisions (such as method arguments).</para>
+
+        <para>Next you'll need to define an AspectJ <literal>aspect</literal>.
+        For example:</para>
+
+        <para><programlisting>package net.sf.acegisecurity.samples.aspectj;
+
+import net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor;
+import net.sf.acegisecurity.intercept.method.aspectj.AspectJCallback;
+import org.springframework.beans.factory.InitializingBean;
+
+public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
+
+  private AspectJSecurityInterceptor securityInterceptor;
+
+  pointcut domainObjectInstanceExecution(): target(PersistableEntity) 
+             &amp;&amp; execution(public * *(..)) &amp;&amp; !within(DomainObjectInstanceSecurityAspect);
+
+  Object around(): domainObjectInstanceExecution() {
+    if (this.securityInterceptor != null) {
+      AspectJCallback callback = new AspectJCallback() {
+        public Object proceedWithObject() {
+        return proceed();
+      }
+    };
+    return this.securityInterceptor.invoke(thisJoinPoint, callback);
+    } else {
+      return proceed();
+    }
+  }
+
+  public AspectJSecurityInterceptor getSecurityInterceptor() {
+    return securityInterceptor;
+  }
+
+  public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) {
+    this.securityInterceptor = securityInterceptor;
+  }
+
+  public void afterPropertiesSet() throws Exception {
+    if (this.securityInterceptor == null)
+      throw new IllegalArgumentException("securityInterceptor required");
+  }
+}</programlisting></para>
+
+        <para>In the above example, the security interceptor will be applied
+        to every instance of <literal>PersistableEntity</literal>, which is an
+        abstract class not shown (you can use any other class or
+        <literal>pointcut</literal> expression you like). For those curious,
+        <literal>AspectJCallback</literal> is needed because the
+        <literal>proceed();</literal> statement has special meaning only
+        within an <literal>around()</literal> body. The
+        <literal>AspectJSecurityInterceptor</literal> calls this anonymous
+        <literal>AspectJCallback</literal> class when it wants the target
+        object to continue.</para>
+
+        <para>You will need to configure Spring to load the aspect and wire it
+        with the <literal>AspectJSecurityInterceptor</literal>. A bean
+        declaration which achieves this is shown below:</para>
+
+        <para><programlisting>&lt;bean id="domainObjectInstanceSecurityAspect" 
+    class="net.sf.acegisecurity.samples.aspectj.DomainObjectInstanceSecurityAspect"
+    factory-method="aspectOf"&gt;
+  &lt;property name="securityInterceptor"&gt;&lt;ref bean="aspectJSecurityInterceptor"/&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>That's it! Now you can create your beans from anywhere within
+        your application, using whatever means you think fit (eg <literal>new
+        Person();</literal>) and they will have the security interceptor
+        applied.</para>
+      </sect2>
+
+      <sect2 id="security-interception-filterinvocation">
+        <title>FilterInvocation Security Interceptor</title>
+
+        <para>To secure <literal>FilterInvocation</literal>s, developers need
+        to add a filter to their <literal>web.xml</literal> that delegates to
+        the <literal>SecurityEnforcementFilter</literal>. A typical
+        configuration example is provided below: <programlisting>&lt;filter&gt;
+  &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
+  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
+  &lt;init-param&gt;
+    &lt;param-name&gt;targetClass&lt;/param-name&gt;
+    &lt;param-value&gt;net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter&lt;/param-value&gt;
+  &lt;/init-param&gt;
+&lt;/filter&gt;
+
+&lt;filter-mapping&gt;
+  &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
+  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+&lt;/filter-mapping&gt;</programlisting></para>
+
+        <para>Notice that the filter is actually a
+        <literal>FilterToBeanProxy</literal>. Most of the filters used by the
+        Acegi Security System for Spring use this class. Refer to the Filters
+        section to learn more about this bean.</para>
+
+        <para>In the application context you will need to configure three
+        beans:</para>
+
+        <programlisting>&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
+  &lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
+  &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;
+  &lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="forceHttps"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
+  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
+  &lt;property name="objectDefinitionSource"&gt;
+    &lt;value&gt;
+      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+      \A/secure/super/.*\Z=ROLE_WE_DONT_HAVE
+      \A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
+    &lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting>
+
+        <para>The <literal>AuthenticationEntryPoint</literal> will be called
+        if the user requests a secure HTTP resource but they are not
+        authenticated. The class handles presenting the appropriate response
+        to the user so that authentication can begin. Three concrete
+        implementations are provided with the Acegi Security System for
+        Spring: <literal>AuthenticationProcessingFilterEntryPoint</literal>
+        for commencing a form-based authentication,
+        <literal>BasicProcessingFilterEntryPoint</literal> for commencing a
+        Http Basic authentication process, and
+        <literal>CasProcessingFilterEntryPoint</literal> for commencing a Yale
+        Central Authentication Service (CAS) login. The
+        <literal>AuthenticationProcessingFilterEntryPoint</literal> and
+        <literal>CasProcessingFilterEntryPoint</literal> have optional
+        properties related to forcing the use of HTTPS, so please refer to the
+        JavaDocs if you require this.</para>
+
+        <para>The <literal>PortMapper</literal> provides information on which
+        HTTPS ports correspond to which HTTP ports. This is used by the
+        <literal>AuthenticationProcessingFilterEntryPoint</literal> and
+        several other beans. The default implementation,
+        <literal>PortMapperImpl</literal>, knows the common HTTP ports 80 and
+        8080 map to HTTPS ports 443 and 8443 respectively. You can customise
+        this mapping if desired.</para>
+
+        <para>The <literal>SecurityEnforcementFilter</literal> primarily
+        provides session management support and initiates authentication when
+        required. It delegates actual <literal>FilterInvocation</literal>
+        security decisions to the configured
+        <literal>FilterSecurityInterceptor</literal>.</para>
+
+        <para>Like any other security interceptor, the
+        <literal>FilterSecurityInterceptor</literal> requires a reference to
+        an <literal>AuthenticationManager</literal>,
+        <literal>AccessDecisionManager</literal> and
+        <literal>RunAsManager</literal>, which are each discussed in separate
+        sections below. The <literal>FilterSecurityInterceptor</literal> is
+        also configured with configuration attributes that apply to different
+        HTTP URL requests. A full discussion of configuration attributes is
+        provided in the High Level Design section of this document.</para>
+
+        <para>The <literal>FilterSecurityInterceptor</literal> can be
+        configured with configuration attributes in two ways. The first is via
+        a property editor and the application context, which is shown above.
+        The second is via writing your own
+        <literal>ObjectDefinitionSource</literal>, although this is beyond the
+        scope of this document. Irrespective of the approach used, the
+        <literal>ObjectDefinitionSource</literal> is responsible for returning
+        a <literal>ConfigAttributeDefinition</literal> object that contains
+        all of the configuration attributes associated with a single secure
+        HTTP URL.</para>
+
+        <para>It should be noted that the
+        <literal>FilterSecurityInterceptor.setObjectDefinitionSource()</literal>
+        method actually expects an instance of
+        <literal>FilterInvocationDefinitionSource</literal>. This is a marker
+        interface which subclasses <literal>ObjectDefinitionSource</literal>.
+        It simply denotes the <literal>ObjectDefinitionSource</literal>
+        understands <literal>FilterInvocation</literal>s. In the interests of
+        simplicity we'll continue to refer to the
+        <literal>FilterInvocationDefinitionSource</literal> as an
+        <literal>ObjectDefinitionSource</literal>, as the distinction is of
+        little relevance to most users of the
+        <literal>FilterSecurityInterceptor</literal>.</para>
+
+        <para>If using the application context property editor approach (as
+        shown above), commas are used to delimit the different configuration
+        attributes that apply to each HTTP URL. Each configuration attribute
+        is assigned into its own <literal>SecurityConfig</literal> object. The
+        <literal>SecurityConfig</literal> object is discussed in the High
+        Level Design section. The <literal>ObjectDefinitionSource</literal>
+        created by the property editor,
+        <literal>FilterInvocationDefinitionSource</literal>, matches
+        configuration attributes against <literal>FilterInvocations</literal>
+        based on expression evaluation of the request URL. Two standard
+        expression syntaxes are supported. The default is to treat all
+        expressions as regular expressions. Alternatively, the presence of a
+        <literal>PATTERN_TYPE_APACHE_ANT</literal> directive will cause all
+        expressions to be treated as Apache Ant paths. It is not possible to
+        mix expression syntaxes within the same definition. For example, the
+        earlier configuration could be generated using Apache Ant paths as
+        follows:</para>
+
+        <para><programlisting>&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
+  &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
+  &lt;property name="objectDefinitionSource"&gt;
+    &lt;value&gt;
+      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+      PATTERN_TYPE_APACHE_ANT
+      /secure/super/**=ROLE_WE_DONT_HAVE
+      /secure/**=ROLE_SUPERVISOR,ROLE_TELLER
+    &lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>Irrespective of the type of expression syntax used, expressions
+        are always evaluated in the order they are defined. Thus it is
+        important that more specific expressions are defined higher in the
+        list than less specific expressions. This is reflected in our example
+        above, where the more specific <literal>/secure/super/</literal>
+        pattern appears higher than the less specific
+        <literal>/secure/</literal> pattern. If they were reversed, the
+        <literal>/secure/</literal> pattern would always match and the
+        <literal>/secure/super/</literal> pattern would never be
+        evaluated.</para>
+
+        <para>The special keyword
+        <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> causes
+        the <literal>FilterInvocationDefinitionSource</literal> to
+        automatically convert a request URL to lowercase before comparison
+        against the expressions. Whilst by default the case of the request URL
+        is not converted, it is generally recommended to use
+        <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> and
+        write each expression assuming lowercase.</para>
+
+        <para>As with other security interceptors, the
+        <literal>validateConfigAttributes</literal> property is observed. When
+        set to <literal>true</literal> (the default), at startup time the
+        <literal>FilterSecurityInterceptor</literal> will evaluate if the
+        provided configuration attributes are valid. It does this by checking
+        each configuration attribute can be processed by either the
+        <literal>AccessDecisionManager</literal> or the
+        <literal>RunAsManager</literal>. If neither of these can process a
+        given configuration attribute, an exception is thrown.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-authentication">
+      <title>Authentication</title>
+
+      <sect2 id="security-authentication-requests">
+        <title>Authentication Requests</title>
+
+        <para>Authentication requires a way for client code to present its
+        security identification to the Acegi Security System for Spring. This
+        is the role of the <literal>Authentication</literal> interface. The
+        <literal>Authentication</literal> interface holds three important
+        objects: the principal (the identity of the caller), the credentials
+        (the proof of the identity of the caller, such as a password), and the
+        authorities that have been granted to the principal. The principal and
+        its credentials are populated by the client code, whilst the granted
+        authorities are populated by the
+        <literal>AuthenticationManager</literal>. The Acegi Security System
+        for Spring includes several concrete <literal>Authentication</literal>
+        implementations:</para>
+
+        <itemizedlist spacing="compact">
+          <listitem>
+            <para><literal>UsernamePasswordAuthenticationToken</literal>
+            allows a username and password to be presented as the principal
+            and credentials respectively. It is also what is created by the
+            HTTP Session Authentication system.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>TestingAuthenticationToken</literal> facilitates
+            unit testing by automatically being considered an authenticated
+            object by its associated
+            <literal>AuthenticationProvider</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>RunAsUserToken</literal> is used by the default
+            run-as authentication replacement implementation. This is
+            discussed further in the Run-As Authentication Replacement
+            section.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>CasAuthenticationToken</literal> is used to
+            represent a successful Yale Central Authentication Service (CAS)
+            authentication. This is discussed further in the CAS
+            section.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>PrincipalAcegiUserToken</literal> and
+            <literal>JettyAcegiUserToken</literal> implement
+            <literal>AuthByAdapter</literal> (a subclass of
+            <literal>Authentication</literal>) and are used whenever
+            authentication is completed by Acegi Security System for Spring
+            container adapters. This is discussed further in the Container
+            Adapters section.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>The authorities granted to a principal are represented by the
+        <literal>GrantedAuthority</literal> interface. The
+        <literal>GrantedAuthority</literal> interface is discussed at length
+        in the Authorization section.</para>
+      </sect2>
+
+      <sect2 id="security-authentication-manager">
+        <title>Authentication Manager</title>
+
+        <para>As discussed in the Security Interception section, the
+        <literal>AbstractSecurityInterceptor</literal> extracts the
+        <literal>Authentication</literal> object from the
+        <literal>SecureContext</literal> in the
+        <literal>ContextHolder</literal>. This is then passed to an
+        <literal>AuthenticationManager</literal>. The
+        <literal>AuthenticationManager</literal> interface is very
+        simple:</para>
+
+        <programlisting>public Authentication authenticate(Authentication authentication) throws AuthenticationException;</programlisting>
+
+        <para>Implementations of <literal>AuthenticationManager</literal> are
+        required to throw an <literal>AuthenticationException</literal> should
+        authentication fail, or return a fully populated
+        <literal>Authentication</literal> object. In particular, the returned
+        <literal>Authentication</literal> object should contain an array of
+        <literal>GrantedAuthority</literal> objects. The
+        <literal>SecurityInterceptor</literal> places the populated
+        <literal>Authentication</literal> object back in the
+        <literal>SecureContext</literal> in the
+        <literal>ContextHolder</literal>, overwriting the original
+        <literal>Authentication</literal> object.</para>
+
+        <para>The <literal>AuthenticationException</literal> has a number of
+        subclasses. The most important are
+        <literal>BadCredentialsException</literal> (an incorrect principal or
+        credentials), <literal>DisabledException</literal> and
+        <literal>LockedException</literal>. The latter two exceptions indicate
+        the principal was found, but the credentials were not checked and
+        authentication is denied. An
+        <literal>AuthenticationServiceException</literal> is also provided,
+        which indicates the authentication system could not process the
+        request (eg a database was unavailable).</para>
+      </sect2>
+
+      <sect2 id="security-authentication-provider">
+        <title>Provider-Based Authentication</title>
+
+        <para>Whilst the basic <literal>Authentication</literal> and
+        <literal>AuthenticationManager</literal> interfaces enable users to
+        develop their own authentication systems, users should consider using
+        the provider-based authentication packages provided by the Acegi
+        Security System for Spring. The key class,
+        <literal>ProviderManager</literal>, is configured via the bean context
+        with a list of <literal>AuthenticationProvider</literal>s:</para>
+
+        <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
+  &lt;property name="providers"&gt;
+    &lt;list&gt;
+      &lt;ref bean="daoAuthenticationProvider"/&gt;
+      &lt;ref bean="someOtherAuthenticationProvider"/&gt;
+    &lt;/list&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para><literal>ProviderManager</literal> calls a series of registered
+        <literal>AuthenticationProvider</literal> implementations, until one
+        is found that indicates it is able to authenticate a given
+        <literal>Authentication</literal> class. When the first compatible
+        <literal>AuthenticationProvider</literal> is located, it is passed the
+        authentication request. The <literal>AuthenticationProvider</literal>
+        will then either throw an <literal>AuthenticationException</literal>
+        or return a fully populated <literal>Authentication</literal>
+        object.</para>
+
+        <para>Note the <literal>ProviderManager</literal> may throw a
+        <literal>ProviderNotFoundException</literal> (a subclass of
+        <literal>AuthenticationException</literal>) if it none of the
+        registered <literal>AuthenticationProviders</literal> can validate the
+        <literal>Authentication</literal> object.</para>
+
+        <para>Several <literal>AuthenticationProvider</literal>
+        implementations are provided with the Acegi Security System for
+        Spring:</para>
+
+        <para><itemizedlist spacing="compact">
+            <listitem>
+              <para><literal>TestingAuthenticationProvider</literal> is able
+              to authenticate a <literal>TestingAuthenticationToken</literal>.
+              The limit of its authentication is simply to treat whatever is
+              contained in the <literal>TestingAuthenticationToken</literal>
+              as valid. This makes it ideal for use during unit testing, as
+              you can create an <literal>Authentication</literal> object with
+              precisely the <literal>GrantedAuthority</literal> objects
+              required for calling a given method. You definitely would not
+              register this <literal>AuthenticationProvider</literal> on a
+              production system.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>DaoAuthenticationProvider</literal> is able to
+              authenticate a
+              <literal>UsernamePasswordAuthenticationToken</literal> by
+              accessing an authentication respository via a data access
+              object. This is discussed further below, as it is the main way
+              authentication is initially handled.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>RunAsImplAuthenticationToken</literal> is able to
+              authenticate a <literal>RunAsUserToken</literal>. This is
+              discussed further in the Run-As Authentication Replacement
+              section. You would not register this
+              <literal>AuthenticationProvider</literal> if you were not using
+              run-as replacement.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>AuthByAdapterProvider</literal> is able to
+              authenticate any <literal>AuthByAdapter</literal> (a subclass of
+              <literal>Authentication</literal> used with container adapters).
+              This is discussed further in the Container Adapters section. You
+              would not register this
+              <literal>AuthenticationProvider</literal> if you were not using
+              container adapters.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>CasAuthenticationProvider</literal> is able to
+              authenticate Yale Central Authentication Service (CAS) tickets.
+              This is discussed further in the CAS Single Sign On
+              section.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>JaasAuthenticationProvider</literal> is able to
+              delegate authentication requests to a JAAS
+              <literal>LoginModule</literal>. This is discussed further
+              below.</para>
+            </listitem>
+          </itemizedlist></para>
+      </sect2>
+
+      <sect2 id="security-authentication-provider-dao">
+        <title>Data Access Object Authentication Provider</title>
+
+        <para>The Acegi Security System for Spring includes a
+        production-quality <literal>AuthenticationProvider</literal>
+        implementation called <literal>DaoAuthenticationProvider</literal>.
+        This authentication provider is able to authenticate a
+        <literal>UsernamePasswordAuthenticationToken</literal> by obtaining
+        authentication details from a data access object configured at bean
+        creation time:</para>
+
+        <para><programlisting>&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
+  &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
+  &lt;property name="saltSource"&gt;&lt;ref bean="saltSource"/&gt;&lt;/property&gt;
+  &lt;property name="passwordEncoder"&gt;&lt;ref bean="passwordEncoder"/&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>The <literal>PasswordEncoder</literal> and
+        <literal>SaltSource</literal> are optional. A
+        <literal>PasswordEncoder</literal> provides encoding and decoding of
+        passwords obtained from the authentication repository. A
+        <literal>SaltSource</literal> enables the passwords to be populated
+        with a "salt", which enhances the security of the passwords in the
+        authentication repository. <literal>PasswordEncoder</literal>
+        implementations are provided with the Acegi Security System for Spring
+        covering MD5, SHA and cleartext encodings. Two
+        <literal>SaltSource</literal> implementations are also provided:
+        <literal>SystemWideSaltSource</literal> which encodes all passwords
+        with the same salt, and <literal>ReflectionSaltSource</literal>, which
+        inspects a given property of the returned
+        <literal>UserDetails</literal> object to obtain the salt. Please refer
+        to the JavaDocs for further details on these optional features.</para>
+
+        <para>In addition to the properties above, the
+        <literal>DaoAuthenticationProvider</literal> supports optional caching
+        of <literal>UserDetails</literal> objects. The
+        <literal>UserCache</literal> interface enables the
+        <literal>DaoAuthenticationProvider</literal> to place a
+        <literal>UserDetails</literal> object into the cache, and retrieve it
+        from the cache upon subsequent authentication attempts for the same
+        username. By default the <literal>DaoAuthenticationProvider</literal>
+        uses the <literal>NullUserCache</literal>, which performs no caching.
+        A usable caching implementation is also provided,
+        <literal>EhCacheBasedUserCache</literal>, which is configured as
+        follows:</para>
+
+        <para><programlisting>&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
+  &lt;property name="authenticationDao"&gt;&lt;ref bean="authenticationDao"/&gt;&lt;/property&gt;
+  &lt;property name="userCache"&gt;&lt;ref bean="userCache"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;
+  &lt;property name="minutesToIdle"&gt;&lt;value&gt;5&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>For a class to be able to provide the
+        <literal>DaoAuthenticationProvider</literal> with access to an
+        authentication repository, it must implement the
+        <literal>AuthenticationDao</literal> interface:</para>
+
+        <para><programlisting>public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;</programlisting></para>
+
+        <para>The <literal>UserDetails</literal> is an interface that provides
+        getters that guarantee non-null provision of basic authentication
+        information such as the username, password, granted authorities and
+        whether the user is enabled or disabled. A concrete implementation,
+        <literal>User</literal>, is also provided. Acegi Security users will
+        need to decide when writing their <literal>AuthenticationDao</literal>
+        what type of <literal>UserDetails</literal> to return. In most cases
+        <literal>User</literal> will be used directly or subclassed, although
+        special circumstances (such as object relational mappers) may require
+        users to write their own <literal>UserDetails</literal> implementation
+        from scratch.</para>
+
+        <para>Given <literal>AuthenticationDao</literal> is so simple to
+        implement, it should be easy for users to retrieve authentication
+        information using a persistence strategy of their choice.</para>
+
+        <para>A design decision was made not to support account locking in the
+        <literal>DaoAuthenticationProvider</literal>, as doing so would have
+        increased the complexity of the <literal>AuthenticationDao</literal>
+        interface. For instance, a method would be required to increase the
+        count of unsuccessful authentication attempts. Such functionality
+        could be easily provided by leveraging the application event
+        publishing features discussed below.</para>
+
+        <para><literal>DaoAuthenticationProvider</literal> returns an
+        <literal>Authentication</literal> object which in turn has its
+        <literal>principal</literal> property set. The principal will be
+        either a <literal>String</literal> (which is essentially the username)
+        or a <literal>UserDetails</literal> object (which was looked up from
+        the <literal>AuthenticationDao</literal>). By default the
+        <literal>UserDetails</literal> is returned, as this enables
+        applications to add extra properties potentially of use in
+        applications, such as the user's full name, email address etc. If
+        using container adapters, or if your applications were written to
+        operate with <literal>String</literal>s (as was the case for releases
+        prior to Acegi Security 0.6), you should set the
+        <literal>DaoAuthenticationProvider.forcePrincipalAsString</literal>
+        property to <literal>true</literal> in your application
+        context.</para>
+      </sect2>
+
+      <sect2 id="security-authentication-provider-events">
+        <title>Event Publishing</title>
+
+        <para>The <literal>DaoAuthenticationProvider</literal> automatically
+        obtains the <literal>ApplicationContext</literal> it is running in at
+        startup time. This allows the provider to publish events through the
+        standard Spring event framework. Three types of event messages are
+        published:</para>
+
+        <itemizedlist spacing="compact">
+          <listitem>
+            <para><literal>AuthenticationSuccessEvent</literal> is published
+            when an authentication request is successful.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>AuthenticationFailureDisabledEvent</literal> is
+            published when an authentication request is unsuccessful because
+            the returned <literal>UserDetails</literal> is disabled. This is
+            normally the case when an account is locked.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>AuthenticationFailureUsernameNotFoundEvent</literal>
+            is published when an authentication request is unsuccessful
+            because the <literal>AuthenticationDao</literal> could not locate
+            the <literal>UserDetails</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>AuthenticationFailurePasswordEvent</literal> is
+            published when an authentication request is unsuccessful because
+            the presented password did not match that in the
+            <literal>UserDetails</literal>.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Each event contains two objects: the
+        <literal>Authentication</literal> object that represented the
+        authentication request, and the <literal>UserDetails</literal> object
+        that was found in response to the authentication request (clearly the
+        latter will be a dummy object in the case of
+        <literal>AuthenticationFailureUsernameNotFoundEvent</literal>). The
+        <literal>Authentication</literal> interface provides a
+        <literal>getDetails()</literal> method which often includes
+        information that event consumers may find useful (eg the TCP/IP
+        address that the authentication request originated from).</para>
+
+        <para>As per standard Spring event handling, you can receive these
+        events by adding a bean to the application context which implements
+        the <literal>ApplicationListener</literal> interface. Included with
+        Acegi Security is a <literal>LoggerListener</literal> class which
+        receives these events and publishes their details to Commons Logging.
+        Refer to the JavaDocs for <literal>LoggerListener</literal> for
+        details on the logging priorities used for different message
+        types.</para>
+
+        <para>This event publishing system enables you to implement account
+        locking and record authentication event history. This might be of
+        interest to application users, who can be advised of the times and
+        source IP address of all unsuccessful password attempts (and account
+        lockouts) since their last successful login. Such capabilities are
+        simple to implement and greatly improve the security of your
+        application.</para>
+      </sect2>
+
+      <sect2 id="security-authentication-provider-in-memory">
+        <title>In-Memory Authentication</title>
+
+        <para>Whilst it is easy to use the
+        <literal>DaoAuthenticationProvider</literal> and create a custom
+        <literal>AuthenticationDao</literal> implementation that extracts
+        information from a persistence engine of choice, many applications do
+        not require such complexity. One alternative is to configure an
+        authentication repository in the application context itself using the
+        <literal>InMemoryDaoImpl</literal>:</para>
+
+        <para><programlisting>&lt;bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl"&gt;
+  &lt;property name="userMap"&gt;
+    &lt;value&gt;
+      marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
+      dianne=emu,ROLE_TELLER
+      scott=wombat,ROLE_TELLER
+      peter=opal,disabled,ROLE_TELLER
+    &lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>The <literal>userMap</literal> property contains each of the
+        usernames, passwords, a list of granted authorities and an optional
+        enabled/disabled keyword. Commas delimit each token. The username must
+        appear to the left of the equals sign, and the password must be the
+        first token to the right of the equals sign. The
+        <literal>enabled</literal> and <literal>disabled</literal> keywords
+        (case insensitive) may appear in the second or any subsequent token.
+        Any remaining tokens are treated as granted authorities, which are
+        created as <literal>GrantedAuthorityImpl</literal> objects (refer to
+        the Authorization section for further discussion on granted
+        authorities). Note that if a user has no password and/or no granted
+        authorities, the user will not be created in the in-memory
+        authentication repository.</para>
+      </sect2>
+
+      <sect2 id="security-authentication-provider-jdbc">
+        <title>JDBC Authentication</title>
+
+        <para>The Acegi Security System for Spring also includes an
+        authentication provider that can obtain authentication information
+        from a JDBC data source. The typical configuration for the
+        <literal>JdbcDaoImpl</literal> is shown below:</para>
+
+        <para><programlisting>&lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
+  &lt;property name="driverClassName"&gt;&lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="url"&gt;&lt;value&gt;jdbc:hsqldb:hsql://localhost:9001&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="username"&gt;&lt;value&gt;sa&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="password"&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl"&gt;
+  &lt;property name="dataSource"&gt;&lt;ref bean="dataSource"/&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>You can use different relational database management systems by
+        modifying the <literal>DriverManagerDataSource</literal> shown above.
+        Irrespective of the database used, a standard schema must be used as
+        indicated in <literal>dbinit.txt</literal>.</para>
+
+        <para>If you default schema is unsuitable for your needs,
+        <literal>JdbcDaoImpl</literal> provides two properties that allow
+        customisation of the SQL statements. You may also subclass the
+        <literal>JdbcDaoImpl</literal> if further customisation is necessary.
+        Please refer to the JavaDocs for details.</para>
+
+        <para>The Acegi Security System for Spring ships with a Hypersonic SQL
+        instance that has the required authentication information and sample
+        data already populated. To use this server, simply execute the
+        <literal>server.bat</literal> or <literal>server.sh</literal> script
+        included in the distribution. This will load a new database server
+        instance that will service requests made to the URL indicated in the
+        bean context configuration shown above.</para>
+      </sect2>
+
+      <sect2 id="security-authentication-provider-jaas">
+        <title>JAAS Authentication</title>
+
+        <para>Acegi Security provides a package able to delegate
+        authentication requests to the Java Authentication and Authorization
+        Service (JAAS). This package is discussed in detail below.</para>
+
+        <para>Central to JAAS operation are login configuration files. To
+        learn more about JAAS login configuration files, consult the JAAS
+        reference documentation available from Sun Microsystems. We expect you
+        to have a basic understanding of JAAS and its login configuration file
+        syntax in order to understand this section.</para>
+
+        <sect3>
+          <title>JaasAuthenticationProvider</title>
+
+          <para>The <literal>JaasAuthenticationProvider</literal> attempts to
+          authenticate a user’s principal and credentials through JAAS.</para>
+
+          <para>Let’s assume we have a JAAS login configuration file,
+          <literal>/WEB-INF/login.conf</literal>, with the following
+          contents:</para>
+
+          <para><programlisting>JAASTest {
+  sample.SampleLoginModule required;
+};</programlisting></para>
+
+          <para>Like all Acegi Security beans, the
+          <literal>JaasAuthenticationProvider</literal> is configured via the
+          application context. The following definitions would correspond to
+          the above JAAS login configuration file:</para>
+
+          <para><programlisting>&lt;bean id="jaasAuthenticationProvider" class="net.sf.acegisecurity.providers.jaas.JaasAuthenticationProvider"&gt;
+  &lt;property name="loginConfig"&gt;
+    &lt;value&gt;/WEB-INF/login.conf&lt;/value&gt;
+  &lt;/property&gt;
+  &lt;property name="loginContextName"&gt;
+    &lt;value&gt;JAASTest&lt;/value&gt;
+  &lt;/property&gt;
+  &lt;property name="callbackHandlers"&gt;
+    &lt;list&gt;
+      &lt;bean class="net.sf.acegisecurity.providers.jaas.JaasNameCallbackHandler"/&gt;
+      &lt;bean class="net.sf.acegisecurity.providers.jaas.JaasPasswordCallbackHandler"/&gt;
+    &lt;/list&gt;
+  &lt;/property&gt;
+  &lt;property name="authorityGranters"&gt;
+    &lt;list&gt;
+      &lt;bean class="net.sf.acegisecurity.providers.jaas.TestAuthorityGranter"/&gt;
+    &lt;/list&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+          <para>The <literal>CallbackHandler</literal>s and
+          <literal>AuthorityGranter</literal>s are discussed below.</para>
+        </sect3>
+
+        <sect3>
+          <title>Callbacks</title>
+
+          <para>Most JAAS <literal>LoginModule</literal>s require a callback
+          of some sort. These callbacks are usually used to obtain the
+          username and password from the user. In an Acegi Security
+          deployment, Acegi Security is responsible for this user interaction
+          (typically via a reference to a
+          <literal>ContextHolder</literal>-managed
+          <literal>Authentication</literal> object). The JAAS package for
+          Acegi Security provides two default callback handlers,
+          <literal>JaasNameCallbackHandler</literal> and
+          <literal>JaasPasswordCallbackHandler</literal>. Each of these
+          callback handlers implement
+          <literal>JaasAuthenticationCallbackHandler</literal>. In most cases
+          these callback handlers can simply be used without understanding the
+          internal mechanics. For those needing full control over the callback
+          behavior, internally <literal>JaasAutheticationProvider</literal>
+          wraps these <literal>JaasAuthenticationCallbackHandler</literal>s
+          with an <literal>InternalCallbackHandler</literal>. The
+          <literal>InternalCallbackHandler</literal> is the class that
+          actually implements JAAS’ normal <literal>CallbackHandler</literal>
+          interface. Any time that the JAAS <literal>LoginModule</literal> is
+          used, it is passed a list of application context configured
+          <literal>InternalCallbackHandler</literal>s. If the
+          <literal>LoginModule</literal> requests a callback against the
+          <literal>InternalCallbackHandler</literal>s, the callback is in-turn
+          passed to the <literal>JaasAuthenticationCallbackHandler</literal>s
+          being wrapped.</para>
+        </sect3>
+
+        <sect3>
+          <title>AuthorityGranters</title>
+
+          <para>JAAS works with principals. Even “roles” are represented as
+          principals in JAAS. Acegi Security, on the other hand, works with
+          <literal>Authentication</literal> objects. Each
+          <literal>Authentication</literal> object contains a single
+          principal, and multiple <literal>GrantedAuthority</literal>[]s. To
+          facilitate mapping between these different concepts, the Acegi
+          Security JAAS package includes an
+          <literal>AuthorityGranter</literal> interface. An
+          <literal>AuthorityGranter</literal> is responsible for inspecting a
+          JAAS principal and returning a <literal>String</literal>. The
+          <literal>JaasAuthenticationProvider</literal> then creates a
+          <literal>JaasGrantedAuthority</literal> (which implements Acegi
+          Security’s <literal>GrantedAuthority</literal> interface) containing
+          both the <literal>AuthorityGranter</literal>-returned
+          <literal>String</literal> and the JAAS principal that the
+          <literal>AuthorityGranter</literal> was passed. The
+          <literal>JaasAuthenticationProvider</literal> obtains the JAAS
+          principals by firstly successfully authenticating the user’s
+          credentials using the JAAS <literal>LoginModule</literal>, and then
+          accessing the <literal>LoginContext</literal> it returns. A call to
+          <literal>LoginContext.getSubject().getPrincipals()</literal> is
+          made, with each resulting principal passed to each
+          <literal>AuthorityGranter</literal> defined against the
+          <literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal>
+          property. Acegi Security does not include any production
+          <literal>AuthorityGranter</literal>s given every JAAS principal has
+          an implementation-specific meaning. However, there is a
+          <literal>TestAuthorityGranter</literal> in the unit tests that
+          demonstrates a simple <literal>AuthorityGranter</literal>
+          implementation.</para>
+        </sect3>
+      </sect2>
+
+      <sect2 id="security-authentication-recommendations">
+        <title>Authentication Recommendations</title>
+
+        <para>With the heavy use of interfaces throughout the authentication
+        system (<literal>Authentication</literal>,
+        <literal>AuthenticationManager</literal>,
+        <literal>AuthenticationProvider</literal> and
+        <literal>AuthenticationDao</literal>) it might be confusing to a new
+        user to know which part of the authentication system to customize. In
+        general, the following is recommended:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>Use the
+            <literal>UsernamePasswordAuthenticationToken</literal>
+            implementation where possible.</para>
+          </listitem>
+
+          <listitem>
+            <para>If you simply need to implement a new authentication
+            repository (eg to obtain user details from your application’s
+            existing database), use the
+            <literal>DaoAuthenticationProvider</literal> along with the
+            <literal>AuthenticationDao</literal>. It is the fastest and safest
+            way to integrate an external database.</para>
+          </listitem>
+
+          <listitem>
+            <para>If you're using Container Adapters or a
+            <literal>RunAsManager</literal> that replaces the
+            <literal>Authentication</literal> object, ensure you have
+            registered the <literal>AuthByAdapterProvider</literal> and
+            <literal>RunAsManagerImplProvider</literal> respectively with your
+            <literal>ProviderManager</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Never enable the
+            <literal>TestingAuthenticationProvider</literal> on a production
+            system. Doing so will allow any client to simply present a
+            <literal>TestingAuthenticationToken</literal> and obtain whatever
+            access they request.</para>
+          </listitem>
+
+          <listitem>
+            <para>Adding a new <literal>AuthenticationProvider</literal> is
+            sufficient to support most custom authentication requirements.
+            Only unusual requirements would require the
+            <literal>ProviderManager</literal> to be replaced with a different
+            <literal>AuthenticationManager</literal>.</para>
+          </listitem>
+        </itemizedlist>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-authorization">
+      <title>Authorization</title>
+
+      <sect2 id="security-authorization-granted-authorities">
+        <title>Granted Authorities</title>
+
+        <para>As briefly mentioned in the Authentication section, all
+        <literal>Authentication</literal> implementations are required to
+        store an array of <literal>GrantedAuthority</literal> objects. These
+        represent the authorities that have been granted to the principal. The
+        <literal>GrantedAuthority</literal> objects are inserted into the
+        <literal>Authentication</literal> object by the
+        <literal>AuthenticationManager</literal> and are later read by
+        <literal>AccessDecisionManager</literal>s when making authorization
+        decisions.</para>
+
+        <para><literal>GrantedAuthority</literal> is an interface with only
+        one method:</para>
+
+        <para><programlisting>public String getAuthority();</programlisting></para>
+
+        <para>This method allows <literal>AccessDecisionManager</literal>s to
+        obtain a precise <literal>String</literal> representation of the
+        <literal>GrantedAuthority</literal>. By returning a representation as
+        a <literal>String</literal>, a <literal>GrantedAuthority</literal> can
+        be easily "read" by most <literal>AccessDecisionManager</literal>s. If
+        a <literal>GrantedAuthority</literal> cannot be precisely represented
+        as a <literal>String</literal>, the
+        <literal>GrantedAuthority</literal> is considered "complex" and
+        <literal>getAuthority()</literal> must return
+        <literal>null</literal>.</para>
+
+        <para>An example of a "complex" <literal>GrantedAuthority</literal>
+        would be an implementation that stores a list of operations and
+        authority thresholds that apply to different customer account numbers.
+        Representing this complex <literal>GrantedAuthority</literal> as a
+        <literal>String</literal> would be quite complex, and as a result the
+        <literal>getAuthority()</literal> method should return
+        <literal>null</literal>. This will indicate to any
+        <literal>AccessDecisionManager</literal> that it will need to
+        specifically support the <literal>GrantedAuthority</literal>
+        implementation in order to understand its contents.</para>
+
+        <para>The Acegi Security System for Spring includes one concrete
+        <literal>GrantedAuthority</literal> implementation,
+        <literal>GrantedAuthorityImpl</literal>. This allows any
+        user-specified <literal>String</literal> to be converted into a
+        <literal>GrantedAuthority</literal>. All
+        <literal>AuthenticationProvider</literal>s included with the security
+        architecture use <literal>GrantedAuthorityImpl</literal> to populate
+        the <literal>Authentication</literal> object.</para>
+      </sect2>
+
+      <sect2 id="security-authorization-access-decision-managers">
+        <title>Access Decision Managers</title>
+
+        <para>The <literal>AccessDecisionManager</literal> is called by the
+        <literal>AbstractSecurityInterceptor</literal> and is responsible for
+        making final access control decisions. The
+        <literal>AccessDecisionManager</literal> interface contains three
+        methods:</para>
+
+        <para><programlisting>public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException;
+public boolean supports(ConfigAttribute attribute);
+public boolean supports(Class clazz);</programlisting></para>
+
+        <para>As can be seen from the first method, the
+        <literal>AccessDecisionManager</literal> is passed via method
+        parameters all information that is likely to be of value in assessing
+        an authorization decision. In particular, passing the secure
+        <literal>Object</literal> enables those arguments contained in the
+        actual secure object invocation to be inspected. For example, let's
+        assume the secure object was a <literal>MethodInvocation</literal>. It
+        would be easy to query the <literal>MethodInvocation</literal> for any
+        <literal>Customer</literal> argument, and then implement some sort of
+        security logic in the <literal>AccessDecisionManager</literal> to
+        ensure the principal is permitted to operate on that customer.
+        Implementations are expected to throw an
+        <literal>AccessDeniedException</literal> if access is denied.</para>
+
+        <para>The <literal>supports(ConfigAttribute)</literal> method is
+        called by the <literal>AbstractSecurityInterceptor</literal> at
+        startup time to determine if the
+        <literal>AccessDecisionManager</literal> can process the passed
+        <literal>ConfigAttribute</literal>. The
+        <literal>supports(Class)</literal> method is called by a security
+        interceptor implementation to ensure the configured
+        <literal>AccessDecisionManager</literal> supports the type of secure
+        object that the security interceptor will present.</para>
+      </sect2>
+
+      <sect2 id="security-authorization-voting-decision-manager">
+        <title>Voting Decision Manager</title>
+
+        <para>Whilst users can implement their own
+        <literal>AccessDecisionManager</literal> to control all aspects of
+        authorization, the Acegi Security System for Spring includes several
+        <literal>AccessDecisionManager</literal> implementations that are
+        based on voting. Using this approach, a series of
+        <literal>AccessDecisionVoter</literal> implementations are polled on
+        an authorization decision. The
+        <literal>AccessDecisionManager</literal> then decides whether or not
+        to throw an <literal>AccessDeniedException</literal> based on its
+        assessment of the votes.</para>
+
+        <para>The <literal>AccessDecisionVoter</literal> interface has three
+        methods:</para>
+
+        <para><programlisting>public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
+public boolean supports(ConfigAttribute attribute);
+public boolean supports(Class clazz);</programlisting></para>
+
+        <para>Concrete implementations return an <literal>int</literal>, with
+        possible values being reflected in the
+        <literal>AccessDecisionVoter</literal> static fields
+        <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal>
+        and <literal>ACCESS_GRANTED</literal>. A voting implementation will
+        return <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an
+        authorization decision. If it does have an opinion, it must return
+        either <literal>ACCESS_DENIED</literal> or
+        <literal>ACCESS_GRANTED</literal>.</para>
+
+        <para>There are three concrete
+        <literal>AccessDecisionManager</literal>s provided with the Acegi
+        Security System for Spring that tally the votes. The
+        <literal>ConsensusBased</literal> implementation will grant or deny
+        access based on the consensus of non-abstain votes. Properties are
+        provided to control behavior in the event of an equality of votes or
+        if all votes are abstain. The <literal>AffirmativeBased</literal>
+        implementation will grant access if one or more
+        <literal>ACCESS_GRANTED</literal> votes were received (ie a deny vote
+        will be ignored, provided there was at least one grant vote). Like the
+        <literal>ConsensusBased</literal> implementation, there is a parameter
+        that controls the behavior if all voters abstain. The
+        <literal>UnanimousBased</literal> provider expects unanimous
+        <literal>ACCESS_GRANTED</literal> votes in order to grant access,
+        ignoring abstains. It will deny access if there is any
+        <literal>ACCESS_DENIED</literal> vote. Like the other implementations,
+        there is a parameter that controls the behaviour if all voters
+        abstain.</para>
+
+        <para>It is possible to implement a custom
+        <literal>AccessDecisionManager</literal> that tallies votes
+        differently. For example, votes from a particular
+        <literal>AccessDecisionVoter</literal> might receive additional
+        weighting, whilst a deny vote from a particular voter may have a veto
+        effect.</para>
+
+        <para>There is one concrete <literal>AccessDecisionVoter</literal>
+        implementation provided with the Acegi Security System for Spring. The
+        <literal>RoleVoter</literal> class will vote if any ConfigAttribute
+        begins with <literal>ROLE_</literal>. It will vote to grant access if
+        there is a <literal>GrantedAuthority</literal> which returns a
+        <literal>String</literal> representation (via the
+        <literal>getAuthority()</literal> method) exactly equal to one or more
+        <literal>ConfigAttributes</literal> starting with
+        <literal>ROLE_</literal>. If there is no exact match of any
+        <literal>ConfigAttribute</literal> starting with
+        <literal>ROLE_</literal>, the <literal>RoleVoter</literal> will vote
+        to deny access. If no <literal>ConfigAttribute</literal> begins with
+        <literal>ROLE_</literal>, the voter will abstain.
+        <literal>RoleVoter</literal> is case sensitive on comparisons as well
+        as the <literal>ROLE_</literal> prefix.</para>
+
+        <para>It is possible to implement a custom
+        <literal>AccessDecisionVoter</literal>. Several examples are provided
+        in the Acegi Security System for Spring unit tests, including
+        <literal>ContactSecurityVoter</literal> and
+        <literal>DenyVoter</literal>. The
+        <literal>ContactSecurityVoter</literal> abstains from voting decisions
+        where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal>
+        <literal>ConfigAttribute</literal> is not found. If voting, it queries
+        the <literal>MethodInvocation</literal> to extract the owner of the
+        <literal>Contact</literal> object that is subject of the method call.
+        It votes to grant access if the <literal>Contact</literal> owner
+        matches the principal presented in the
+        <literal>Authentication</literal> object. It could have just as easily
+        compared the <literal>Contact</literal> owner with some
+        <literal>GrantedAuthority</literal> the
+        <literal>Authentication</literal> object presented. All of this is
+        achieved with relatively few lines of code and demonstrates the
+        flexibility of the authorization model.</para>
+      </sect2>
+
+      <sect2 id="security-authorization-taglib">
+        <title>Authorization Tag Library</title>
+
+        <para>The Acegi Security System for Spring comes bundled with a JSP
+        tag library that eases JSP writing. The tag library is known as
+        <literal>authz</literal>.</para>
+
+        <para>This library allows you to easy develop JSP pages which
+        reference the security environment. For example,
+        <literal>authz</literal> allows you to determine if a principal holds
+        a particular granted authority, holds a group of granted authorities,
+        or does not hold a given granted authority.</para>
+
+        <sect3>
+          <title>Usage</title>
+
+          <para>The following JSP fragment illustrates how to use the
+          <literal>authz</literal> taglib:</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 code was copied from the Contacts sample
+          application.</para>
+
+          <para>What this code says is: if the principal has been granted
+          ROLE_SUPERVISOR, allow the tag's body to be output.</para>
+        </sect3>
+
+        <sect3>
+          <title>Installation</title>
+
+          <para>Installation is a simple matter. Simply copy the
+          <literal>acegi-security-taglib.jar</literal> file into your
+          application's <literal>WEB-INF/lib</literal> folder. The tag library
+          includes it's TLD, which makes it easier to work with JSP 1.2+
+          containers.</para>
+
+          <para>If you are using a JSP 1.1 container, you will need to declare
+          the JSP tag library in your application's <literal>web.xml</literal>
+          file, with code such as this:</para>
+
+          <para><programlisting>&lt;taglib&gt;
+       &lt;taglib-uri&gt;http://acegisecurity.sf.net/authz&lt;/taglib-uri&gt;
+       &lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
+&lt;/taglib&gt;</programlisting></para>
+
+          <para>For JSP 1.1 containers you will also need to extract the
+          <literal>authz.tld</literal> file from the
+          <literal>acegi-security-taglib.jar</literal> file and put it into
+          your application's <literal>WEB-INF/lib</literal> folder. Use a
+          regular Zip tool, or Java's JAR utility.</para>
+        </sect3>
+
+        <sect3>
+          <title>Reference</title>
+
+          <para>The <literal>authz:authorize</literal> tag declares the
+          following attributes:</para>
+
+          <para><itemizedlist spacing="compact">
+              <listitem>
+                <para><literal>ifAllGranted</literal>: All the listed roles
+                must be granted for the tag to output its body.</para>
+              </listitem>
+
+              <listitem>
+                <para><literal>ifAnyGranted</literal>: Any of the listed roles
+                must be granted for the tag to output its body.</para>
+              </listitem>
+
+              <listitem>
+                <para><literal>ifNotGranted</literal>: None of the listed
+                roles must be granted for the tag to output its body.</para>
+              </listitem>
+            </itemizedlist></para>
+
+          <para>You'll note that in each attribute you can list multiple
+          roles. Simply separate the roles using a comma. The
+          <literal>authorize</literal> tag ignores whitespace in
+          attributes.</para>
+
+          <para>The tag library logically ANDs all of it's parameters
+          together. This means that if you combine two or more attributes, all
+          attributes must be true for the tag to output it's body. Don't add
+          an <literal>ifAllGranted="ROLE_SUPERVISOR"</literal>, followed by an
+          <literal>ifNotGranted="ROLE_SUPERVISOR"</literal>, or you'll be
+          surprised to never see the tag's body.</para>
+
+          <para>By requiring all attributes to return true, the authorize tag
+          allows you to create more complex authorization scenarios. For
+          example, you could declare an
+          <literal>ifAllGranted="ROLE_SUPERVISOR"</literal> and an
+          <literal>ifNotGranted="ROLE_NEWBIE_SUPERVISOR"</literal> in the same
+          tag, in order to prevent new supervisors from seeing the tag body.
+          However it would no doubt be simpler to use
+          <literal>ifAllGranted="ROLE_EXPERIENCED_SUPERVISOR"</literal> rather
+          than inserting NOT conditions into your design.</para>
+
+          <para>One last item: the tag verifies the authorizations in a
+          specific order: first <literal>ifNotGranted</literal>, then
+          <literal>ifAllGranted</literal>, and finally,
+          <literal>ifAnyGranted</literal>.</para>
+        </sect3>
+      </sect2>
+
+      <sect2 id="security-authorization-recommendations">
+        <title>Authorization Recommendations</title>
+
+        <para>Given there are several ways to achieve similar authorization
+        outcomes in the Acegi Security System for Spring, the following
+        general recommendations are made:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>Grant authorities using
+            <literal>GrantedAuthorityImpl</literal> where possible. Because it
+            is already supported by the Acegi Security System for Spring, you
+            avoid the need to create custom
+            <literal>AuthenticationManager</literal> or
+            <literal>AuthenticationProvider</literal> implementations simply
+            to populate the <literal>Authentication</literal> object with a
+            custom <literal>GrantedAuthority</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Writing an <literal>AccessDecisionVoter</literal>
+            implementation and using either <literal>ConsensusBased</literal>,
+            <literal>AffirmativeBased</literal> or
+            <literal>UnanimousBased</literal> as the
+            <literal>AccessDecisionManager</literal> may be the best approach
+            to implementing your custom access decision rules.</para>
+          </listitem>
+        </itemizedlist>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-run-as">
+      <title>Run-As Authentication Replacement</title>
+
+      <sect2 id="security-run-as-purpose">
+        <title>Purpose</title>
+
+        <para>The <literal>AbstractSecurityInterceptor</literal> is able to
+        temporarily replace the <literal>Authentication</literal> object in
+        the <literal>SecureContext</literal> and
+        <literal>ContextHolder</literal> during the
+        <literal>SecurityInterceptorCallback</literal>. This only occurs if
+        the original <literal>Authentication</literal> object was successfully
+        processed by the <literal>AuthenticationManager</literal> and
+        <literal>AccessDecisionManager</literal>. The
+        <literal>RunAsManager</literal> will indicate the replacement
+        <literal>Authentication</literal> object, if any, that should be used
+        during the <literal>SecurityInterceptorCallback</literal>.</para>
+
+        <para>By temporarily replacing the <literal>Authentication</literal>
+        object during a <literal>SecurityInterceptorCallback</literal>, the
+        secured invocation will be able to call other objects which require
+        different authentication and authorization credentials. It will also
+        be able to perform any internal security checks for specific
+        <literal>GrantedAuthority</literal> objects.</para>
+      </sect2>
+
+      <sect2 id="security-run-as-usage">
+        <title>Usage</title>
+
+        <para>A <literal>RunAsManager</literal> interface is provided by the
+        Acegi Security System for Spring:</para>
+
+        <para><programlisting>public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config);
+public boolean supports(ConfigAttribute attribute);
+public boolean supports(Class clazz);</programlisting></para>
+
+        <para>The first method returns the <literal>Authentication</literal>
+        object that should replace the existing
+        <literal>Authentication</literal> object for the duration of the
+        method invocation. If the method returns <literal>null</literal>, it
+        indicates no replacement should be made. The second method is used by
+        the <literal>AbstractSecurityInterceptor</literal> as part of its
+        startup validation of configuration attributes. The
+        <literal>supports(Class)</literal> method is called by a security
+        interceptor implementation to ensure the configured
+        <literal>RunAsManager</literal> supports the type of secure object
+        that the security interceptor will present.</para>
+
+        <para>One concrete implementation of a <literal>RunAsManager</literal>
+        is provided with the Acegi Security System for Spring. The
+        <literal>RunAsManagerImpl</literal> class returns a replacement
+        <literal>RunAsUserToken</literal> if any
+        <literal>ConfigAttribute</literal> starts with
+        <literal>RUN_AS_</literal>. If any such
+        <literal>ConfigAttribute</literal> is found, the replacement
+        <literal>RunAsUserToken</literal> will contain the same principal,
+        credentials and granted authorities as the original
+        <literal>Authentication</literal> object, along with a new
+        <literal>GrantedAuthorityImpl</literal> for each
+        <literal>RUN_AS_</literal> <literal>ConfigAttribute</literal>. Each
+        new <literal>GrantedAuthorityImpl</literal> will be prefixed with
+        <literal>ROLE_</literal>, followed by the <literal>RUN_AS</literal>
+        <literal>ConfigAttribute</literal>. For example, a
+        <literal>RUN_AS_SERVER</literal> will result in the replacement
+        <literal>RunAsUserToken</literal> containing a
+        <literal>ROLE_RUN_AS_SERVER</literal> granted authority.</para>
+
+        <para>The replacement <literal>RunAsUserToken</literal> is just like
+        any other <literal>Authentication</literal> object. It needs to be
+        authenticated by the <literal>AuthenticationManager</literal>,
+        probably via delegation to a suitable
+        <literal>AuthenticationProvider</literal>. The
+        <literal>RunAsImplAuthenticationProvider</literal> performs such
+        authentication. It simply accepts as valid any
+        <literal>RunAsUserToken</literal> presented.</para>
+
+        <para>To ensure malicious code does not create a
+        <literal>RunAsUserToken</literal> and present it for guaranteed
+        acceptance by the <literal>RunAsImplAuthenticationProvider</literal>,
+        the hash of a key is stored in all generated tokens. The
+        <literal>RunAsManagerImpl</literal> and
+        <literal>RunAsImplAuthenticationProvider</literal> is created in the
+        bean context with the same key:</para>
+
+        <para><programlisting>&lt;bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl"&gt;
+  &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting><programlisting>&lt;bean id="runAsAuthenticationProvider" class="net.sf.acegisecurity.runas.RunAsImplAuthenticationProvider"&gt;
+  &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>By using the same key, each <literal>RunAsUserToken</literal>
+        can be validated it was created by an approved
+        <literal>RunAsManagerImpl</literal>. The
+        <literal>RunAsUserToken</literal> is immutable after creation for
+        security reasons.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-ui">
+      <title>User Interfacing with the ContextHolder</title>
+
+      <sect2 id="security-ui-purpose">
+        <title>Purpose</title>
+
+        <para>Everything presented so far assumes one thing: the
+        <literal>ContextHolder</literal> is populated with a valid
+        <literal>SecureContext</literal>, which in turn contains a valid
+        <literal>Authentication</literal> object. Developers are free to do
+        this in whichever way they like, such as directly calling the relevant
+        objects at runtime. However, several classes have been provided to
+        make this process transparent in many situations.</para>
+
+        <para>The <literal>net.sf.acegisecurity.ui</literal> package is
+        designed to make interfacing web application user interfaces with the
+        <literal>ContextHolder</literal> as simple as possible. There are two
+        major steps in doing this:</para>
+
+        <para><itemizedlist spacing="compact">
+            <listitem>
+              <para>Actually authenticate the user and place the resulting
+              <literal>Authentication</literal> object in a "well-known
+              location".</para>
+            </listitem>
+
+            <listitem>
+              <para>Extract the <literal>Authentication</literal> object from
+              the "well-known location" and place in into the
+              <literal>ContextHolder</literal> for the duration of the secure
+              object invocation.</para>
+            </listitem>
+          </itemizedlist></para>
+
+        <para>There are several alternatives are available for the first step,
+        which will be briefly discussed in this chapter. The most popular
+        approach is HTTP Session Authentication, which uses the
+        <literal>HttpSession</literal> object and filters to authenticate the
+        user. Another approach is HTTP Basic Authentication, which allows
+        clients to use HTTP headers to present authentication information to
+        the Acegi Security System for Spring. Alternatively, you can also use
+        Yale Central Authentication Service (CAS) for enterprise-wide single
+        sign on. The final approach is via Container Adapters, which allow
+        supported web containers to perform the authentication themselves.
+        HTTP Session and Basic Authentication is discussed below, whilst CAS
+        and Container Adapters are discussed in separate sections of this
+        document.</para>
+      </sect2>
+
+      <sect2 id="security-ui-http-session">
+        <title>HTTP Session Authentication</title>
+
+        <para>HTTP Session Authentication involves using the
+        <literal>AuthenticationProcessingFilter</literal> to process a login
+        form. The login form simply contains <literal>j_username</literal> and
+        <literal>j_password</literal> input fields, and posts to a URL that is
+        monitored by the filter (by default
+        <literal>j_acegi_security_check</literal>). The filter is defined in
+        <literal>web.xml</literal> behind a
+        <literal>FilterToBeanProxy</literal> as follows:</para>
+
+        <para><programlisting>&lt;filter&gt;
+  &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
+  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
+  &lt;init-param&gt;
+    &lt;param-name&gt;targetClass&lt;/param-name&gt;
+    &lt;param-value&gt;net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter&lt;/param-value&gt;
+  &lt;/init-param&gt;
+&lt;/filter&gt;
+
+&lt;filter-mapping&gt;
+  &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
+  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+&lt;/filter-mapping&gt;</programlisting></para>
+
+        <para>For a discussion of <literal>FilterToBeanProxy</literal>, please
+        refer to the Filters section. The application context will need to
+        define the <literal>AuthenticationProcessingFilter</literal>:</para>
+
+        <para><programlisting>&lt;bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter"&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/acegilogin.jsp?login_error=1&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_security_check&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>The configured <literal>AuthenticationManager</literal>
+        processes each authentication request. If authentication fails, the
+        browser will be redirected to the
+        <literal>authenticationFailureUrl</literal>. The
+        <literal>AuthenticationException</literal> will be placed into the
+        <literal>HttpSession</literal> attribute indicated by
+        <literal>AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY</literal>,
+        enabling a reason to be provided to the user on the error page.</para>
+
+        <para>If authentication is successful, the resulting
+        <literal>Authentication</literal> object will be placed into the
+        <literal>HttpSession</literal> attribute indicated by
+        <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.
+        This becomes the "well-known location" from which the
+        <literal>Authentication</literal> object is later extracted.</para>
+
+        <para>Once the <literal>HttpSession</literal> has been updated, the
+        browser will need to be redirected to the target URL. The target URL
+        is usually indicated by the <literal>HttpSession</literal> attribute
+        specified by
+        <literal>AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY</literal>.
+        This attribute is automatically set by the
+        <literal>SecurityEnforcementFilter</literal> when an
+        <literal>AuthenticationException</literal> occurs, so that after login
+        is completed the user can return to what they were trying to access.
+        If for some reason the <literal>HttpSession</literal> does not
+        indicate the target URL, the browser will be redirected to the
+        <literal>defaultTargetUrl</literal> property.</para>
+
+        <para>Because this authentication approach is fully contained within a
+        single web application, HTTP Session Authentication is recommended to
+        be used instead of Container Adapters.</para>
+      </sect2>
+
+      <sect2 id="security-ui-http-basic">
+        <title>HTTP Basic Authentication</title>
+
+        <para>The Acegi Security System for Spring provides a
+        <literal>BasicProcessingFilter</literal> which is capable of
+        processing 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.</para>
+
+        <para>To implement HTTP Basic Authentication, it is necessary to add
+        the following filter to <literal>web.xml</literal>:</para>
+
+        <para><programlisting>&lt;filter&gt;
+  &lt;filter-name&gt;Acegi HTTP BASIC Authorization Filter&lt;/filter-name&gt;
+  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
+  &lt;init-param&gt;
+    &lt;param-name&gt;targetClass&lt;/param-name&gt;
+    &lt;param-value&gt;net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter&lt;/param-value&gt;
+  &lt;/init-param&gt;
+&lt;/filter&gt;
+
+&lt;filter-mapping&gt;
+  &lt;filter-name&gt;Acegi HTTP BASIC Authorization 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>BasicProcessingFilter</literal> and its required
+        collaborator:</para>
+
+        <para><programlisting>&lt;bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter"&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"&gt;
+  &lt;property name="realmName"&gt;&lt;value&gt;Name Of Your Realm&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>The configured <literal>AuthenticationManager</literal>
+        processes each authentication request. If authentication fails, the
+        configured <literal>AuthenticationEntryPoint</literal> will be used to
+        retry the authentication process. Usually you will use the
+        <literal>BasicProcessingFilterEntryPoint</literal>, which returns a
+        401 response with a suitable header to retry HTTP Basic
+        authentication. If authentication is successful, the resulting
+        <literal>Authentication</literal> object will be placed into the
+        <literal>HttpSession</literal> attribute indicated by
+        <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.
+        This becomes the "well-known location" from which the
+        <literal>Authentication</literal> object is later extracted.</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>
+
+        <para>HTTP Basic Authentication is recommended to be used instead of
+        Container Adapters. It can be used in conjunction with HTTP Session
+        Authentication, as demonstrated in the Contacts sample application.
+        You can also use it instead of HTTP Session Authentication if you
+        wish.</para>
+      </sect2>
+
+      <sect2 id="security-ui-well-known">
+        <title>Well-Known Location Integration</title>
+
+        <para>Once a web application has used either HTTP Session
+        Authentication, HTTP Basic Authentication, or a Container Adapter, an
+        <literal>Authentication</literal> object will exist in a well-known
+        location. The final step in automatically integrating the user
+        interface with the backend security interceptor is to extract this
+        <literal>Authentication</literal> object from the well-known location
+        and place it into a <literal>SecureContext</literal> in the
+        <literal>ContextHolder</literal>.</para>
+
+        <para>The <literal>AbstractIntegrationFilter</literal> and its
+        subclasses provide this well-known location integration. These classes
+        are standard filters, and at the start of each request they will
+        attempt to extract the <literal>Authentication</literal> object from a
+        well-known location. The <literal>Authentication</literal> object will
+        then be added to a <literal>SecureContext</literal>, the
+        <literal>SecureContext</literal> associated with the
+        <literal>ContextHolder</literal> for the duration of the request, and
+        the <literal>ContextHolder</literal> be cleared when the request is
+        finished. Four concrete subclasses of
+        <literal>AbstractIntegrationFilter</literal> are provided with the
+        Acegi Security System for Spring:</para>
+
+        <para><itemizedlist>
+            <listitem>
+              <para><literal>HttpSessionIntegrationFilter</literal> is used
+              with HTTP Session Authentication, HTTP Basic Authentication, or
+              any other approach that populates the
+              <literal>HttpSession</literal> accordingly. It extracts the
+              <literal>Authentication</literal> object from the
+              <literal>HttpSession</literal> attribute indicated by
+              <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>HttpRequestIntegrationFilter</literal> is used
+              with Catalina, Jetty and Resin Container Adapters. It extracts
+              the authentication information from
+              <literal>HttpServletRequest.getUserPrincipal()</literal>.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>JbossIntegrationFilter</literal> is used with the
+              JBoss Container Adapter. It extracts the authentication from
+              <literal>java:comp/env/security/subject</literal>.</para>
+            </listitem>
+
+            <listitem>
+              <para><literal>AutoIntegrationFilter</literal> automatically
+              determines which filter to use. This makes a web application WAR
+              file more portable, as the <literal>web.xml</literal> is not
+              hard-coded to a specific
+              <literal>AbstractIntegrationFilter</literal>.</para>
+            </listitem>
+          </itemizedlist></para>
+
+        <para>To define the <literal>AutoIntegrationFilter</literal>
+        (recommended), simply add the following to your web.xml:</para>
+
+        <para><programlisting>&lt;filter&gt;
+  &lt;filter-name&gt;Acegi Security System for Spring Auto Integration Filter&lt;/filter-name&gt;
+  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
+  &lt;init-param&gt;
+    &lt;param-name&gt;targetClass&lt;/param-name&gt;
+    &lt;param-value&gt;net.sf.acegisecurity.ui.AutoIntegrationFilter&lt;/param-value&gt;
+  &lt;/init-param&gt;
+&lt;/filter&gt;
+
+&lt;filter-mapping&gt;
+  &lt;filter-name&gt;Acegi Security System for Spring Auto Integration Filter&lt;/filter-name&gt;
+  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+&lt;/filter-mapping&gt;</programlisting></para>
+
+        <para>You will also need to add the following line to your application
+        context:</para>
+
+        <para><programlisting>&lt;bean id="autoIntegrationFilter" class="net.sf.acegisecurity.ui.AutoIntegrationFilter" /&gt;</programlisting></para>
+
+        <para>Once in the <literal>ContextHolder</literal>, the standard Acegi
+        Security System for Spring classes can be used. Because
+        <literal>ContextHolder</literal> is a standard object which is
+        populated using a filter at the container level, JSPs and Servlets do
+        not need to use Spring's MVC packages. This enables those applications
+        that use other MVC frameworks to still leverage Spring's other
+        capabilities, with full authentication and authorization support. The
+        <literal>debug.jsp</literal> page provided with the sample application
+        demonstrates accessing the <literal>ContextHolder</literal>
+        independent of Spring's MVC packages.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-container-adapters">
+      <title>Container Adapters</title>
+
+      <sect2 id="security-container-adapters-overview">
+        <title>Overview</title>
+
+        <para>Early versions of the Acegi Security System for Spring
+        exclusively used Container Adapters for interfacing authentication
+        with end users. Whilst this worked well, it required considerable time
+        to support multiple container versions and the configuration itself
+        was relatively time-consuming for developers. For this reason the HTTP
+        Session Authentication and HTTP Basic Authentication approaches were
+        developed, and are today recommended for most applications.</para>
+
+        <para>Container Adapters enable the Acegi Security System for Spring
+        to integrate directly with the containers used to host end user
+        applications. This integration means that applications can continue to
+        leverage the authentication and authorization capabilities built into
+        containers (such as <literal>isUserInRole()</literal> and form-based
+        or basic authentication), whilst benefiting from the enhanced security
+        interception capabilities provided by the Acegi Security System for
+        Spring.</para>
+
+        <para>The integration between a container and the Acegi Security
+        System for Spring is achieved through an adapter. The adapter provides
+        a container-compatible user authentication provider, and needs to
+        return a container-compatible user object.</para>
+
+        <para>The adapter is instantiated by the container and is defined in a
+        container-specific configuration file. The adapter then loads a Spring
+        application context which defines the normal authentication manager
+        settings, such as the authentication providers that can be used to
+        authenticate the request. The application context is usually named
+        <literal>acegisecurity.xml</literal> and is placed in a
+        container-specific location.</para>
+
+        <para>The Acegi Security System for Spring currently supports Jetty,
+        Catalina (Tomcat), JBoss and Resin. Additional container adapters can
+        easily be written.</para>
+      </sect2>
+
+      <sect2 id="security-container-adapters-adapter-provider">
+        <title>Adapter Authentication Provider</title>
+
+        <para>As is always the case, the container adapter generated
+        <literal>Authentication</literal> object still needs to be
+        authenticated by an <literal>AuthenticationManager</literal> when
+        requested to do so by the
+        <literal>AbstractSecurityInterceptor</literal>. The
+        <literal>AuthenticationManager</literal> needs to be certain the
+        adapter-provided <literal>Authentication</literal> object is valid and
+        was actually authenticated by a trusted adapter.</para>
+
+        <para>Adapters create <literal>Authentication</literal> objects which
+        are immutable and implement the <literal>AuthByAdapter</literal>
+        interface. These objects store the hash of a key that is defined by
+        the adapter. This allows the <literal>Authentication</literal> object
+        to be validated by the <literal>AuthByAdapterProvider</literal>. This
+        authentication provider is defined as follows:</para>
+
+        <para><programlisting>&lt;bean id="authByAdapterProvider" class="net.sf.acegisecurity.adapters.AuthByAdapterProvider"&gt;
+  &lt;property name="key"&gt;&lt;value&gt;my_password&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>The key must match the key that is defined in the
+        container-specific configuration file that starts the adapter. The
+        <literal>AuthByAdapterProvider</literal> automatically accepts as
+        valid any <literal>AuthByAdapter</literal> implementation that returns
+        the expected hash of the key.</para>
+
+        <para>To reiterate, this means the adapter will perform the initial
+        authentication using providers such as
+        <literal>DaoAuthenticationProvider</literal>, returning an
+        <literal>AuthByAdapter</literal> instance that contains a hash code of
+        the key. Later, when an application calls a security interceptor
+        managed resource, the <literal>AuthByAdapter</literal> instance in the
+        <literal>SecureContext</literal> in the
+        <literal>ContextHolder</literal> will be tested by the application's
+        <literal>AuthByAdapterProvider</literal>. There is no requirement for
+        additional authentication providers such as
+        <literal>DaoAuthenticationProvider</literal> within the
+        application-specific application context, as the only type of
+        <literal>Authentication</literal> instance that will be presented by
+        the application is from the container adapter.</para>
+
+        <para>Classloader issues are frequent with containers and the use of
+        container adapters illustrates this further. Each container requires a
+        very specific configuration. The installation instructions are
+        provided below. Once installed, please take the time to try the sample
+        application to ensure your container adapter is properly
+        configured.</para>
+
+        <para>When using container adapters with the
+        <literal>DaoAuthenticationProvider</literal>, ensure you set its
+        <literal>forcePrincipalAsString</literal> property to
+        <literal>true</literal>.</para>
+      </sect2>
+
+      <sect2 id="security-container-adapters-catalina">
+        <title>Catalina (Tomcat) Installation</title>
+
+        <para>The following was tested with Jakarta Tomcat 4.1.30 and 5.0.19.
+        We automatically test the following directions using our container
+        integration test system and these versions of Catalina
+        (Tomcat).</para>
+
+        <para><literal>$CATALINA_HOME</literal> refers to the root of your
+        Catalina (Tomcat) installation.</para>
+
+        <para>Edit your <literal>$CATALINA_HOME/conf/server.xml</literal> file
+        so the <literal>&lt;Engine&gt;</literal> section contains only one
+        active <literal>&lt;Realm&gt;</literal> entry. An example realm
+        entry:</para>
+
+        <para><programlisting>      &lt;Realm className="net.sf.acegisecurity.adapters.catalina.CatalinaAcegiUserRealm"
+             appContextLocation="conf/acegisecurity.xml"
+             key="my_password" /&gt;</programlisting></para>
+
+        <para>Be sure to remove any other <literal>&lt;Realm&gt;</literal>
+        entry from your <literal>&lt;Engine&gt;</literal> section.</para>
+
+        <para>Copy <literal>acegisecurity.xml</literal> into
+        <literal>$CATALINA_HOME/conf</literal>.</para>
+
+        <para>Copy <literal>acegi-security-catalina-server.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>acegi-security-catalina-common.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.jar</literal>) should be in your application's
+        <literal>WEB-INF/lib</literal>. The realm name indicated in your
+        <literal>web.xml</literal> does not matter with Catalina.</para>
+
+        <para>We have received reports of problems using this Container
+        Adapter with Mac OS X. A work-around is to use a script such as
+        follows:</para>
+
+        <para><programlisting>#!/bin/sh
+export CATALINA_HOME="/Library/Tomcat"
+export JAVA_HOME="/Library/Java/Home"
+cd /
+$CATALINA_HOME/bin/startup.sh</programlisting></para>
+      </sect2>
+
+      <sect2 id="security-container-adapters-jetty">
+        <title>Jetty Installation</title>
+
+        <para>The following was tested with Jetty 4.2.18. We automatically
+        test the following directions using our container integration test
+        system and this version of Jetty.</para>
+
+        <para><literal>$JETTY_HOME</literal> refers to the root of your Jetty
+        installation.</para>
+
+        <para>Edit your <literal>$JETTY_HOME/etc/jetty.xml</literal> file so
+        the <literal>&lt;Configure class&gt;</literal> section has a new
+        addRealm call:</para>
+
+        <para><programlisting>  &lt;Call name="addRealm"&gt;
+    &lt;Arg&gt;
+      &lt;New class="net.sf.acegisecurity.adapters.jetty.JettyAcegiUserRealm"&gt;
+        &lt;Arg&gt;Spring Powered Realm&lt;/Arg&gt;
+        &lt;Arg&gt;my_password&lt;/Arg&gt;
+        &lt;Arg&gt;etc/acegisecurity.xml&lt;/Arg&gt;
+      &lt;/New&gt;
+    &lt;/Arg&gt;
+  &lt;/Call&gt;</programlisting></para>
+
+        <para>Copy <literal>acegisecurity.xml</literal> into
+        <literal>$JETTY_HOME/etc</literal>.</para>
+
+        <para>Copy the following files into
+        <literal>$JETTY_HOME/ext</literal>:<itemizedlist>
+            <listitem>
+              <para><literal>aopalliance.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>commons-logging.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>spring.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>acegi-security-jetty-ext.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.jar</literal>) should be in your application's
+        <literal>WEB-INF/lib</literal>. The realm name indicated in your
+        <literal>web.xml</literal> does matter with Jetty. The
+        <literal>web.xml</literal> must express the same
+        <literal>&lt;realm-name&gt;</literal> as your
+        <literal>jetty.xml</literal> (in the example above, "Spring Powered
+        Realm").</para>
+      </sect2>
+
+      <sect2 id="security-container-adapters-joss">
+        <title>JBoss Installation</title>
+
+        <para>The following was tested with JBoss 3.2.3. We automatically test
+        the following directions using our container integration test system
+        and this version of JBoss.</para>
+
+        <para><literal>$JBOSS_HOME</literal> refers to the root of your JBoss
+        installation.</para>
+
+        <para>Edit your
+        <literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal>
+        file so that it contains a new entry under the
+        <literal>&lt;Policy&gt;</literal> section:</para>
+
+        <para><programlisting>    &lt;application-policy name = "SpringPoweredRealm"&gt;
+       &lt;authentication&gt;
+          &lt;login-module code = "net.sf.acegisecurity.adapters.jboss.JbossSpringLoginModule"
+            flag = "required"&gt;
+            &lt;module-option name = "appContextLocation"&gt;acegisecurity.xml&lt;/module-option&gt;
+            &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
+         &lt;/login-module&gt;
+       &lt;/authentication&gt;
+    &lt;/application-policy&gt;</programlisting></para>
+
+        <para>Copy <literal>acegisecurity.xml</literal> into
+        <literal>$JBOSS_HOME/server/your_config/conf</literal>.</para>
+
+        <para>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-lib.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.jar</literal>) should be in your application's
+        <literal>WEB-INF/lib</literal>. The realm name indicated in your
+        <literal>web.xml</literal> does not matter with JBoss. However, your
+        web application's <literal>WEB-INF/jboss-web.xml</literal> must
+        express the same <literal>&lt;security-domain&gt;</literal> as your
+        <literal>login-config.xml</literal>. For example, to match the above
+        example, your <literal>jboss-web.xml</literal> would look like
+        this:</para>
+
+        <para><programlisting>&lt;jboss-web&gt;
+  &lt;security-domain&gt;java:/jaas/SpringPoweredRealm&lt;/security-domain&gt;
+&lt;/jboss-web&gt;</programlisting></para>
+      </sect2>
+
+      <sect2 id="security-container-adapters-resin">
+        <title>Resin Installation</title>
+
+        <para>The following was tested with Resin 3.0.6.</para>
+
+        <para><literal>$RESIN_HOME</literal> refers to the root of your Resin
+        installation.</para>
+
+        <para>Resin provides several ways to support the container adapter. In
+        the instructions below we have elected to maximise consistency with
+        other container adapter configurations. This will allow Resin users to
+        simply deploy the sample application and confirm correct
+        configuration. Developers comfortable with Resin are naturally able to
+        use its capabilities to package the JARs with the web application
+        itself, and/or support single sign-on.</para>
+
+        <para>Copy the following files into
+        <literal>$RESIN_HOME/lib</literal>:<itemizedlist>
+            <listitem>
+              <para><literal>aopalliance.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>commons-logging.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>spring.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>acegi-security-resin-lib.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>commons-codec.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>burlap.jar</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>hessian.jar</literal></para>
+            </listitem>
+          </itemizedlist></para>
+
+        <para>Unlike the container-wide <literal>acegisecurity.xml</literal>
+        files used by other container adapters, each Resin web application
+        will contain its own
+        <literal>WEB-INF/resin-acegisecurity.xml</literal> file. Each web
+        application will also contain a <literal>resin-web.xml</literal> file
+        which Resin uses to start the container adapter:</para>
+
+        <para><programlisting>&lt;web-app&gt;
+  &lt;authenticator&gt;
+    &lt;type&gt;net.sf.acegisecurity.adapters.resin.ResinAcegiAuthenticator&lt;/type&gt;
+    &lt;init&gt;
+      &lt;app-context-location&gt;WEB-INF/resin-acegisecurity.xml&lt;/app-context-location&gt;
+      &lt;key&gt;my_password&lt;/key&gt;
+    &lt;/init&gt;
+  &lt;/authenticator&gt;
+&lt;/web-app&gt;</programlisting></para>
+
+        <para>With the basic configuration provided above, none of the JAR
+        files listed (or <literal>acegi-security.jar</literal>) should be in
+        your application's <literal>WEB-INF/lib</literal>. The realm name
+        indicated in your <literal>web.xml</literal> does not matter with
+        Resin, as the relevant authentication class is indicated by the
+        <literal>&lt;authenticator&gt;</literal> setting.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-cas">
+      <title>Yale Central Authentication Service (CAS) Single Sign On</title>
+
+      <sect2 id="security-cas-overview">
+        <title>Overview</title>
+
+        <para>Yale University produces an enterprise-wide single sign on
+        system known as CAS. Unlike other initiatives, Yale's Central
+        Authentication Service is open source, widely used, simple to
+        understand, platform independent, and supports proxy capabilities. The
+        Acegi Security System for Spring fully supports CAS, and provides an
+        easy migration path from single-application deployments of Acegi
+        Security through to multiple-application deployments secured by an
+        enterprise-wide CAS server.</para>
+
+        <para>You can learn more about CAS at
+        <literal>http://www.yale.edu/tp/auth/</literal>. You will need to
+        visit this URL to download the CAS Server files. Whilst the Acegi
+        Security System for Spring includes two CAS libraries in the
+        "-with-dependencies" ZIP file, you will still need the CAS Java Server
+        Pages and <literal>web.xml</literal> to customise and deploy your CAS
+        server.</para>
+      </sect2>
+
+      <sect2 id="security-cas-how-cas-works">
+        <title>How CAS Works</title>
+
+        <para>Whilst the CAS web site above contains two documents that detail
+        the architecture of CAS, we present the general overview again here
+        within the context of the Acegi Security System for Spring. The
+        following refers to CAS 2.0, being the version of CAS that Acegi
+        Security System for Spring supports.</para>
+
+        <para>Somewhere in your enterprise you will need to setup a CAS
+        server. The CAS server is simply a standard WAR file, so there isn't
+        anything difficult about setting up your server. Inside the WAR file
+        you will customise the login and other single sign on pages displayed
+        to users. You will also need to specify in the web.xml a
+        <literal>PasswordHandler</literal>. The
+        <literal>PasswordHandler</literal> has a simple method that returns a
+        boolean as to whether a given username and password is valid. Your
+        <literal>PasswordHandler</literal> implementation will need to link
+        into some type of backend authentication repository, such as an LDAP
+        server or database.</para>
+
+        <para>If you are already running an existing CAS server instance, you
+        will have already established a <literal>PasswordHandler</literal>. If
+        you do not already have a <literal>PasswordHandler</literal>, you
+        might prefer to use the Acegi Security System for Spring
+        <literal>CasPasswordHandler</literal> class. This class delegates
+        through to the standard Acegi Security
+        <literal>AuthenticationManager</literal>, enabling you to use a
+        security configuration you might already have in place. You do not
+        need to use the <literal>CasPasswordHandler</literal> class on your
+        CAS server if you do not wish. The Acegi Security System for Spring
+        will function as a CAS client successfully irrespective of the
+        <literal>PasswordHandler</literal> you've chosen for your CAS
+        server.</para>
+
+        <para>Apart from the CAS server itself, the other key player is of
+        course the secure web applications deployed throughout your
+        enterprise. These web applications are known as "services". There are
+        two types of services: standard services and proxy services. A proxy
+        service is able to request resources from other services on behalf of
+        the user. This will be explained more fully later.</para>
+
+        <para>Services can be developed in a large variety of languages, due
+        to CAS 2.0's very light XML-based protocol. The Yale CAS home page
+        contains a clients archive which demonstrates CAS clients in Java,
+        Active Server Pages, Perl, Python and others. Naturally, Java support
+        is very strong given the CAS server is written in Java. You do not
+        need to use any of CAS' client classes in applications secured by the
+        Acegi Security System for Spring. This is handled transparently for
+        you.</para>
+
+        <para>The basic interaction between a web browser, CAS server and an
+        Acegi Security for System Spring secured service is as follows:</para>
+
+        <orderedlist>
+          <listitem>
+            <para>The web user is browsing the service's public pages. CAS or
+            Acegi Security is not involved.</para>
+          </listitem>
+
+          <listitem>
+            <para>The user eventually requests a page that is either secure or
+            one of the beans it uses is secure. Acegi Security's
+            <literal>SecurityEnforcementFilter</literal> will detect the
+            <literal>AuthenticationException</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Because the user's <literal>Authentication</literal> object
+            (or lack thereof) caused an
+            <literal>AuthenticationException</literal>, the
+            <literal>SecurityEnforcementFilter</literal> will call the
+            configured <literal>AuthenticationEntryPoint</literal>. If using
+            CAS, this will be the
+            <literal>CasProcessingFilterEntryPoint</literal> class.</para>
+          </listitem>
+
+          <listitem>
+            <para>The <literal>CasProcessingFilterEntry</literal> point will
+            redirect the user's browser to the CAS server. It will also
+            indicate a <literal>service</literal> parameter, which is the
+            callback URL for the Acegi Security service. For example, the URL
+            to which the browser is redirected might be
+            <literal>https://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_acegi_cas_security_check</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>After the user's browser redirects to CAS, they will be
+            prompted for their username and password. If the user presents a
+            session cookie which indicates they've previously logged on, they
+            will not be prompted to login again (there is an exception to this
+            procedure, which we'll cover later). CAS will use the
+            <literal>PasswordHandler</literal> discussed above to decide
+            whether the username and password is valid.</para>
+          </listitem>
+
+          <listitem>
+            <para>Upon successful login, CAS will redirect the user's browser
+            back to the original service. It will also include a
+            <literal>ticket</literal> parameter, which is an opaque string
+            representing the "service ticket". Continuing our earlier example,
+            the URL the browser is redirected to might be
+            <literal>https://server3.company.com/webapp/j_acegi_cas_security_check?ticket=ST-0-ER94xMJmn6pha35CQRoZ</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Back in the service web application, the
+            <literal>CasProcessingFilter</literal> is always listening for
+            requests to <literal>/j_acegi_cas_security_check</literal> (this
+            is configurable, but we'll use the defaults in this introduction).
+            The processing filter will construct a
+            <literal>UsernamePasswordAuthenticationToken</literal>
+            representing the service ticket. The principal will be equal to
+            <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>,
+            whilst the credentials will be the service ticket opaque value.
+            This authentication request will then be handed to the configured
+            <literal>AuthenticationManager</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>The <literal>AuthenticationManager</literal> implementation
+            will be the <literal>ProviderManager</literal>, which is in turn
+            configured with the <literal>CasAuthenticationProvider</literal>.
+            The <literal>CasAuthenticationProvider</literal> only responds to
+            <literal>UsernamePasswordAuthenticationToken</literal>s containing
+            the CAS-specific principal (such as
+            <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>)
+            and <literal>CasAuthenticationToken</literal>s (discussed
+            later).</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>CasAuthenticationProvider</literal> will validate
+            the service ticket using a <literal>TicketValidator</literal>
+            implementation. Acegi Security includes one implementation, the
+            <literal>CasProxyTicketValidator</literal>. This implementation a
+            ticket validation class included in the CAS client library. The
+            <literal>CasProxyTicketValidator</literal> makes a HTTPS request
+            to the CAS server in order to validate the service ticket. The
+            <literal>CasProxyTicketValidator</literal> may also include a
+            proxy callback URL, which is included in this example:
+            <literal>https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_acegi_cas_security_check&amp;ticket=ST-0-ER94xMJmn6pha35CQRoZ&amp;pgtUrl=https://server3.company.com/webapp/casProxy/receptor</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>Back on the CAS server, the proxy validation request will be
+            received. If the presented service ticket matches the service URL
+            the ticket was issued to, CAS will provide an affirmative response
+            in XML indicating the username. If any proxy was involved in the
+            authentication (discussed below), the list of proxies is also
+            included in the XML response.</para>
+          </listitem>
+
+          <listitem>
+            <para>[OPTIONAL] If the request to the CAS validation service
+            included the proxy callback URL (in the <literal>pgtUrl</literal>
+            parameter), CAS will include a <literal>pgtIou</literal> string in
+            the XML response. This <literal>pgtIou</literal> represents a
+            proxy-granting ticket IOU. The CAS server will then create its own
+            HTTPS connection back to the <literal>pgtUrl</literal>. This is to
+            mutually authenticate the CAS server and the claimed service URL.
+            The HTTPS connection will be used to send a proxy granting ticket
+            to the original web application. For example,
+            <literal>https://server3.company.com/webapp/casProxy/receptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&amp;pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH</literal>.
+            We suggest you use CAS' <literal>ProxyTicketReceptor</literal>
+            servlet to receive these proxy-granting tickets, if they are
+            required.</para>
+          </listitem>
+
+          <listitem>
+            <para>The <literal>CasProxyTicketValidator</literal> will parse
+            the XML received from the CAS server. It will return to the
+            <literal>CasAuthenticationProvider</literal> a
+            <literal>TicketResponse</literal>, which includes the username
+            (mandatory), proxy list (if any were involved), and proxy-granting
+            ticket IOU (if the proxy callback was requested).</para>
+          </listitem>
+
+          <listitem>
+            <para>Next <literal>CasAuthenticationProvider</literal> will call
+            a configured <literal>CasProxyDecider</literal>. The
+            <literal>CasProxyDecider</literal> indicates whether the proxy
+            list in the <literal>TicketResponse</literal> is acceptable to the
+            service. Several implementations are provided with the Acegi
+            Security System: <literal>RejectProxyTickets</literal>,
+            <literal>AcceptAnyCasProxy</literal> and
+            <literal>NamedCasProxyDecider</literal>. These names are largely
+            self-explanatory, except <literal>NamedCasProxyDecider</literal>
+            which allows a <literal>List</literal> of trusted proxies to be
+            provided.</para>
+          </listitem>
+
+          <listitem>
+            <para><literal>CasAuthenticationProvider</literal> will next
+            request a <literal>CasAuthoritiesPopulator</literal> to advise the
+            <literal>GrantedAuthority</literal> objects that apply to the user
+            contained in the <literal>TicketResponse</literal>. Acegi Security
+            includes a <literal>DaoCasAuthoritiesPopulator</literal> which
+            simply uses the <literal>AuthenticationDao</literal>
+            infrastructure to find the <literal>UserDetails</literal> and
+            their associated <literal>GrantedAuthority</literal>s. Note that
+            the password and enabled/disabled status of
+            <literal>UserDetails</literal> returned by the
+            <literal>AuthenticationDao</literal> are ignored, as the CAS
+            server is responsible for authentication decisions.
+            <literal>DaoCasAuthoritiesPopulator</literal> is only concerned
+            with retrieving the <literal>GrantedAuthority</literal>s.</para>
+          </listitem>
+
+          <listitem>
+            <para>If there were no problems,
+            <literal>CasAuthenticationProvider</literal> constructs a
+            <literal>CasAuthenticationToken</literal> including the details
+            contained in the <literal>TicketResponse</literal> and the
+            <literal>GrantedAuthority</literal>s. The
+            <literal>CasAuthenticationToken</literal> contains the hash of a
+            key, so that the <literal>CasAuthenticationProvider</literal>
+            knows it created it.</para>
+          </listitem>
+
+          <listitem>
+            <para>Control then returns to
+            <literal>CasProcessingFilter</literal>, which places the created
+            <literal>CasAuthenticationToken</literal> into the
+            <literal>HttpSession</literal> attribute named
+            <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>The user's browser is redirected to the original page that
+            caused the <literal>AuthenticationException</literal>.</para>
+          </listitem>
+
+          <listitem>
+            <para>As the <literal>Authentication</literal> object is now in
+            the well-known location, it is handled like any other
+            authentication approach. Usually the
+            <literal>AutoIntegrationFilter</literal> will be used to associate
+            the <literal>Authentication</literal> object with the
+            <literal>ContextHolder</literal> for the duration of each
+            request.</para>
+          </listitem>
+        </orderedlist>
+
+        <para>It's good that you're still here! It might sound involved, but
+        you can relax as the Acegi Security System for Spring classes hide
+        much of the complexity. Let's now look at how this is
+        configured.</para>
+      </sect2>
+
+      <sect2 id="security-cas-install-server">
+        <title>CAS Server Installation (Optional)</title>
+
+        <para>As mentioned above, the Acegi Security System for Spring
+        includes a <literal>PasswordHandler</literal> that bridges your
+        existing <literal>AuthenticationManager</literal> into CAS. You do not
+        need to use this <literal>PasswordHandler</literal> to use Acegi
+        Security on the client side (any CAS
+        <literal>PasswordHandler</literal> will do).</para>
+
+        <para>To install, you will need to download and extract the CAS server
+        archive. We used version 2.0.12. There will be a
+        <literal>/web</literal> directory in the root of the deployment. Copy
+        an <literal>applicationContext.xml</literal> containing your
+        <literal>AuthenticationManager</literal> as well as the
+        <literal>CasPasswordHandler</literal> into the
+        <literal>/web/WEB-INF</literal> directory. A sample
+        <literal>applicationContext.xml</literal> is included below:</para>
+
+        <programlisting>&lt;bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl"&gt;
+  &lt;property name="userMap"&gt;
+    &lt;value&gt;
+      marissa=koala,ROLES_IGNORED_BY_CAS
+      dianne=emu,ROLES_IGNORED_BY_CAS
+      scott=wombat,ROLES_IGNORED_BY_CAS
+      peter=opal,disabled,ROLES_IGNORED_BY_CAS
+    &lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
+  &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
+  &lt;property name="providers"&gt;
+    &lt;list&gt;
+      &lt;ref bean="daoAuthenticationProvider"/&gt;
+    &lt;/list&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="casPasswordHandler" class="net.sf.acegisecurity.adapters.cas.CasPasswordHandler"&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting>
+
+        <para>Note the granted authorities are ignored by CAS because it has
+        no way of communicating the granted authorities to calling
+        applications. CAS is only concerned with username and passwords (and
+        the enabled/disabled status).</para>
+
+        <para>Next you will need to edit the existing
+        <literal>/web/WEB-INF/web.xml</literal> file. Add (or edit in the case
+        of the <literal>authHandler</literal> property) the following
+        lines:</para>
+
+        <para><programlisting>&lt;context-param&gt;
+  &lt;param-name&gt;edu.yale.its.tp.cas.authHandler&lt;/param-name&gt;
+  &lt;param-value&gt;net.sf.acegisecurity.adapters.cas.CasPasswordHandlerProxy&lt;/param-value&gt;
+&lt;/context-param&gt;
+
+&lt;context-param&gt;
+  &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
+  &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
+&lt;/context-param&gt;
+
+&lt;listener&gt;
+  &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
+&lt;/listener&gt;</programlisting></para>
+
+        <para>Copy the <literal>spring.jar</literal> and
+        <literal>acegi-security.jar</literal> files into
+        <literal>/web/WEB-INF/lib</literal>. Now use the <literal>ant
+        dist</literal> task in the <literal>build.xml</literal> in the root of
+        the directory structure. This will create
+        <literal>/lib/cas.war</literal>, which is ready for deployment to your
+        servlet container.</para>
+
+        <para>Note CAS heavily relies on HTTPS. You can't even test the system
+        without a HTTPS certificate. Whilst you should refer to your web
+        container's documentation on setting up HTTPS, if you need some
+        additional help or a test certificate you might like to check the
+        <literal>samples/contacts/etc/ssl</literal> directory.</para>
+      </sect2>
+
+      <sect2 id="security-cas-install-client">
+        <title>CAS Acegi Security System Client Installation</title>
+
+        <para>The web application side of CAS is made easy due to the Acegi
+        Security System for Spring. It is assumed you already know the basics
+        of using the Acegi Security System for Spring, so these are not
+        covered again below. Only the CAS-specific beans are mentioned.</para>
+
+        <para>You will need to add a <literal>ServiceProperties</literal> bean
+        to your application context. This represents your service:</para>
+
+        <para><programlisting>&lt;bean id="serviceProperties" class="net.sf.acegisecurity.ui.cas.ServiceProperties"&gt;
+  &lt;property name="service"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="sendRenew"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>The <literal>service</literal> must equal a URL that will be
+        monitored by the <literal>CasProcessingFilter</literal>. The
+        <literal>sendRenew</literal> defaults to false, but should be set to
+        true if your application is particularly sensitive. What this
+        parameter does is tell the CAS login service that a single sign on
+        login is unacceptable. Instead, the user will need to re-enter their
+        username and password in order to gain access to the service.</para>
+
+        <para>The following beans should be configured to commence the CAS
+        authentication process:</para>
+
+        <para><programlisting>&lt;bean id="casProcessingFilter" class="net.sf.acegisecurity.ui.cas.CasProcessingFilter"&gt;
+  &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
+  &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/casfailed.jsp&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
+  &lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
+  &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="casProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="casProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.cas.CasProcessingFilterEntryPoint"&gt;
+  &lt;property name="loginUrl"&gt;&lt;value&gt;https://localhost:8443/cas/login&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
+&lt;/bean&gt;</programlisting></para>
+
+        <para>You will also need to add the
+        <literal>CasProcessingFilter</literal> to web.xml:</para>
+
+        <para><programlisting>&lt;filter&gt;
+  &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
+  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
+  &lt;init-param&gt;
+    &lt;param-name&gt;targetClass&lt;/param-name&gt;
+    &lt;param-value&gt;net.sf.acegisecurity.ui.cas.CasProcessingFilter&lt;/param-value&gt;
+  &lt;/init-param&gt;
+&lt;/filter&gt;
+
+&lt;filter-mapping&gt;
+  &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
+  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+&lt;/filter-mapping&gt;</programlisting></para>
+
+        <para>The <literal>CasProcessingFilter</literal> has very similar
+        properties to the <literal>AuthenticationProcessingFilter</literal>
+        (used for form-based logins). Each property is
+        self-explanatory.</para>
+
+        <para>For CAS to operate, the
+        <literal>SecurityEnforcementFilter</literal> must have its
+        <literal>authenticationEntryPoint</literal> property set to the
+        <literal>CasProcessingFilterEntryPoint</literal> bean.</para>
+
+        <para>The <literal>CasProcessingFilterEntryPoint</literal> must refer
+        to the <literal>ServiceProperties</literal> bean (discussed above),
+        which provides the URL to the enterprise's CAS login server. This is
+        where the user's browser will be redirected.</para>
+
+        <para>Next you need to add an <literal>AuthenticationManager</literal>
+        that uses <literal>CasAuthenticationProvider</literal> and its
+        collaborators:</para>
+
+        <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
+  &lt;property name="providers"&gt;
+    &lt;list&gt;
+      &lt;ref bean="casAuthenticationProvider"/&gt;
+    &lt;/list&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="casAuthenticationProvider" class="net.sf.acegisecurity.providers.cas.CasAuthenticationProvider"&gt;
+  &lt;property name="casAuthoritiesPopulator"&gt;&lt;ref bean="casAuthoritiesPopulator"/&gt;&lt;/property&gt;
+  &lt;property name="casProxyDecider"&gt;&lt;ref bean="casProxyDecider"/&gt;&lt;/property&gt;
+  &lt;property name="ticketValidator"&gt;&lt;ref bean="casProxyTicketValidator"/&gt;&lt;/property&gt;
+  &lt;property name="statelessTicketCache"&gt;&lt;ref bean="statelessTicketCache"/&gt;&lt;/property&gt;
+  &lt;property name="key"&gt;&lt;value&gt;my_password_for_this_auth_provider_only&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="casProxyTicketValidator" class="net.sf.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator"&gt;
+  &lt;property name="casValidate"&gt;&lt;value&gt;https://localhost:8443/cas/proxyValidate&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="proxyCallbackUrl"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/casProxy/receptor&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
+  &lt;!-- &lt;property name="trustStore"&gt;&lt;value&gt;/some/path/to/your/lib/security/cacerts&lt;/value&gt;&lt;/property&gt; --&gt;
+&lt;/bean&gt;
+
+&lt;bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"&gt;
+  &lt;property name="minutesToIdle"&gt;&lt;value&gt;20&lt;/value&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
+  &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="casProxyDecider" class="net.sf.acegisecurity.providers.cas.proxy.RejectProxyTickets"/&gt;</programlisting></para>
+
+        <para>The beans are all reasonable self-explanatory if you refer back
+        to the "How CAS Works" section. Careful readers might notice one
+        surprise: the <literal>statelessTicketCache</literal> property of the
+        <literal>CasAuthenticationProvider</literal>. This is discussed in
+        detail in the "Advanced CAS Usage" section.</para>
+
+        <para>Note the <literal>CasProxyTicketValidator</literal> has a
+        remarked out <literal>trustStore</literal> property. This property
+        might be helpful if you experience HTTPS certificate issues. Also note
+        the <literal>proxyCallbackUrl</literal> is set so the service can
+        receive a proxy-granting ticket. As mentioned above, this is optional
+        and unnecessary if you do not require proxy-granting tickets. If you
+        do use this feature, you will need to configure a suitable servlet to
+        receive the proxy-granting tickets. We suggest you use CAS'
+        <literal>ProxyTicketReceptor</literal> by adding the following to your
+        web application's <literal>web.xml</literal>:</para>
+
+        <para><programlisting>&lt;servlet&gt;
+  &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
+  &lt;servlet-class&gt;edu.yale.its.tp.cas.proxy.ProxyTicketReceptor&lt;/servlet-class&gt;
+&lt;/servlet&gt;
+
+&lt;servlet-mapping&gt;
+  &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
+  &lt;url-pattern&gt;/casProxy/*&lt;/url-pattern&gt;
+&lt;/servlet-mapping&gt;</programlisting></para>
+
+        <para>This completes the configuration of CAS. If you haven't made any
+        mistakes, your web application should happily work within the
+        framework of CAS single sign on. No other parts of the Acegi Security
+        System for Spring need to be concerned about the fact CAS handled
+        authentication.</para>
+
+        <para>There is also a <literal>contacts-cas.war</literal> file in the
+        sample applications directory. This sample application uses the above
+        settings and can be deployed to see CAS in operation.</para>
+      </sect2>
+
+      <sect2 id="security-cas-advanced-usage">
+        <title>Advanced CAS Usage</title>
+
+        <para>The <literal>CasAuthenticationProvider</literal> distinguishes
+        between stateful and stateless clients. A stateful client is
+        considered any that originates via the
+        <literal>CasProcessingFilter</literal>. A stateless client is any that
+        presents an authentication request via the
+        <literal>UsernamePasswordAuthenticationToken</literal> with a
+        principal equal to
+        <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>.</para>
+
+        <para>Stateless clients are likely to be via remoting protocols such
+        as Hessian and Burlap. The <literal>BasicProcessingFilter</literal> is
+        still used in this case, but the remoting protocol client is expected
+        to present a username equal to the static string above, and a password
+        equal to a CAS service ticket. Clients should acquire a CAS service
+        ticket directly from the CAS server.</para>
+
+        <para>Because remoting protocols have no way of presenting themselves
+        within the context of a <literal>HttpSession</literal>, it isn't
+        possible to rely on the <literal>HttpSession</literal>'s
+        <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>
+        attribute to locate the <literal>CasAuthenticationToken</literal>.
+        Furthermore, because the CAS server invalidates a service ticket after
+        it has been validated by the <literal>TicketValidator</literal>,
+        presenting the same service ticket on subsequent requests will not
+        work. It is similarly very difficult to obtain a proxy-granting ticket
+        for a remoting protocol client, as they are often deployed on client
+        machines which rarely have HTTPS URLs that would be accessible to the
+        CAS server.</para>
+
+        <para>One obvious option is to not use CAS at all for remoting
+        protocol clients. However, this would eliminate many of the desirable
+        features of CAS.</para>
+
+        <para>As a middle-ground, the
+        <literal>CasAuthenticationProvider</literal> uses a
+        <literal>StatelessTicketCache</literal>. This is used solely for
+        requests with a principal equal to
+        <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>. What
+        happens is the <literal>CasAuthenticationProvider</literal> will store
+        the resulting <literal>CasAuthenticationToken</literal> in the
+        <literal>StatelessTicketCache</literal>, keyed on the service ticket.
+        Accordingly, remoting protocol clients can present the same service
+        ticket and the <literal>CasAuthenticationProvider</literal> will not
+        need to contact the CAS server for validation (aside from the first
+        request).</para>
+
+        <para>The other aspect of advanced CAS usage involves creating proxy
+        tickets from the proxy-granting ticket. As indicated above, we
+        recommend you use CAS' <literal>ProxyTicketReceptor</literal> to
+        receive these tickets. The <literal>ProxyTicketReceptor</literal>
+        provides a static method that enables you to obtain a proxy ticket by
+        presenting the proxy-granting IOU ticket. You can obtain the
+        proxy-granting IOU ticket by calling
+        <literal>CasAuthenticationToken.getProxyGrantingTicketIou()</literal>.</para>
+
+        <para>It is hoped you find CAS integration easy and useful with the
+        Acegi Security System for Spring classes. Welcome to enterprise-wide
+        single sign on!</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-channels">
+      <title>Channel Security</title>
+
+      <sect2 id="security-channels-overview">
+        <title>Overview</title>
+
+        <para>In addition to coordinating the authentication and authorization
+        requirements of your application, the Acegi Security System for Spring
+        is also able to ensure unauthenticated web requests have certain
+        properties. These properties may include being of a particular
+        transport type, having a particular <literal>HttpSession</literal>
+        attribute set and so on. The most common requirement is for your web
+        requests to be received using a particular transport protocol, such as
+        HTTPS.</para>
+
+        <para>An important issue in considering transport security is that of
+        session hijacking. Your web container manages a
+        <literal>HttpSession</literal> by reference to a
+        <literal>jsessionid</literal> that is sent to user agents either via a
+        cookie or URL rewriting. If the <literal>jsessionid</literal> is ever
+        sent over HTTP, there is a possibility that session identifier can be
+        intercepted and used to impersonate the user after they complete the
+        authentication process. This is because most web containers maintain
+        the same session identifier for a given user, even after they switch
+        from HTTP to HTTPS pages.</para>
+
+        <para>If session hijacking is considered too significant a risk for
+        your particular application, the only option is to use HTTPS for every
+        request. This means the <literal>jsessionid</literal> is never sent
+        across an insecure channel. You will need to ensure your
+        <literal>web.xml</literal>-defined
+        <literal>&lt;welcome-file&gt;</literal> points to a HTTPS location,
+        and the application never directs the user to a HTTP location. The
+        Acegi Security System for Spring provides a solution to assist with
+        the latter.</para>
+      </sect2>
+
+      <sect2 id="security-channels-installation">
+        <title>Configuration</title>
+
+        <para>To utilise Acegi Security's channel security services, add the
+        following lines to <literal>web.xml</literal>:</para>
+
+        <para><programlisting>&lt;filter&gt;
+  &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
+  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
+  &lt;init-param&gt;
+    &lt;param-name&gt;targetClass&lt;/param-name&gt;
+    &lt;param-value&gt;net.sf.acegisecurity.securechannel.ChannelProcessingFilter&lt;/param-value&gt;
+  &lt;/init-param&gt;
+&lt;/filter&gt;
+
+&lt;filter-mapping&gt;
+  &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
+  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+&lt;/filter-mapping&gt;</programlisting></para>
+
+        <para>As usual when running <literal>FilterToBeanProxy</literal>, you
+        will also need to configure the filter in your application
+        context:</para>
+
+        <para><programlisting>&lt;bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter"&gt;
+  &lt;property name="channelDecisionManager"&gt;&lt;ref bean="channelDecisionManager"/&gt;&lt;/property&gt;
+  &lt;property name="filterInvocationDefinitionSource"&gt;
+    &lt;value&gt;
+      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+      \A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
+      \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
+      \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL	
+      \A.*\Z=REQUIRES_INSECURE_CHANNEL
+    &lt;/value&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"&gt;
+  &lt;property name="channelProcessors"&gt;
+    &lt;list&gt;
+      &lt;ref bean="secureChannelProcessor"/&gt;
+      &lt;ref bean="insecureChannelProcessor"/&gt;
+    &lt;/list&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/&gt;
+&lt;bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/&gt;</programlisting></para>
+
+        <para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
+        style paths are also supported by the
+        <literal>ChannelProcessingFilter</literal>.</para>
+
+        <para>The <literal>ChannelProcessingFilter</literal> operates by
+        filtering all web requests and determining the configuration
+        attributes that apply. It then delegates to the
+        <literal>ChannelDecisionManager</literal>. The default implementation,
+        <literal>ChannelDecisionManagerImpl</literal>, should suffice in most
+        cases. It simply delegates through the list of configured
+        <literal>ChannelProcessor</literal> instances. A
+        <literal>ChannelProcessor</literal> will review the request, and if it
+        is unhappy with the request (eg it was received across the incorrect
+        transport protocol), it will perform a redirect, throw an exception or
+        take whatever other action is appropriate.</para>
+
+        <para>Included with the Acegi Security System for Spring are two
+        concrete <literal>ChannelProcessor</literal> implementations:
+        <literal>SecureChannelProcessor</literal> ensures requests with a
+        configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
+        are received over HTTPS, whilst
+        <literal>InsecureChannelProcessor</literal> ensures requests with a
+        configuration attribute of
+        <literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
+        Both implementations delegate to a
+        <literal>ChannelEntryPoint</literal> if the required transport
+        protocol is not used. The two <literal>ChannelEntryPoint</literal>
+        implementations included with Acegi Security simply redirect the
+        request to HTTP and HTTPS as appropriate. Appropriate defaults are
+        assigned to the <literal>ChannelProcessor</literal> implementations
+        for the configuration attribute keywords they respond to and the
+        <literal>ChannelEntryPoint</literal> they delegate to, although you
+        have the ability to override these using the application
+        context.</para>
+
+        <para>Note that the redirections are absolute (eg
+        http://www.company.com:8080/app/page), not relative (eg /app/page).
+        During testing it was discovered that Internet Explorer 6 Service Pack
+        1 has a bug whereby it does not respond correctly to a redirection
+        instruction which also changes the port to use. Accordingly, absolute
+        URLs are used in conjunction with bug detection logic in the
+        <literal>PortResolverImpl</literal> that is wired up by default to
+        many Acegi Security beans. Please refer to the JavaDocs for
+        <literal>PortResolverImpl</literal> for further details.</para>
+      </sect2>
+
+      <sect2 id="security-channels-usage">
+        <title>Usage</title>
+
+        <para>Once configured, using the channel security filter is very easy.
+        Simply request pages without regard to the protocol (ie HTTP or HTTPS)
+        or port (eg 80, 8080, 443, 8443 etc). Obviously you'll still need a
+        way of making the initial request (probably via the
+        <literal>web.xml</literal> <literal>&lt;welcome-file&gt;</literal> or
+        a well-known home page URL), but once this is done the filter will
+        perform redirects as defined by your application context.</para>
+
+        <para>You can also add your own <literal>ChannelProcessor</literal>
+        implementations to the <literal>ChannelDecisionManagerImpl</literal>.
+        For example, you might set a <literal>HttpSession</literal> attribute
+        when a human user is detected via a "enter the contents of this
+        graphic" procedure. Your <literal>ChannelProcessor</literal> would
+        respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration
+        attributes and redirect to an appropriate entry point to start the
+        human user validation process if the <literal>HttpSession</literal>
+        attribute is not currently set.</para>
+
+        <para>To decide whether a security check belongs in a
+        <literal>ChannelProcessor</literal> or an
+        <literal>AccessDecisionVoter</literal>, remember that the former is
+        designed to handle unauthenticated requests, whilst the latter is
+        designed to handle authenticated requests. The latter therefore has
+        access to the granted authorities of the authenticated principal. In
+        addition, problems detected by a <literal>ChannelProcessor</literal>
+        will generally cause a HTTP/HTTPS redirection so its requirements can
+        be met, whilst problems detected by an
+        <literal>AccessDecisionVoter</literal> will ultimately result in an
+        <literal>AccessDeniedException</literal> (depending on the governing
+        <literal>AccessDecisionManager</literal>).</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="acls">
+      <title>Instance-Based Access Control List (ACL) Security</title>
+
+      <sect2 id="acls-overview">
+        <title>Overview</title>
+
+        <para>THIS FEATURE WAS ADDED IN VERSION 0.6. WE WELCOME YOUR COMMENTS
+        AND IMPROVEMENTS.</para>
+
+        <para>Complex applications often will find the need to define access
+        permissions not simply at a web request or method invocation level.
+        Instead, security decisions need to comprise both who
+        (<literal>Authentication</literal>), where
+        (<literal>MethodInvocation</literal>) and what
+        (<literal>SomeDomainObject</literal>). In other words, authorization
+        decisions also need to consider the actual domain object instance
+        subject of a method invocation.</para>
+
+        <para>Imagine you're designing an application for a pet clinic. There
+        will be two main groups of users of your Spring-based application:
+        staff of the pet clinic, as well as the pet clinic's customers. The
+        staff will have access to all of the data, whilst your customers will
+        only be able to see their own customer records. To make it a little
+        more interesting, your customers can allow other users to see their
+        customer records, such as their "puppy preschool "mentor or president
+        of their local "Pony Club". Using Acegi Security System for Spring as
+        the foundation, you have several approaches that can be
+        used:<orderedlist>
+            <listitem>
+              <para>Write your business methods to enforce the security. You
+              could consult a collection within the
+              <literal>Customer</literal> domain object instance to determine
+              which users have access. By using the
+              <literal>ContextHolder.getContext()</literal> and casting it to
+              <literal>SecureContext</literal>, you'll be able to access the
+              <literal>Authentication</literal> object.</para>
+            </listitem>
+
+            <listitem>
+              <para>Write an <literal>AccessDecisionVoter</literal> to enforce
+              the security from the <literal>GrantedAuthority[]</literal>s
+              stored in the <literal>Authentication</literal> object. This
+              would mean your <literal>AuthenticationManager</literal> would
+              need to populate the <literal>Authentication</literal> with
+              custom <literal>GrantedAuthority</literal>[]s representing each
+              of the <literal>Customer</literal> domain object instances the
+              principal has access to.</para>
+            </listitem>
+
+            <listitem>
+              <para>Write an <literal>AccessDecisionVoter</literal> to enforce
+              the security and open the target <literal>Customer</literal>
+              domain object directly. This would mean your voter needs access
+              to a DAO that allows it to retrieve the
+              <literal>Customer</literal> object. It would then access the
+              <literal>Customer</literal> object's collection of approved
+              users and make the appropriate decision.</para>
+            </listitem>
+          </orderedlist></para>
+
+        <para>Each one of these approaches is perfectly legitimate. However,
+        the first couples your authorization checking to your business code.
+        The main problems with this include the enhanced difficulty of unit
+        testing and the fact it would be more difficult to reuse the
+        <literal>Customer</literal> authorization logic elsewhere. Obtaining
+        the <literal>GrantedAuthority[]</literal>s from the
+        <literal>Authentication</literal> object is also fine, but will not
+        scale to large numbers of <literal>Customer</literal>s. If a user
+        might be able to access 5,000 <literal>Customer</literal>s (unlikely
+        in this case, but imagine if it were a popular vet for a large Pony
+        Club!) the amount of memory consumed and time required to construct
+        the <literal>Authentication</literal> object would be undesirable. The
+        final method, opening the <literal>Customer</literal> directly from
+        external code, is probably the best of the three. It achieves
+        separation of concerns, and doesn't misuse memory or CPU cycles, but
+        it is still inefficient in that both the
+        <literal>AccessDecisionVoter</literal> and the eventual business
+        method itself will perform a call to the DAO responsible for
+        retrieving the <literal>Customer</literal> object. Two accesses per
+        method invocation is clearly undesirable. In addition, with every
+        approach listed you'll need to write your own access control list
+        (ACL) persistence and business logic from scratch.</para>
+
+        <para>Fortunately, there is another alternative, which we'll talk
+        about below.</para>
+      </sect2>
+
+      <sect2 id="acls-acl-package">
+        <title>The net.sf.acegisecurity.acl Package</title>
+
+        <para>The <literal>net.sf.acegisecurity.acl</literal> package is very
+        simple, comprising only a handful of interfaces and a single class. It
+        provides the basic foundation for access control list (ACL) lookups.
+        The central interface is <literal>AclManager</literal>, which is
+        defined by two methods:</para>
+
+        <para><programlisting>public AclEntry[] getAcls(java.lang.Object domainInstance);
+public AclEntry[] getAcls(java.lang.Object domainInstance, Authentication authentication);</programlisting></para>
+
+        <para><literal>AclManager</literal> is intended to be used as a
+        collaborator against your business objects, or, more desirably,
+        <literal>AccessDecisionVoter</literal>s. This means you use Spring's
+        normal <literal>ApplicationContext</literal> features to wire up your
+        <literal>AccessDecisionVoter</literal> (or business method) with an
+        <literal>AclManager</literal>. Consideration was given to placing the
+        ACL information in the <literal>ContextHolder</literal>, but it was
+        felt this would be inefficient both in terms of memory usage as well
+        as the time spent loading potentially unused ACL information. The
+        trade-off of needing to wire up a collaborator for those objects
+        requiring ACL information is rather minor, particularly in a
+        Spring-managed application.</para>
+
+        <para>The first method of the <literal>AclManager</literal> will
+        return all ACLs applying to the domain object instance passed to it.
+        The second method does the same, but only returns those ACLs which
+        apply to the passed <literal>Authentication</literal> object.</para>
+
+        <para>The <literal>AclEntry</literal> interface returned by
+        <literal>AclManager</literal> is merely a marker interface. You will
+        need to provide an implementation that reflects that ACL permissions
+        for your application.</para>
+
+        <para>Rounding out the <literal>net.sf.acegisecurity.acl</literal>
+        package is an <literal>AclProviderManager</literal> class, with a
+        corresponding <literal>AclProvider</literal> interface.
+        <literal>AclProviderManager</literal> is a concrete implementation of
+        <literal>AclManager</literal>, which iterates through registered
+        <literal>AclProvider</literal>s. The first
+        <literal>AclProvider</literal> that indicates it can authoritatively
+        provide ACL information for the presented domain object instance will
+        be used. This is very similar to the
+        <literal>AuthenticationProvider</literal> interface used for
+        authentication.</para>
+
+        <para>With this background, let's now look at a usable ACL
+        implementation.</para>
+      </sect2>
+
+      <sect2 id="acls-masking">
+        <title>Integer Masked ACLs</title>
+
+        <para>Acegi Security System for Spring includes a production-quality
+        ACL provider implementation. The implementation is based on integer
+        masking, which is commonly used for ACL permissions given its
+        flexibility and speed. Anyone who has used Unix's
+        <literal>chmod</literal> command will know all about this type of
+        permission masking (eg <literal>chmod 777</literal>). You'll find the
+        classes and interfaces for the integer masking ACL package under
+        <literal>net.sf.acegisecurity.acl.basic</literal>.</para>
+
+        <para>Extending the <literal>AclEntry</literal> interface is a
+        <literal>BasicAclEntry</literal> interface, with the main methods
+        shown below:</para>
+
+        <para><programlisting>public AclObjectIdentity getAclObjectIdentity();
+public AclObjectIdentity getAclObjectParentIdentity();
+public int getMask();
+public java.lang.Object getRecipient();</programlisting></para>
+
+        <para>As shown, each <literal>BasicAclEntry</literal> has four main
+        properties. The <literal>mask</literal> is the integer that represents
+        the permissions granted to the <literal>recipient</literal>. The
+        <literal>aclObjectIdentity</literal> is able to identify the domain
+        object instance for which the ACL applies, and the
+        <literal>aclObjectParentIdentity</literal> optionally specifies the
+        parent of the domain object instance. Multiple
+        <literal>BasicAclEntry</literal>s usually exist against a single
+        domain object instance, and as suggested by the parent identity
+        property, permissions granted higher in the object hierarchy will
+        trickle down and be inherited (unless blocked by integer zero).</para>
+
+        <para><literal>BasicAclEntry</literal> implementations typically
+        provide convenience methods, such as
+        <literal>isReadAllowed()</literal>, to avoid application classes
+        needing to perform bit masking themselves. The
+        <literal>SimpleAclEntry</literal> and
+        <literal>AbstractBasicAclEntry</literal> demonstrate and provide much
+        of this bit masking logic.</para>
+
+        <para>The <literal>AclObjectIdentity</literal> itself is merely a
+        marker interface, so you need to provide implementations for your
+        domain objects. However, the package does include a
+        <literal>NamedEntityObjectIdentity</literal> implementation which will
+        suit many needs. The <literal>NamedEntityObjectIdentity</literal>
+        identifies a given domain object instance by the classname of the
+        instance and the identity of the instance. A
+        <literal>NamedEntityObjectIdentity</literal> can be constructed
+        manually (by calling the constructor and providing the classname and
+        identity <literal>String</literal>s), or by passing in any domain
+        object that contains a <literal>getId()</literal> method.</para>
+
+        <para>The actual <literal>AclProvider</literal> implementation is
+        named <literal>BasicAclProvider</literal>. It has adopted a similar
+        design to that used by the authentication-related
+        <literal>DaoAuthenticationProvder</literal>. Specifically, you define
+        a <literal>BasicAclDao</literal> against the provider, so different
+        ACL repository types can be accessed in a pluggable manner. The
+        <literal>BasicAclProvider</literal> also supports pluggable cache
+        providers (with Acegi Security System for Spring including an
+        implementation that fronts EH-CACHE).</para>
+
+        <para>The <literal>BasicAclDao</literal> interface is very simple to
+        implement:</para>
+
+        <para><programlisting>public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);</programlisting></para>
+
+        <para>A <literal>BasicAclDao</literal> implementation needs to
+        understand the presented <literal>AclObjectIdentity</literal> and how
+        it maps to a storage repository, find the relevant records, and create
+        appropriate <literal>BasicAclEntry</literal> objects and return
+        them.</para>
+
+        <para>Acegi Security includes a single <literal>BasicAclDao</literal>
+        implementation called <literal>JdbcDaoImpl</literal>. As implied by
+        the name, it accesses ACL information from a JDBC database. The
+        default database schema and some sample data will aid in understanding
+        its function:</para>
+
+        <para><programlisting>CREATE TABLE acl_object_identity (
+     id IDENTITY NOT NULL,
+     object_identity VARCHAR_IGNORECASE(250) NOT NULL,
+     parent_object INTEGER,
+     acl_class VARCHAR_IGNORECASE(250) NOT NULL,
+     CONSTRAINT unique_object_identity UNIQUE(object_identity),
+     FOREIGN KEY (parent_object) REFERENCES acl_object_identity(id)
+);
+
+CREATE TABLE acl_permission (
+     id IDENTITY NOT NULL,
+     acl_object_identity INTEGER NOT NULL,
+     recipient VARCHAR_IGNORECASE(100) NOT NULL,
+     mask INTEGER NOT NULL,
+     CONSTRAINT unique_recipient UNIQUE(acl_object_identity, recipient),
+     FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id)
+);
+
+INSERT INTO acl_object_identity VALUES (1, 'corp.DomainObject:1', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
+INSERT INTO acl_object_identity VALUES (2, 'corp.DomainObject:2', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
+INSERT INTO acl_object_identity VALUES (3, 'corp.DomainObject:3', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
+INSERT INTO acl_object_identity VALUES (4, 'corp.DomainObject:4', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
+INSERT INTO acl_object_identity VALUES (5, 'corp.DomainObject:5', 3, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
+INSERT INTO acl_object_identity VALUES (6, 'corp.DomainObject:6', 3, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
+
+INSERT INTO acl_permission VALUES (null, 1, 'ROLE_SUPERVISOR', 1);
+INSERT INTO acl_permission VALUES (null, 2, 'ROLE_SUPERVISOR', 0);
+INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);
+INSERT INTO acl_permission VALUES (null, 3, 'scott', 14);
+INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
+
+        <para>As can be seen, database-specific constraints are used
+        extensively to ensure the integrity of the ACL information. If you
+        need to use a different database (Hypersonic SQL statements are shown
+        above), you should try to implement equivalent constraints.</para>
+
+        <para>The <literal>JdbcDaoImpl</literal> will only respond to requests
+        for <literal>NamedEntityObjectIdentity</literal>s. It converts such
+        identities into a single <literal>String</literal>, comprising
+        the<literal> NamedEntityObjectIdentity.getClassname()</literal> +
+        <literal>":"</literal> +
+        <literal>NamedEntityObjectIdentity.getId()</literal>. This yields the
+        type of <literal>object_identity</literal> values shown above. As
+        indicated by the sample data, each database row corresponds to a
+        single <literal>BasicAclEntry</literal>. As stated earlier and
+        demonstrated by <literal>corp.DomainObject:2</literal> in the above
+        sample data, each domain object instance will often have multiple
+        <literal>BasicAclEntry</literal>[]s.</para>
+
+        <para>As <literal>JdbcDaoImpl</literal> is required to return concrete
+        <literal>BasicAclEntry</literal> classes, it needs to know which
+        <literal>BasicAclEntry</literal> implementation it is to create and
+        populate. This is the role of the <literal>acl_class</literal> column.
+        <literal>JdbcDaoImpl</literal> will create the indicated class and set
+        its <literal>mask</literal>, <literal>recipient</literal>,
+        <literal>aclObjectIdentity</literal> and
+        <literal>aclObjectParentIdentity</literal> properties.</para>
+
+        <para>As you can probably tell from the sample data, the
+        <literal>parent_object_identity</literal> value can either be null or
+        in the same format as the <literal>object_identity</literal>. If
+        non-null, <literal>JdbcDaoImpl</literal> will create a
+        <literal>NamedEntityObjectIdentity</literal> to place inside the
+        returned <literal>BasicAclEntry</literal> class.</para>
+
+        <para>Returning to the <literal>BasicAclProvider</literal>, before it
+        can poll the <literal>BasicAclDao</literal> implementation it needs to
+        convert the domain object instance it was passed into an
+        <literal>AclObjectIdentity</literal>.
+        <literal>BasicAclProvider</literal> has a <literal>protected
+        AclObjectIdentity obtainIdentity(Object domainInstance)</literal>
+        method that is responsible for this. As a protected method, it enables
+        subclasses to easily override. The normal implementation checks
+        whether the passed domain object instance implements the
+        <literal>AclObjectIdentityAware</literal> interface, which is merely a
+        getter for an <literal>AclObjectIdentity</literal>. If the domain
+        object does implement this interface, that is the identity returned.
+        If the domain object does not implement this interface, the method
+        will attempt to create an <literal>AclObjectIdentity</literal> by
+        passing the domain object instance to the constructor of a class
+        defined by the
+        <literal>BasicAclProvider.getDefaultAclObjectIdentity()</literal>
+        method. By default the defined class is
+        <literal>NamedEntityObjectIdentity</literal>, which was described in
+        more detail above. Therefore, you will need to either (i) provide a
+        <literal>getId()</literal> method on your domain objects, (ii)
+        implement <literal>AclObjectIdentityAware</literal> on your domain
+        objects, (iii) provide an alternative
+        <literal>AclObjectIdentity</literal> implementation that will accept
+        your domain object in its constructor, or (iv) override the
+        <literal>obtainIdentity(Object)</literal> method.</para>
+
+        <para>Once the <literal>AclObjectIdentity</literal> of the domain
+        object instance is determined, the <literal>BasicAclProvider</literal>
+        will poll the DAO to obtain its <literal>BasicAclEntry</literal>[]s.
+        If any of the entries returned by the DAO indicate there is a parent,
+        that parent will be polled, and the process will repeat until there is
+        no further parent. The permissions assigned to a
+        <literal>recipient</literal> closest to the domain object instance
+        will always take priority and override any inherited permissions. From
+        the sample data above, the following inherited permissions would
+        apply:</para>
+
+        <para><programlisting>--- Mask integer 0  = no permissions
+--- Mask integer 1  = administer
+--- Mask integer 2  = read
+--- Mask integer 6  = read and write permissions
+--- Mask integer 14 = read and write and create permissions
+
+---------------------------------------------------------------------
+--- *** INHERITED RIGHTS FOR DIFFERENT INSTANCES AND RECIPIENTS ***
+--- INSTANCE  RECIPIENT         PERMISSION(S) (COMMENT #INSTANCE)
+---------------------------------------------------------------------
+---    1      ROLE_SUPERVISOR   Administer
+---    2      ROLE_SUPERVISOR   None (overrides parent #1)
+---           marissa           Read
+---    3      ROLE_SUPERVISOR   Administer (from parent #1)
+---           scott             Read, Write, Create
+---    4      ROLE_SUPERVISOR   Administer (from parent #1)
+---    5      ROLE_SUPERVISOR   Administer (from parent #3)
+---           scott             Read, Write, Create (from parent #3)
+---    6      ROLE_SUPERVISOR   Administer (from parent #3)
+---           scott             Administer (overrides parent #3)</programlisting></para>
+
+        <para>So the above explains how a domain object instance has its
+        <literal>AclObjectIdentity</literal> discovered, and the
+        <literal>BasicAclDao</literal> will be polled successively until an
+        array of inherited permissions is constructed for the domain object
+        instance. The final step is to determine the
+        <literal>BasicAclEntry</literal>[]s that are actually applicable to a
+        given <literal>Authentication</literal> object.</para>
+
+        <para>As you would recall, the <literal>AclManager</literal> (and all
+        delegates, up to and including <literal>BasicAclProvider</literal>)
+        provides a method which returns only those
+        <literal>BasicAclEntry</literal>[]s applying to a passed
+        <literal>Authentication</literal> object.
+        <literal>BasicAclProvider</literal> delivers this functionality by
+        delegating the filtering operation to an
+        <literal>EffectiveAclsResolver</literal> implementation. The default
+        implementation,
+        <literal>GrantedAuthorityEffectiveAclsResolver</literal>, will iterate
+        through the <literal>BasicAclEntry</literal>[]s and include only those
+        where the <literal>recipient</literal> is equal to either the
+        <literal>Authentication</literal>'s <literal>principal</literal> or
+        any of the <literal>Authentication</literal>'s
+        <literal>GrantedAuthority</literal>[]s. Please refer to the JavaDocs
+        for more information.</para>
+      </sect2>
+
+      <sect2 id="acls-conclusion">
+        <title>Conclusion</title>
+
+        <para>Acegi Security's instance-specific ACL packages shield you from
+        much of the complexity of developing your own ACL approach. The
+        interfaces and classes detailed above provide a scalable, customisable
+        ACL solution that is decoupled from your application code. Whilst the
+        reference documentation may suggest complexity, the basic
+        implementation is able to support most typical applications
+        out-of-the-box.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-filters">
+      <title>Filters</title>
+
+      <sect2 id="security-filters-overview">
+        <title>Overview</title>
+
+        <para>The Acegi Security System for Spring uses filters extensively.
+        Each filter is covered in detail in a respective section of this
+        document. This section includes information that applies to all
+        filters.</para>
+      </sect2>
+
+      <sect2 id="security-filters-filtertobeanproxy">
+        <title>FilterToBeanProxy</title>
+
+        <para>Most filters are configured using the
+        <literal>FilterToBeanProxy</literal>. An example configuration from
+        <literal>web.xml</literal> follows:</para>
+
+        <para><programlisting>&lt;filter&gt;
+  &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
+  &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
+  &lt;init-param&gt;
+    &lt;param-name&gt;targetClass&lt;/param-name&gt;
+    &lt;param-value&gt;net.sf.acegisecurity.ClassThatImplementsFilter&lt;/param-value&gt;
+  &lt;/init-param&gt;
+&lt;/filter&gt;</programlisting></para>
+
+        <para>Notice that the filter in <literal>web.xml</literal> is actually
+        a <literal>FilterToBeanProxy</literal>, and not the filter that will
+        actually implements the logic of the filter. What
+        <literal>FilterToBeanProxy</literal> does is delegate the
+        <literal>Filter</literal>'s methods through to a bean which is
+        obtained from the Spring application context. This enables the bean to
+        benefit from the Spring application context lifecycle support and
+        configuration flexibility. The bean must implement
+        <literal>javax.servlet.Filter</literal>.</para>
+
+        <para>The <literal>FilterToBeanProxy</literal> only requires a single
+        initialization parameter, <literal>targetClass</literal> or
+        <literal>targetBean</literal>. The <literal>targetClass</literal>
+        parameter locates the first object in the application context of the
+        specified class, whilst <literal>targetBean</literal> locates the
+        object by bean name. Like standard Spring web applications, the
+        <literal>FilterToBeanProxy</literal> accesses the application context
+        via<literal>
+        WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>,
+        so you should configure a <literal>ContextLoaderListener</literal> in
+        <literal>web.xml</literal>.</para>
+      </sect2>
+
+      <sect2 id="security-filters-order">
+        <title>Filter Ordering</title>
+
+        <para>The order that filters are defined in <literal>web.xml</literal>
+        is important.</para>
+
+        <para>Irrespective of which filters you are actually using, the order
+        of the <literal>&lt;filter-mapping&gt;</literal>s should be as
+        follows:</para>
+
+        <orderedlist>
+          <listitem>
+            <para>Acegi Channel Processing Filter
+            (<literal>ChannelProcessingFilter</literal>)</para>
+          </listitem>
+
+          <listitem>
+            <para>Acegi Authentication Processing Filter
+            (<literal>AuthenticationProcessingFilter</literal>)</para>
+          </listitem>
+
+          <listitem>
+            <para>Acegi CAS Processing Filter
+            (<literal>CasProcessingFilter</literal>)</para>
+          </listitem>
+
+          <listitem>
+            <para>Acegi HTTP BASIC Authorization Filter
+            (<literal>BasicProcessingFilter</literal>)</para>
+          </listitem>
+
+          <listitem>
+            <para>Acegi Security System for Spring Auto Integration Filter
+            (<literal>AutoIntegrationFilter</literal>)</para>
+          </listitem>
+
+          <listitem>
+            <para>Acegi HTTP Request Security Filter
+            (<literal>SecurityEnforcementFilter</literal>)</para>
+          </listitem>
+        </orderedlist>
+
+        <para>All of the above filters use
+        <literal>FilterToBeanProxy</literal>, which is discussed in the
+        previous section.</para>
+
+        <para>If you're using SiteMesh, ensure the Acegi Security filters
+        execute before the SiteMesh filters are called. This enables the
+        <literal>ContextHolder</literal> to be populated in time for use by
+        SiteMesh decorators.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="security-sample">
+      <title>Contacts Sample Application</title>
+
+      <para>Included with the Acegi Security System for Spring is a very
+      simple application that can demonstrate the basic security facilities
+      provided by the system (and confirm your Container Adapter is properly
+      configured if you're using one).</para>
+
+      <para>The Contacts sample application includes two deployable versions:
+      <literal>contacts.war</literal> is configured with the HTTP Session
+      Authentication approach, and does not use Container Adapters. The
+      <literal>contacts-container-adapter.war</literal> is configured to use a
+      Container Adapter. If you're just wanting to see how the sample
+      application works, please use <literal>contacts.war</literal> as it does
+      not require special configuration of your container.</para>
+
+      <para>If you are going to use the
+      <literal>contacts-container-adapter.war</literal> version, first
+      configure your container as described in the Container Adapters section
+      of this chapter. Do not modify <literal>acegisecurity.xml</literal>. It
+      contains a very basic in-memory authentication configuration that is
+      compatible with the sample application.</para>
+
+      <para>To deploy, simply copy the relevant
+      <literal>contacts.war</literal> or
+      <literal>contacts-container-adapter.war</literal> file from the Acegi
+      Security System for Spring distribution into your container’s
+      <literal>webapps</literal> directory.</para>
+
+      <para>After starting your container, check the application can load.
+      Visit <literal>http://localhost:8080/contacts</literal> (or whichever
+      URL is appropriate for your web container and the WAR you deployed). A
+      random contact should be displayed. Click "Refresh" several times and
+      you will see different contacts. The business method that provides this
+      random contact is not secured.</para>
+
+      <para>Next, click "Debug". You will be prompted to authenticate, and a
+      series of usernames and passwords are suggested on that page. Simply
+      authenticate with any of these and view the resulting page. It should
+      contain a success message similar to the following:</para>
+
+      <blockquote>
+        <para>Context on ContextHolder is of type:
+        net.sf.acegisecurity.context.SecureContextImpl</para>
+
+        <para>The Context implements SecureContext.</para>
+
+        <para>Authentication object is of type:
+        net.sf.acegisecurity.adapters.PrincipalAcegiUserToken</para>
+
+        <para>Authentication object as a String:
+        net.sf.acegisecurity.adapters.PrincipalAcegiUserToken@e9a7c2:
+        Username: marissa; Password: [PROTECTED]; Authenticated: true; Granted
+        Authorities: ROLE_TELLER, ROLE_SUPERVISOR</para>
+
+        <para>Authentication object holds the following granted
+        authorities:</para>
+
+        <para>ROLE_TELLER (getAuthority(): ROLE_TELLER)</para>
+
+        <para>ROLE_SUPERVISOR (getAuthority(): ROLE_SUPERVISOR)</para>
+
+        <para>SUCCESS! Your [container adapter|web filter] appears to be
+        properly configured!</para>
+      </blockquote>
+
+      <para>If you receive a different message, and deployed
+      <literal>contacts-container-adapter.war</literal>, check you have
+      properly configured your Container Adapter. Refer to the instructions
+      provided above.</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 belonging 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>contacts.war</literal>, the
+      <literal>FilterSecurityInterceptor</literal> is also securing the HTTP
+      requests. If using <literal>contacts.war</literal>, be sure to try
+      visiting <literal>http://localhost:8080/contacts/secure/super</literal>,
+      which will demonstrate access being denied by the
+      <literal>SecurityEnforcementFilter</literal>.</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 the Hessian
+      and Burlap protocols. This demonstrates how to use the Acegi Security
+      System for Spring for authentication with Spring remoting protocols. To
+      try this client, ensure your servlet container is still running the
+      Contacts sample application, and then execute <literal>client marissa
+      marissa koala</literal>. The command-line parameters respectively
+      represent the owner of the contacts to extract, 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. To
+      see that security does indeed work, try running <literal>client scott
+      marissa koala</literal>, which will try to obtain
+      <literal>scott</literal>'s contacts when authenticating as
+      <literal>marissa</literal>. To see it work properly, use <literal>client
+      scott scott wombat</literal>.</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 scott _cas_stateless_
+      YOUR-SERVICE-TICKET-ID-FOR-SCOTT</literal>.</para>
+    </sect1>
+
+    <sect1 id="security-become-involved">
+      <title>Become Involved</title>
+
+      <para>We welcome you to become involved in the Acegi Security System for
+      Spring project. There are many ways of contributing, including reading
+      the mailing list and responding to questions from other people, writing
+      new code, improving existing code, assisting with documentation, or
+      simply making suggestions.</para>
+
+      <para>SourceForge provides CVS services for the project, allowing
+      anybody to access the latest code. If you wish to contribute new code,
+      please observe the following requirements. These exist to maintain the
+      quality and consistency of the project:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>Run the Ant <literal>format</literal> task (or use a suitable
+          IDE plug-in) to convert your code into the project's consistent
+          style</para>
+        </listitem>
+
+        <listitem>
+          <para>Ensure your code does not break any unit tests (run the Ant
+          <literal>tests</literal> target)</para>
+        </listitem>
+
+        <listitem>
+          <para>Please use the container integration test system to test your
+          code in the project's officially supported containers</para>
+        </listitem>
+
+        <listitem>
+          <para>When writing a new container adapter, expand the container
+          integration test system to properly test it</para>
+        </listitem>
+
+        <listitem>
+          <para>If you have added new code, please provide suitable unit tests
+          (use <literal>ant clover.html</literal> to view coverage)</para>
+        </listitem>
+
+        <listitem>
+          <para>Join the acegisecurity-developer and acegisecurity-cvs mailing
+          lists so you're in the loop</para>
+        </listitem>
+
+        <listitem>
+          <para>Use CamelCase</para>
+        </listitem>
+
+        <listitem>
+          <para>Add a CVS <literal>$Id: index.xml,v 1.3 2004/04/02 21:12:25
+          fbos Exp $</literal> tag to the JavaDocs for any new class you
+          create</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>Mentioned above is our container integration test system, which
+      aims to test the Acegi Security System for Spring container adapters
+      with current, production versions of each container. Some containers
+      might not be supported due to difficulties with starting or stopping the
+      container within an Ant target. You will need to download the container
+      release files as specified in the integration test
+      <literal>readme.txt</literal> file. These files are intentionally
+      excluded from CVS due to their large size.</para>
+    </sect1>
+
+    <sect1 id="security-further">
+      <title>Further Information</title>
+
+      <para>Questions and comments on the Acegi Security System for Spring are
+      welcome. Please use the Spring Community Forum web site at
+      <literal>http://forum.springframework.org</literal>. You're also welcome
+      to join the acegisecurity-developer mailing list. Our project home page
+      (where you can obtain the latest release of the project and access to
+      CVS, mailing lists, forums etc) is at
+      <literal>http://acegisecurity.sourceforge.net</literal>.</para>
+    </sect1>
+  </chapter>
+</book>

+ 488 - 0
docbook/styles/fo/docbook.xsl

@@ -0,0 +1,488 @@
+<?xml version="1.0"?>
+
+<!-- 
+
+    This is the XSL FO configuration file for the Hibernate
+    Reference Documentation. It defines a custom titlepage and
+    the parameters for the A4 sized PDF printable output.
+    
+    It took me days to figure out this stuff and fix most of
+    the obvious bugs in the DocBook XSL distribution, so if you
+    use this stylesheet, give some credit back to the Hibernate
+    project.
+    
+    christian.bauer@bluemars.de
+-->
+
+<!DOCTYPE xsl:stylesheet [
+    <!ENTITY db_xsl_bak        "docbook-bak.xsl">
+    <!ENTITY admon_gfx_path     "../images/admons/">
+]>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0"
+                xmlns="http://www.w3.org/TR/xhtml1/transitional"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                exclude-result-prefixes="#default">
+                
+<xsl:import href="&db_xsl_bak;"/>
+
+<!--###################################################
+                   Custom Title Page
+    ################################################### --> 
+    
+    <xsl:template name="book.titlepage.recto">
+        <fo:block>
+            <fo:table table-layout="fixed" width="175mm">
+                <fo:table-column column-width="175mm"/>
+                <fo:table-body>
+                    <fo:table-row>
+                        <fo:table-cell text-align="center">
+                            <fo:block>
+                                <fo:external-graphic src="file:images/logo.gif"/>
+                            </fo:block>
+                            <fo:block font-family="Helvetica" font-size="22pt" padding-before="10mm">
+                                <xsl:value-of select="bookinfo/subtitle"/> 
+                            </fo:block>
+                            <fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
+                                <xsl:value-of select="bookinfo/releaseinfo"/>  
+                            </fo:block>
+                        </fo:table-cell>
+                    </fo:table-row>
+                    <fo:table-row>
+                        <fo:table-cell text-align="center">
+                            <fo:block font-family="Helvetica" font-size="14pt" padding="10mm">
+                                <xsl:value-of select="bookinfo/pubdate"/> 
+                            </fo:block>
+                        </fo:table-cell>
+                    </fo:table-row>
+                    <fo:table-row>
+                        <fo:table-cell text-align="center">
+                            <fo:block font-family="Helvetica" font-size="12pt" padding="10mm">
+                                <xsl:text>Copyright (c) 2004  -  </xsl:text>
+                                <xsl:for-each select="bookinfo/authorgroup/author">
+                                    <xsl:if test="position() > 1">
+                                        <xsl:text>, </xsl:text>
+                                    </xsl:if>
+                                    <xsl:value-of select="firstname"/>
+                                    <xsl:text> </xsl:text>
+                                    <xsl:value-of select="surname"/>
+                                </xsl:for-each>
+                            </fo:block>
+                            <fo:block font-family="Helvetica" font-size="10pt" padding="1mm">
+                                <xsl:value-of select="bookinfo/legalnotice"/>  
+                            </fo:block>
+                        </fo:table-cell>
+                    </fo:table-row>
+                </fo:table-body>
+            </fo:table>
+        </fo:block>
+    </xsl:template>
+
+    <!-- Prevent blank pages in output -->    
+    <xsl:template name="book.titlepage.before.verso">
+    </xsl:template>
+    <xsl:template name="book.titlepage.verso">
+    </xsl:template>
+    <xsl:template name="book.titlepage.separator">
+    </xsl:template>
+        
+<!--###################################################
+                      Header
+    ################################################### -->  
+
+    <!-- More space in the center header for long text -->
+    <xsl:attribute-set name="header.content.properties">
+        <xsl:attribute name="font-family">
+            <xsl:value-of select="$body.font.family"/>
+        </xsl:attribute>
+        <xsl:attribute name="margin-left">-5em</xsl:attribute>
+        <xsl:attribute name="margin-right">-5em</xsl:attribute>
+    </xsl:attribute-set>
+
+<!--###################################################
+                      Custom Footer
+    ################################################### -->     
+
+    <!-- This footer prints the version number on the left side -->
+    <xsl:template name="footer.content">
+        <xsl:param name="pageclass" select="''"/>
+        <xsl:param name="sequence" select="''"/>
+        <xsl:param name="position" select="''"/>
+        <xsl:param name="gentext-key" select="''"/>
+
+        <xsl:variable name="Version">
+            <xsl:choose>
+                <xsl:when test="//releaseinfo">
+                        <xsl:text>Acegi Security System for Spring </xsl:text><xsl:value-of select="//releaseinfo"/>
+                </xsl:when>
+                <xsl:otherwise>
+                    <!-- nop -->
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:variable>
+
+        <xsl:choose>
+            <xsl:when test="$sequence='blank'">
+            <xsl:choose>
+                <xsl:when test="$double.sided != 0 and $position = 'left'">
+                <xsl:value-of select="$Version"/>
+                </xsl:when>
+
+                <xsl:when test="$double.sided = 0 and $position = 'center'">
+                <!-- nop -->
+                </xsl:when>
+
+                <xsl:otherwise>
+                <fo:page-number/>
+                </xsl:otherwise>
+            </xsl:choose>
+            </xsl:when>
+
+            <xsl:when test="$pageclass='titlepage'">
+            <!-- nop: other titlepage sequences have no footer -->
+            </xsl:when>
+
+            <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='left'">
+            <fo:page-number/>
+            </xsl:when>
+
+            <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='right'">
+            <fo:page-number/>
+            </xsl:when>
+
+            <xsl:when test="$double.sided = 0 and $position='right'">
+            <fo:page-number/>
+            </xsl:when>
+
+            <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='left'">
+            <xsl:value-of select="$Version"/>
+            </xsl:when>
+
+            <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='right'">
+            <xsl:value-of select="$Version"/>
+            </xsl:when>
+
+            <xsl:when test="$double.sided = 0 and $position='left'">
+            <xsl:value-of select="$Version"/>
+            </xsl:when>
+
+            <xsl:otherwise>
+            <!-- nop -->
+            </xsl:otherwise>
+        </xsl:choose>
+    </xsl:template>    
+    
+<!--###################################################
+                   Custom Toc Line
+    ################################################### -->
+    
+    <!-- The default DocBook XSL TOC printing is seriously broken... -->
+    <xsl:template name="toc.line">
+        <xsl:variable name="id">
+            <xsl:call-template name="object.id"/>
+        </xsl:variable>
+
+        <xsl:variable name="label">
+            <xsl:apply-templates select="." mode="label.markup"/>
+        </xsl:variable>
+
+        <!-- justify-end removed from block attributes (space problem in title.markup) -->
+        <fo:block  end-indent="{$toc.indent.width}pt"
+                   last-line-end-indent="-{$toc.indent.width}pt"
+                   white-space-treatment="preserve"
+                   white-space-collapse="false">
+            <fo:inline keep-with-next.within-line="always">
+                <!-- print Chapters in bold style -->
+                <xsl:choose>
+                    <xsl:when test="local-name(.) = 'chapter'">
+                        <xsl:attribute name="font-weight">bold</xsl:attribute>
+                    </xsl:when>
+                </xsl:choose>        
+                <fo:basic-link internal-destination="{$id}">
+                    <xsl:if test="$label != ''">
+                        <xsl:copy-of select="$label"/>
+                        <fo:inline white-space-treatment="preserve"
+                                    white-space-collapse="false">
+                            <xsl:value-of select="$autotoc.label.separator"/>
+                        </fo:inline>
+                    </xsl:if>
+                    <xsl:apply-templates select="." mode="title.markup"/>
+                </fo:basic-link>
+            </fo:inline>
+            <fo:inline keep-together.within-line="always">
+            <xsl:text> </xsl:text>
+            <fo:leader leader-pattern="dots"
+                        leader-pattern-width="3pt"
+                        leader-alignment="reference-area"
+                        keep-with-next.within-line="always"/>
+            <xsl:text> </xsl:text>
+            <fo:basic-link internal-destination="{$id}">
+                <fo:page-number-citation ref-id="{$id}"/>
+            </fo:basic-link>
+            </fo:inline>
+        </fo:block>
+    </xsl:template>
+    
+<!--###################################################
+                      Extensions
+    ################################################### -->  
+
+    <!-- These extensions are required for table printing and other stuff -->
+    <xsl:param name="use.extensions">1</xsl:param>
+    <xsl:param name="tablecolumns.extension">0</xsl:param>
+    <xsl:param name="callout.extensions">1</xsl:param>
+    <!-- FOP provide only PDF Bookmarks at the moment -->
+    <xsl:param name="fop.extensions">1</xsl:param>
+
+<!--###################################################
+                      Table Of Contents
+    ################################################### -->   
+
+    <!-- Generate the TOCs for named components only -->
+    <xsl:param name="generate.toc">
+        book   toc
+    </xsl:param>
+    
+    <!-- Show only Sections up to level 3 in the TOCs -->
+    <xsl:param name="toc.section.depth">2</xsl:param>
+    
+    <!-- Dot and Whitespace as separator in TOC between Label and Title-->
+    <xsl:param name="autotoc.label.separator" select="'.  '"/>
+
+        
+<!--###################################################
+                   Paper & Page Size
+    ################################################### -->  
+    
+    <!-- Paper type, no headers on blank pages, no double sided printing -->
+    <xsl:param name="paper.type" select="'A4'"/>
+    <xsl:param name="double.sided">0</xsl:param>
+    <xsl:param name="headers.on.blank.pages">0</xsl:param>
+    <xsl:param name="footers.on.blank.pages">0</xsl:param>
+
+    <!-- Space between paper border and content (chaotic stuff, don't touch) -->
+    <xsl:param name="page.margin.top">5mm</xsl:param>
+    <xsl:param name="region.before.extent">10mm</xsl:param>
+    <xsl:param name="body.margin.top">10mm</xsl:param>
+    
+    <xsl:param name="body.margin.bottom">15mm</xsl:param>
+    <xsl:param name="region.after.extent">10mm</xsl:param>
+    <xsl:param name="page.margin.bottom">0mm</xsl:param>
+    
+    <xsl:param name="page.margin.outer">18mm</xsl:param>
+    <xsl:param name="page.margin.inner">18mm</xsl:param>
+
+    <!-- No intendation of Titles -->
+    <xsl:param name="title.margin.left">0pc</xsl:param>
+
+<!--###################################################
+                   Fonts & Styles
+    ################################################### -->      
+
+    <!-- Left aligned text and no hyphenation -->
+    <xsl:param name="alignment">left</xsl:param>
+    <xsl:param name="hyphenate">false</xsl:param>
+
+    <!-- Default Font size -->
+    <xsl:param name="body.font.master">11</xsl:param>
+    <xsl:param name="body.font.small">8</xsl:param>
+
+    <!-- Line height in body text -->
+    <xsl:param name="line-height">1.4</xsl:param>
+
+    <!-- Monospaced fonts are smaller than regular text -->
+    <xsl:attribute-set name="monospace.properties">
+        <xsl:attribute name="font-family">
+            <xsl:value-of select="$monospace.font.family"/>
+        </xsl:attribute>
+        <xsl:attribute name="font-size">0.8em</xsl:attribute>
+    </xsl:attribute-set>
+    
+<!--###################################################
+                   Tables
+    ################################################### -->
+
+    <!-- The table width should be adapted to the paper size -->
+    <xsl:param name="default.table.width">17.4cm</xsl:param>
+
+    <!-- Some padding inside tables -->    
+    <xsl:attribute-set name="table.cell.padding">
+        <xsl:attribute name="padding-left">4pt</xsl:attribute>
+        <xsl:attribute name="padding-right">4pt</xsl:attribute>
+        <xsl:attribute name="padding-top">4pt</xsl:attribute>
+        <xsl:attribute name="padding-bottom">4pt</xsl:attribute>
+    </xsl:attribute-set>
+    
+    <!-- Only hairlines as frame and cell borders in tables -->
+    <xsl:param name="table.frame.border.thickness">0.1pt</xsl:param>
+    <xsl:param name="table.cell.border.thickness">0.1pt</xsl:param>
+        
+<!--###################################################
+                         Labels
+    ################################################### -->   
+
+    <!-- Label Chapters and Sections (numbering) -->
+    <xsl:param name="chapter.autolabel">1</xsl:param>
+    <xsl:param name="section.autolabel" select="1"/>
+    <xsl:param name="section.label.includes.component.label" select="1"/>
+
+<!--###################################################
+                         Titles
+    ################################################### -->   
+    
+    <!-- Chapter title size -->
+    <xsl:attribute-set name="chapter.titlepage.recto.style">
+        <xsl:attribute name="text-align">left</xsl:attribute>
+        <xsl:attribute name="font-weight">bold</xsl:attribute>
+        <xsl:attribute name="font-size">
+            <xsl:value-of select="$body.font.master * 1.8"/>
+            <xsl:text>pt</xsl:text>
+        </xsl:attribute>        
+    </xsl:attribute-set>
+
+    <!-- Why is the font-size for chapters hardcoded in the XSL FO templates? 
+        Let's remove it, so this sucker can use our attribute-set only... -->
+    <xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">
+        <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                  xsl:use-attribute-sets="chapter.titlepage.recto.style">
+            <xsl:call-template name="component.title">
+                <xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
+            </xsl:call-template>
+            </fo:block>
+    </xsl:template>
+    
+    <!-- Sections 1, 2 and 3 titles have a small bump factor and padding -->    
+    <xsl:attribute-set name="section.title.level1.properties">
+        <xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
+        <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+        <xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
+        <xsl:attribute name="font-size">
+            <xsl:value-of select="$body.font.master * 1.5"/>
+            <xsl:text>pt</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+    </xsl:attribute-set>
+    <xsl:attribute-set name="section.title.level2.properties">
+        <xsl:attribute name="space-before.optimum">0.6em</xsl:attribute>
+        <xsl:attribute name="space-before.minimum">0.6em</xsl:attribute>
+        <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
+        <xsl:attribute name="font-size">
+            <xsl:value-of select="$body.font.master * 1.25"/>
+            <xsl:text>pt</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+    </xsl:attribute-set>
+    <xsl:attribute-set name="section.title.level3.properties">
+        <xsl:attribute name="space-before.optimum">0.4em</xsl:attribute>
+        <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
+        <xsl:attribute name="space-before.maximum">0.4em</xsl:attribute>
+        <xsl:attribute name="font-size">
+            <xsl:value-of select="$body.font.master * 1.0"/>
+            <xsl:text>pt</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+    </xsl:attribute-set>
+
+    <!-- Titles of formal objects (tables, examples, ...) -->
+    <xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
+        <xsl:attribute name="font-weight">bold</xsl:attribute>
+        <xsl:attribute name="font-size">
+            <xsl:value-of select="$body.font.master"/>
+            <xsl:text>pt</xsl:text>
+        </xsl:attribute>
+        <xsl:attribute name="hyphenate">false</xsl:attribute>
+        <xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
+        <xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
+        <xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
+    </xsl:attribute-set>    
+
+<!--###################################################
+                      Programlistings
+    ################################################### -->  
+    
+    <!-- Verbatim text formatting (programlistings) -->
+    <xsl:attribute-set name="monospace.verbatim.properties">
+        <xsl:attribute name="font-size">
+            <xsl:value-of select="$body.font.small * 1.0"/>
+            <xsl:text>pt</xsl:text>
+        </xsl:attribute>
+    </xsl:attribute-set>
+    
+    <xsl:attribute-set name="verbatim.properties">
+        <xsl:attribute name="space-before.minimum">1em</xsl:attribute>
+        <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+        <xsl:attribute name="space-before.maximum">1em</xsl:attribute>
+        <!-- alef: commented out because footnotes were screwed because of it -->
+        <!--<xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>-->
+        <xsl:attribute name="border-color">#444444</xsl:attribute>
+        <xsl:attribute name="border-style">solid</xsl:attribute>
+        <xsl:attribute name="border-width">0.1pt</xsl:attribute>      
+        <xsl:attribute name="padding-top">0.5em</xsl:attribute>      
+        <xsl:attribute name="padding-left">0.5em</xsl:attribute>      
+        <xsl:attribute name="padding-right">0.5em</xsl:attribute>      
+        <xsl:attribute name="padding-bottom">0.5em</xsl:attribute>      
+        <xsl:attribute name="margin-left">0.5em</xsl:attribute>      
+        <xsl:attribute name="margin-right">0.5em</xsl:attribute>      
+    </xsl:attribute-set>    
+
+    <!-- Shade (background) programlistings -->    
+    <xsl:param name="shade.verbatim">1</xsl:param>
+    <xsl:attribute-set name="shade.verbatim.style">
+        <xsl:attribute name="background-color">#F0F0F0</xsl:attribute>
+    </xsl:attribute-set>
+                    
+<!--###################################################
+                         Callouts
+    ################################################### -->   
+
+    <!-- Use images for callouts instead of (1) (2) (3) -->
+    <xsl:param name="callout.graphics">0</xsl:param>
+    <xsl:param name="callout.unicode">1</xsl:param>
+    
+    <!-- Place callout marks at this column in annotated areas -->
+    <xsl:param name="callout.defaultcolumn">90</xsl:param>
+
+<!--###################################################
+                       Admonitions
+    ################################################### -->   
+
+    <!-- Use nice graphics for admonitions -->
+    <xsl:param name="admon.graphics">'1'</xsl:param>
+    <xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param>
+
+<!--###################################################
+                          Misc
+    ################################################### -->   
+
+    <!-- Placement of titles -->
+    <xsl:param name="formal.title.placement">
+        figure after
+        example before
+        equation before
+        table before
+        procedure before
+    </xsl:param>
+    
+    <!-- Format Variable Lists as Blocks (prevents horizontal overflow) -->
+    <xsl:param name="variablelist.as.blocks">1</xsl:param>
+
+    <!-- The horrible list spacing problems -->
+    <xsl:attribute-set name="list.block.spacing">
+        <xsl:attribute name="space-before.optimum">0.8em</xsl:attribute>
+        <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+        <xsl:attribute name="space-before.maximum">0.8em</xsl:attribute>
+        <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute>
+        <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute>
+    </xsl:attribute-set>
+    
+</xsl:stylesheet>

+ 168 - 0
docbook/styles/html.css

@@ -0,0 +1,168 @@
+A {
+    color: #003399;
+}
+
+A:active {
+    color: #003399;
+}
+
+A:visited {
+    color: #888888;
+}
+
+P, DL, DT, DD, BLOCKQUOTE {
+    color: #000000;
+    margin-bottom: 3px;
+    margin-top: 3px;
+    padding-top: 0px;
+    /*border: 1px solid black;*/
+}
+
+OL, UL, P {
+    margin-top: 6px;
+    margin-bottom: 6px;
+}
+
+P, BLOCKQUOTE {
+    font-size: 90%;
+}
+
+P.releaseinfo {
+    font-size: 120%; font-weight: bold; 
+    font-family: Arial, helvetica, sans-serif;
+    padding-top: 10px;
+}
+
+P.pubdate {
+    font-size: 120%; font-weight: bold; 
+    font-family: Arial, helvetica, sans-serif;
+}
+
+td {
+    font-size: 80%;
+}
+
+
+TD, TH, SPAN {
+    color: #000000;
+}
+
+BLOCKQUOTE {
+    margin-right: 0px;
+}
+
+H1, H2, H3, H4, H5, H6    {
+    color: #000000;
+    font-weight:500;
+    margin-top:0px;
+    padding-top:14px;
+    font-family: Arial, helvetica, sans-serif;
+    margin-bottom: 0px;
+}
+
+H2.title {
+    font-weight:800;
+    margin-bottom: 8px;
+}
+
+H2.subtitle {
+    font-weight:800;
+    margin-bottom: 20px;
+}
+
+H3.author {
+    color: #000000;
+    font-weight:500;
+    margin-top:0px;
+    padding-top:0px;
+    font-family: Arial, helvetica, sans-serif;
+    margin-bottom: 0px;
+}
+
+TABLE  {
+    border-collapse: collapse;
+    border-spacing:0;
+    border: 1px thin black;
+    empty-cells: hide;
+}
+
+TD  {
+    padding: 4pt;
+}
+
+H1 { 
+    font-size: 150%; 
+}
+H2 { 
+    font-size: 110%; 
+}
+H3 {
+    font-size: 100%; font-weight: bold; 
+}
+H4 { 
+    font-size: 90%; font-weight: bold;
+}
+H5 {
+    font-size: 90%; font-style: italic; 
+}
+H6 { 
+    font-size: 100%; font-style: italic; 
+}
+
+TT {
+    font-size: 90%;
+    font-family: "Courier New", Courier, monospace;
+    color: #000000;
+}
+
+.navheader, .navfooter {    
+    background-color: #e4eff3;
+}
+
+PRE {
+    font-size: 90%;
+    padding: 5px;
+    border-style: solid;
+    border-width: 1px;
+    border-color: #CCCCCC;
+    background-color: #F4F4F4;
+}
+
+UL, OL, LI {
+    list-style: disc;
+}
+
+HR  {
+    width: 100%;
+    height: 1px;
+    background-color: #CCCCCC;
+    border-width: 0px;
+    padding: 0px;
+    color: #CCCCCC;
+}
+
+.variablelist { 
+    padding-top: 10; 
+    padding-bottom:10; 
+    margin:0;
+}
+
+/*(.itemizedlist, UL { 
+    padding-top: 0; 
+    padding-bottom:0; 
+    margin:0; 
+}*/
+
+.term { 
+    font-weight:bold;
+}
+
+.mediaobject {
+    padding-top: 30px; 
+    padding-bottom: 30px; 
+}
+
+.legalnotice {
+    font-size: 70%;
+}
+    

+ 94 - 0
docbook/styles/html.xsl

@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+
+<!-- 
+
+    This is the XSL HTML configuration file for the Hibernate
+    Reference Documentation. 
+    
+    It took me days to figure out this stuff and fix most of
+    the obvious bugs in the DocBook XSL distribution, so if you
+    use this stylesheet, give some credit back to the Hibernate
+    project.
+    
+    christian.bauer@bluemars.de
+-->
+
+<!DOCTYPE xsl:stylesheet [
+    <!ENTITY db_xsl_path        "../lib/docbook-xsl/">
+    <!ENTITY callout_gfx_path   "../images/callouts/">
+    <!ENTITY admon_gfx_path     "../images/admons/">
+]>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0"
+                xmlns="http://www.w3.org/TR/xhtml1/transitional"
+                exclude-result-prefixes="#default">
+                
+<xsl:import href="&db_xsl_path;/html/docbook.xsl"/>
+
+<!--###################################################
+                     HTML Settings
+    ################################################### -->   
+
+    <xsl:param name="html.stylesheet">../styles/html.css</xsl:param>
+
+    <!-- These extensions are required for table printing and other stuff -->
+    <xsl:param name="use.extensions">1</xsl:param>
+    <xsl:param name="tablecolumns.extension">0</xsl:param>
+    <xsl:param name="callout.extensions">1</xsl:param>
+    <xsl:param name="graphicsize.extension">0</xsl:param>
+
+<!--###################################################
+                      Table Of Contents
+    ################################################### -->   
+
+    <!-- Generate the TOCs for named components only -->
+    <xsl:param name="generate.toc">
+        book   toc
+    </xsl:param>
+    
+    <!-- Show only Sections up to level 3 in the TOCs -->
+    <xsl:param name="toc.section.depth">3</xsl:param>
+    
+<!--###################################################
+                         Labels
+    ################################################### -->   
+
+    <!-- Label Chapters and Sections (numbering) -->
+    <xsl:param name="chapter.autolabel">1</xsl:param>
+    <xsl:param name="section.autolabel" select="1"/>
+    <xsl:param name="section.label.includes.component.label" select="1"/>
+        
+<!--###################################################
+                         Callouts
+    ################################################### -->   
+
+    <!-- Use images for callouts instead of (1) (2) (3) -->
+    <xsl:param name="callout.graphics">1</xsl:param>
+    <xsl:param name="callout.graphics.path">&callout_gfx_path;</xsl:param>
+    
+    <!-- Place callout marks at this column in annotated areas -->
+    <xsl:param name="callout.defaultcolumn">90</xsl:param>
+
+<!--###################################################
+                       Admonitions
+    ################################################### -->   
+
+    <!-- Use nice graphics for admonitions -->
+    <xsl:param name="admon.graphics">'1'</xsl:param>
+    <xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param>
+
+<!--###################################################
+                          Misc
+    ################################################### -->   
+
+    <!-- Placement of titles -->
+    <xsl:param name="formal.title.placement">
+        figure after
+        example before
+        equation before
+        table before
+        procedure before
+    </xsl:param>    
+    
+</xsl:stylesheet>

+ 96 - 0
docbook/styles/html_chunk.xsl

@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+
+<!-- 
+
+    This is the XSL HTML configuration file for the Hibernate
+    Reference Documentation. 
+    
+    It took me days to figure out this stuff and fix most of
+    the obvious bugs in the DocBook XSL distribution, so if you
+    use this stylesheet, give some credit back to the Hibernate
+    project.
+    
+    christian.bauer@bluemars.de
+-->
+
+<!DOCTYPE xsl:stylesheet [
+    <!ENTITY db_xsl_path        "../lib/docbook-xsl/">
+    <!ENTITY callout_gfx_path   "../images/callouts/">
+    <!ENTITY admon_gfx_path     "../images/admons/">
+]>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0"
+                xmlns="http://www.w3.org/TR/xhtml1/transitional"
+                exclude-result-prefixes="#default">
+                
+<xsl:import href="&db_xsl_path;/html/chunk.xsl"/>
+
+<!--###################################################
+                     HTML Settings
+    ################################################### -->   
+
+    <xsl:param name="chunk.section.depth">'5'</xsl:param>
+    <xsl:param name="use.id.as.filename">'1'</xsl:param>
+    <xsl:param name="html.stylesheet">../styles/html.css</xsl:param>
+
+    <!-- These extensions are required for table printing and other stuff -->
+    <xsl:param name="use.extensions">1</xsl:param>
+    <xsl:param name="tablecolumns.extension">0</xsl:param>
+    <xsl:param name="callout.extensions">1</xsl:param>
+    <xsl:param name="graphicsize.extension">0</xsl:param>
+    
+<!--###################################################
+                      Table Of Contents
+    ################################################### -->   
+
+    <!-- Generate the TOCs for named components only -->
+    <xsl:param name="generate.toc">
+        book   toc
+    </xsl:param>
+    
+    <!-- Show only Sections up to level 3 in the TOCs -->
+    <xsl:param name="toc.section.depth">3</xsl:param>
+
+<!--###################################################
+                         Labels
+    ################################################### -->   
+
+    <!-- Label Chapters and Sections (numbering) -->
+    <xsl:param name="chapter.autolabel">1</xsl:param>
+    <xsl:param name="section.autolabel" select="1"/>
+    <xsl:param name="section.label.includes.component.label" select="1"/>
+                
+<!--###################################################
+                         Callouts
+    ################################################### -->   
+
+    <!-- Use images for callouts instead of (1) (2) (3) -->
+    <xsl:param name="callout.graphics">1</xsl:param>
+    <xsl:param name="callout.graphics.path">&callout_gfx_path;</xsl:param>
+    
+    <!-- Place callout marks at this column in annotated areas -->
+    <xsl:param name="callout.defaultcolumn">90</xsl:param>
+
+<!--###################################################
+                       Admonitions
+    ################################################### -->   
+
+    <!-- Use nice graphics for admonitions -->
+    <xsl:param name="admon.graphics">'1'</xsl:param>
+    <xsl:param name="admon.graphics.path">&admon_gfx_path;</xsl:param>
+
+<!--###################################################
+                          Misc
+    ################################################### -->   
+
+    <!-- Placement of titles -->
+    <xsl:param name="formal.title.placement">
+        figure after
+        example before
+        equation before
+        table before
+        procedure before
+    </xsl:param>    
+    
+</xsl:stylesheet>