Parcourir la source

General improvements ready for 0.9.0.

Ben Alex il y a 20 ans
Parent
commit
478b575ad5
1 fichiers modifiés avec 201 ajouts et 253 suppressions
  1. 201 253
      doc/docbook/acegi.xml

+ 201 - 253
doc/docbook/acegi.xml

@@ -106,12 +106,16 @@
         Portable Runtime Project versioning guidelines, available from
         <literal>http://apr.apache.org/versioning.html</literal>.</para>
 
-        <para>Some minor improvements are currently intended prior to the
-        1.0.0 release, although each of these represent additional
-        functionality that will in no way modify the project's central
-        interfaces or classes. Users of Acegi Security System for Spring
-        should therefore be comfortable depending on the current version of
-        the project in their applications.</para>
+        <para>We are now at release 0.9.0, and a lot of effort has been made
+        to implement all non-backward compatible changes either in or before
+        this release. Some minor improvements are currently intended to the
+        1.0.0 release, although they will in no way modify the project's
+        central interfaces or classes. Users of Acegi Security System for
+        Spring should therefore be comfortable depending on the current
+        version of the project in their applications. Please note that we will
+        be changing the package name prefix in the 1.0.0 release, but this
+        should be a simple "find and replace" type operation in your
+        code.</para>
       </sect2>
     </sect1>
 
@@ -143,7 +147,7 @@
           </listitem>
 
           <listitem>
-            <para>A <literal>ContextHolder</literal> which holds the
+            <para>A <literal>SecurityContextHolder</literal> which holds the
             <literal>Authentication</literal> object in a
             <literal>ThreadLocal</literal>-bound object.</para>
           </listitem>
@@ -335,10 +339,13 @@
         <literal>SecureContext</literal> defined an interface used for storage
         of the <literal>Authentication</literal> object. The
         <literal>ContextHolder</literal> was a <literal>ThreadLocal</literal>.
-        This was removed from 0.9.0 after discussion with other Spring
-        developers for the sake of consistency. See for example
-        <literal>http://article.gmane.org/gmane.comp.java.springframework.devel/8290</literal>.
-        This history is mentioned as the long period
+        A fuller discussion of the <literal>ThreadLocal</literal> usage with
+        Acegi Security follows in this document.
+        <literal>ContextHolder</literal> and <literal>SecureContext</literal>
+        was removed from 0.9.0 after discussion with other Spring developers
+        for the sake of consistency. See for example
+        <literal>http://article.gmane.org/gmane.comp.java.springframework.devel/8290</literal>
+        and JIRA task SEC-77. This history is mentioned as the long period
         <literal>ContextHolder</literal> was used will likely mean that
         certain documentation you encounter concerning Acegi Security might
         still refer to <literal>ContextHolder</literal>. Generally you can
@@ -432,7 +439,7 @@
           <listitem>
             <para>Pass the <literal>Authentication</literal> object to the
             <literal>AuthenticationManager</literal>, update the
-            <literal>ContextHolder</literal> with the response.</para>
+            <literal>SecurityContextHolder</literal> with the response.</para>
           </listitem>
 
           <listitem>
@@ -450,7 +457,7 @@
           <listitem>
             <para>If the <literal>RunAsManager</literal> returns a new
             <literal>Authentication</literal> object, update the
-            <literal>ContextHolder</literal> with it.</para>
+            <literal>SecurityContextHolder</literal> with it.</para>
           </listitem>
 
           <listitem>
@@ -461,7 +468,7 @@
           <listitem>
             <para>If the <literal>RunAsManager</literal> earlier returned a
             new <literal>Authentication</literal> object, update the
-            <literal>ContextHolder</literal> with the
+            <literal>SecurityContextHolder</literal> with the
             <literal>Authentication</literal> object that was previously
             returned by the <literal>AuthenticationManager</literal>.</para>
           </listitem>
@@ -1061,8 +1068,8 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         <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>SecurityContext</literal> in the
+        <literal>SecurityContextHolder</literal>. This is then passed to an
         <literal>AuthenticationManager</literal>. The
         <literal>AuthenticationManager</literal> interface is very
         simple:</para>
@@ -1077,8 +1084,8 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         <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>SecurityContext</literal> in the
+        <literal>SecurityContextHolder</literal>, overwriting the original
         <literal>Authentication</literal> object.</para>
 
         <para>The <literal>AuthenticationException</literal> has a number of
@@ -1133,6 +1140,19 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         registered <literal>AuthenticationProviders</literal> can validate the
         <literal>Authentication</literal> object.</para>
 
+        <para>The <literal>ProviderManager</literal> also has several other
+        important functions. It integrates with concurrent session handling
+        supoprt, and it also converts any exceptions thrown by an
+        <literal>AuthenticationProvider</literal> and publishes a suitable
+        event. The events that are published are located in the
+        <literal>net.sf.acegisecurity.event.authentication</literal> package
+        and advanced users can map different exceptions to different events by
+        configuring the <literal>ProviderManager.exceptionMappings</literal>
+        property (generally this is not required and the default event
+        propagation is appropriate - especially as events will simply be
+        ignored if you don't have an <literal>ApplicationListener</literal>
+        configured in the <literal>ApplicationContext</literal>).</para>
+
         <para>Several <literal>AuthenticationProvider</literal>
         implementations are provided with the Acegi Security System for
         Spring:</para>
@@ -1195,6 +1215,55 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
           </itemizedlist></para>
       </sect2>
 
+      <sect2 id="security-authentication-concurrent-login">
+        <title>Concurrent Session Support</title>
+
+        <para>Acegi Security is able to stop the same principal authenticating
+        to the same web application multiple times concurrently. Put
+        differently, you can stop user "Batman" from logging into a web
+        application twice at the same time.</para>
+
+        <para>To use concurrent session support, you'll need to add the
+        following to web.xml:</para>
+
+        <para><programlisting>&lt;listener&gt;
+  &lt;listener-class&gt;net.sf.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;
+&lt;/listener&gt;</programlisting></para>
+
+        <para>In addition, you will need to add the
+        <literal>net.sf.acegisecurity.concurrent.ConcurrentSessionFilter</literal>
+        to your <literal>FilterChainProxy</literal>. The
+        ConcurrentSessionFilter requires only one property, sessionRegistry,
+        which generally points to an instance of
+        <literal>SessionRegistryImpl</literal>.</para>
+
+        <para>The <literal>web.xml</literal>
+        <literal>HttpSessionEventPublisher</literal> causes an
+        <literal>ApplicationEvent</literal> to be published to the Spring
+        <literal>ApplicationContext</literal> every time a
+        <literal>HttpSession</literal> commences or terminates. This is
+        critical, as it allows the <literal>SessionRegistryImpl</literal> to
+        be notified when a session ends. </para>
+
+        <para>You will also need to wire up the
+        <literal>ConcurrentSessionControllerImpl</literal> and refer to it
+        from your <literal>ProviderManager</literal> bean:</para>
+
+        <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
+  &lt;property name="providers"&gt;
+    &lt;!-- your providers go here --&gt;
+  &lt;/property&gt;
+  &lt;property name="sessionController"&gt;&lt;ref bean="concurrentSessionController"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="concurrentSessionController" class="net.sf.acegisecurity.concurrent.ConcurrentSessionControllerImpl"&gt;
+  &lt;property name="maxSessions"&gt;&lt;value&gt;1&lt;/value&gt;&lt;/property&gt;
+  &lt;property name="sessionRegistry"&gt;&lt;ref local="sessionRegistry"/&gt;&lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="sessionRegistry" class="net.sf.acegisecurity.concurrent.SessionRegistryImpl"/&gt;</programlisting></para>
+      </sect2>
+
       <sect2 id="security-authentication-provider-dao">
         <title>Data Access Object Authentication Provider</title>
 
@@ -1325,89 +1394,6 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         context.</para>
       </sect2>
 
-      <sect2 id="security-authentication-provider-events">
-        <title>Event Publishing</title>
-
-        <para>The <literal>DaoAuthenticationProvider</literal> automatically
-        obtains the <literal>ApplicationContext</literal> it is running in at
-        startup time. This allows the provider to publish events through the
-        standard Spring event framework. Three types of event messages are
-        published:</para>
-
-        <itemizedlist spacing="compact">
-          <listitem>
-            <para><literal>AuthenticationSuccessEvent</literal> is published
-            when an authentication request is successful.</para>
-          </listitem>
-
-          <listitem>
-            <para><literal>AuthenticationFailureDisabledEvent</literal> is
-            published when an authentication request is unsuccessful because
-            the returned <literal>UserDetails</literal> is disabled. This is
-            normally the case when an account is locked.</para>
-          </listitem>
-
-          <listitem>
-            <para><literal>AuthenticationFailureAccountExpiredEvent</literal>
-            is published when an authentication request is unsuccessful
-            because the returned <literal>UserDetails</literal> indicates the
-            account has expired. Some applications may wish to distinguish
-            between an account being disabled and expired.</para>
-          </listitem>
-
-          <listitem>
-            <para><literal>AuthenticationFailureCredentialsExpiredEvent</literal>
-            is published when an authentication request is unsuccessful
-            because the returned <literal>UserDetails</literal> indicates the
-            account's credentials have expired. Some applications may wish to
-            expire the credentials if, for example, a password is not changed
-            with sufficient regularity.</para>
-          </listitem>
-
-          <listitem>
-            <para><literal>AuthenticationFailureUsernameNotFoundEvent</literal>
-            is published when an authentication request is unsuccessful
-            because the <literal>AuthenticationDao</literal> could not locate
-            the <literal>UserDetails</literal>.</para>
-          </listitem>
-
-          <listitem>
-            <para><literal>AuthenticationFailurePasswordEvent</literal> is
-            published when an authentication request is unsuccessful because
-            the presented password did not match that in the
-            <literal>UserDetails</literal>.</para>
-          </listitem>
-        </itemizedlist>
-
-        <para>Each event contains two objects: the
-        <literal>Authentication</literal> object that represented the
-        authentication request, and the <literal>UserDetails</literal> object
-        that was found in response to the authentication request (clearly the
-        latter will be a dummy object in the case of
-        <literal>AuthenticationFailureUsernameNotFoundEvent</literal>). The
-        <literal>Authentication</literal> interface provides a
-        <literal>getDetails()</literal> method which often includes
-        information that event consumers may find useful (eg the TCP/IP
-        address that the authentication request originated from).</para>
-
-        <para>As per standard Spring event handling, you can receive these
-        events by adding a bean to the application context which implements
-        the <literal>ApplicationListener</literal> interface. Included with
-        Acegi Security is a <literal>LoggerListener</literal> class which
-        receives these events and publishes their details to Commons Logging.
-        Refer to the JavaDocs for <literal>LoggerListener</literal> for
-        details on the logging priorities used for different message
-        types.</para>
-
-        <para>This event publishing system enables you to implement account
-        locking and record authentication event history. This might be of
-        interest to application users, who can be advised of the times and
-        source IP address of all unsuccessful password attempts (and account
-        lockouts) since their last successful login. Such capabilities are
-        simple to implement and greatly improve the security of your
-        application.</para>
-      </sect2>
-
       <sect2 id="security-authentication-provider-in-memory">
         <title>In-Memory Authentication</title>
 
@@ -1443,6 +1429,14 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         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>
+
+        <para><literal>InMemoryDaoImpl</literal> also offers a
+        <literal>setUserProperties(Properties)</literal> method, which allows
+        you to externalise the <literal>java.util.Properties</literal> in
+        another Spring configured bean or an external properties file. This
+        might prove useful for simple applications that have a larger number
+        of users, or deployment-time configuration changes, but do not wish to
+        use a full database for authentication details.</para>
       </sect2>
 
       <sect2 id="security-authentication-provider-jdbc">
@@ -1474,77 +1468,6 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
         customisation of the SQL statements. You may also subclass the
         <literal>JdbcDaoImpl</literal> if further customisation is necessary.
         Please refer to the JavaDocs for details.</para>
-
-        <para>The Acegi Security System for Spring ships with a Hypersonic SQL
-        instance that has the required authentication information and sample
-        data already populated. To use this server, simply execute the
-        <literal>server.bat</literal> or <literal>server.sh</literal> script
-        included in the distribution. This will load a new database server
-        instance that will service requests made to the URL indicated in the
-        bean context configuration shown above.</para>
-      </sect2>
-
-      <sect2 id="security-authentication-concurrent-login">
-        <title>Concurrent Session Support</title>
-
-        <para>Acegi Security is able to stop the same principal authenticating
-        to the same web application multiple times concurrently. Put
-        differently, you can stop user "Batman" from logging into a web
-        application twice at the same time.</para>
-
-        <para>To use concurrent session support, you'll need to add the
-        following to web.xml:</para>
-
-        <para><programlisting>&lt;listener&gt;
-  &lt;listener-class&gt;net.sf.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;
-&lt;/listener&gt;</programlisting></para>
-
-        <para>The above code causes an <literal>ApplicationEvent</literal> to
-        be published to the Spring <literal>ApplicationContext</literal> every
-        time a <literal>HttpSession</literal> commences or terminates. This is
-        critical, as it allows the
-        <literal>ConcurrentSessionControllerImpl</literal> to be notified when
-        a session ends. Next up you'll need to wire the
-        <literal>ConcurrentSessionControllerImpl</literal> into your existing
-        <literal>ProviderManager</literal>:</para>
-
-        <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
-  &lt;property name="providers"&gt;
-    &lt;!-- your providers go here --&gt;
-  &lt;/property&gt;
-  &lt;property name="sessionController"&gt;&lt;ref bean="concurrentSessionController"/&gt;&lt;/property&gt;
-&lt;/bean&gt;
-
-&lt;bean id="concurrentSessionController" class="net.sf.acegisecurity.providers.ConcurrentSessionControllerImpl"&gt;
-  &lt;property name="maxSessions"&gt;&lt;value&gt;1&lt;/value&gt;&lt;/property&gt;
-&lt;/bean&gt;</programlisting></para>
-
-        <para>Ensure you do not in-line the
-        <literal>ConcurrentSessionControllerImpl</literal> when declaring it
-        in your XML. This is important, as it appears that in-lined bean
-        declarations do not receive ApplicationEvents.</para>
-
-        <para>The <literal>ConcurrentSessionControllerImpl</literal> relies
-        heavily on the
-        <literal>Authentication.getPrincipal().equals()</literal> method. If
-        you are using a custom <literal>Authentication</literal> object,
-        please keep this in mind. In order for the
-        <literal>ConcurrentSessionControllerImpl</literal> to release a given
-        <literal>HttpSession</literal>, and thus let the user log in to a new
-        <literal>HttpSession</literal>, the existing
-        <literal>HttpSession</literal> must be invalidated. For example, if
-        "Batman" logs into the web application, checks for crimes being
-        commited, and the just closes his browser with out "logging out", he
-        will not be able to log back in until his
-        <literal>HttpSession</literal> is timed out by the server (and a
-        corresponding <literal>ApplicationEvent</literal> is published via
-        <literal>HttpSessionEventPublisher</literal> to the
-        <literal>ConcurrentSessionControllerImpl</literal>). You would have to
-        look at your container's documentation to determine the default
-        timeout period. You can also configure the session timeout in your
-        <literal>web.xml</literal>:<programlisting>&lt;session-config&gt;
-  &lt;session-timeout&gt;30&lt;/session-timeout&gt;
-&lt;/session-config&gt;</programlisting></para>
       </sect2>
 
       <sect2 id="security-authentication-provider-jaas">
@@ -2165,23 +2088,20 @@ public boolean supports(Class clazz);</programlisting></para>
           <title>AuthenticationTag</title>
 
           <para><literal>AuthenticationTag</literal> is used to simply output
-          the current principal to the web page.</para>
+          a property of the current principal's
+          <literal>Authentication.getPrincipal()</literal> object to the web
+          page.</para>
 
           <para>The following JSP fragment illustrates how to use the
           <literal>AuthenticationTag</literal>:</para>
 
-          <para><programlisting>&lt;authz:authentication operation="principal"/&gt;</programlisting></para>
-
-          <para>This tag would cause the principal's name to be output. The
-          taglib properly supports the various types of principals that can
-          exist in the <literal>Authentication</literal> object, such as a
-          <literal>String</literal> or <literal>UserDetails</literal>
-          instance.</para>
+          <para><programlisting>&lt;authz:authentication operation="username"/&gt;</programlisting></para>
 
-          <para>The "operation" attribute must always be "principal". This may
-          be expanded in the future, such as obtaining other
-          <literal>Authentication</literal>-related properties such as email
-          address or telephone numbers.</para>
+          <para>This tag would cause the principal's name to be output. Here
+          we are assuming the <literal>Authentication.getPrincipal()</literal>
+          is a <literal>UserDetails</literal> object, which is generally the
+          case when using the typical
+          <literal>DaoAuthenticationProvider</literal>.</para>
         </sect3>
 
         <sect3>
@@ -2377,8 +2297,8 @@ public boolean supports(Class clazz);</programlisting></para>
 
         <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
+        the <literal>SecurityContext</literal> and
+        <literal>SecurityContextHolder</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
@@ -2472,14 +2392,14 @@ public boolean supports(Class clazz);</programlisting></para>
     </sect1>
 
     <sect1 id="security-ui">
-      <title>User Interfacing with the ContextHolder</title>
+      <title>User Interfacing with the SecurityContextHolder</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>SecurityContextHolder</literal> is populated with a valid
+        <literal>SecurityContext</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
@@ -2491,16 +2411,20 @@ public boolean supports(Class clazz);</programlisting></para>
         processing mechanism is solely concerned with received an
         authentication request from the principal, testing if it seems valid,
         and if so, placing the authentication request token onto the
-        ContextHolder. Of course, if the authentication request is invalid,
-        the authentication processing mechanism is responsible for informing
-        the principal in whatever way is appropriate to the protocol.</para>
-
-        <para>Recall the HttpSessionContextIntegrationFilter (discussed in the
-        context section) is responsible for storing the ContextHolder contents
-        between invocations. This means no authentication processing mechanism
-        need ever interact directly with HttpSession. Indeed
-        HttpSessionContextIntegrationFilter has been designed to minimise the
-        unnecessary creation of HttpSessions, as might occur when using Basic
+        <literal>SecurityContextHolder</literal>. Of course, if the
+        authentication request is invalid, the authentication processing
+        mechanism is responsible for informing the principal in whatever way
+        is appropriate to the protocol.</para>
+
+        <para>Recall the
+        <literal>HttpSessionContextIntegrationFilter</literal> (discussed in
+        the context section) is responsible for storing the
+        <literal>SecurityContextHolder</literal> contents between invocations.
+        This means no authentication processing mechanism need ever interact
+        directly with <literal>HttpSession</literal>. Indeed
+        <literal>HttpSessionContextIntegrationFilter</literal> has been
+        designed to minimise the unnecessary creation of
+        <literal>HttpSession</literal>s, as might occur when using Basic
         authentication for example.</para>
 
         <para>There are several authentication processing mechanisms included
@@ -2567,12 +2491,12 @@ public boolean supports(Class clazz);</programlisting></para>
 
         <para>If authentication is successful, the resulting
         <literal>Authentication</literal> object will be placed into the
-        <literal>ContextHolder</literal>.</para>
+        <literal>SecurityContextHolder</literal>.</para>
 
-        <para>Once the <literal>ContextHolder</literal> has been updated, the
-        browser will need to be redirected to the target URL. The target URL
-        is usually indicated by the <literal>HttpSession</literal> attribute
-        specified by
+        <para>Once the <literal>SecurityContextHolder</literal> has been
+        updated, the browser will need to be redirected to the target URL. The
+        target URL is usually indicated by the <literal>HttpSession</literal>
+        attribute specified by
         <literal>AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY</literal>.
         This attribute is automatically set by the
         <literal>SecurityEnforcementFilter</literal> when an
@@ -2626,7 +2550,7 @@ public boolean supports(Class clazz);</programlisting></para>
         401 response with a suitable header to retry HTTP Basic
         authentication. If authentication is successful, the resulting
         <literal>Authentication</literal> object will be placed into the
-        <literal>ContextHolder</literal>.</para>
+        <literal>SecurityContextHolder</literal>.</para>
 
         <para>If the authentication event was successful, or authentication
         was not attempted because the HTTP header did not contain a supported
@@ -2747,8 +2671,8 @@ key:              A private key to prevent modification of the nonce token
         <para>Like <literal>BasicAuthenticationFilter</literal>, if
         authentication is successful an <literal>Authentication</literal>
         request token will be placed into the
-        <literal>ContextHolder</literal>. If the authentication event was
-        successful, or authentication was not attempted because the HTTP
+        <literal>SecurityContextHolder</literal>. If the authentication event
+        was successful, or authentication was not attempted because the HTTP
         header did not contain a Digest Authentication request, the filter
         chain will continue as normal. The only time the filter chain will be
         interrupted is if authentication fails and the
@@ -2777,10 +2701,11 @@ key:              A private key to prevent modification of the nonce token
         logout and home pages of an application. There are also other
         situations where anonymous authentication would be desired, such as
         when an auditing interceptor queries the
-        <literal>ContextHolder</literal> to identify which principal was
-        responsible for a given operation. Such classes can be authored with
-        more robustness if they know the <literal>ContextHolder</literal>
-        always contains an <literal>Authentication</literal> object, and never
+        <literal>SecurityContextHolder</literal> to identify which principal
+        was responsible for a given operation. Such classes can be authored
+        with more robustness if they know the
+        <literal>SecurityContextHolder</literal> always contains an
+        <literal>Authentication</literal> object, and never
         <literal>null</literal>.</para>
 
         <para>Acegi Security provides three classes that together provide an
@@ -2795,7 +2720,7 @@ key:              A private key to prevent modification of the nonce token
         Finally, there is an AnonymousProcessingFilter, which is chained after
         the normal authentication mechanisms and automatically add an
         <literal>AnonymousAuthenticationToken</literal> to the
-        <literal>ContextHolder</literal> if there is no existing
+        <literal>SecurityContextHolder</literal> if there is no existing
         <literal>Authentication</literal> held there. The definition of the
         filter and authentication provider appears as follows:</para>
 
@@ -2886,7 +2811,7 @@ public void loginSuccess(HttpServletRequest request, HttpServletResponse respons
         <literal>loginFail()</literal> and <literal>loginSuccess()</literal>
         methods. The <literal>autoLogin()</literal> method is called by
         <literal>RememberMeProcessingFilter</literal> whenever the
-        <literal>ContextHolder</literal> does not contain an
+        <literal>SecurityContextHolder</literal> does not contain an
         <literal>Authentication</literal>. This interface therefore provides
         the underlaying remember-me implementation with sufficient
         notification of authentication-related events, and delegates to the
@@ -2967,19 +2892,20 @@ key:              A private key to prevent modification of the remember-me token
         locations" in discussions about storing the
         <literal>Authentication</literal>. This approach did not explicitly
         separate the function of <literal>HttpSession</literal> storage of
-        <literal>ContextHolder</literal> contents from the processing of
-        authentication requests received through various protocols. In
+        <literal>SecurityContextHolder</literal> contents from the processing
+        of authentication requests received through various protocols. In
         addition, the previous approach did not facilitate storage of
         non-<literal>Authentication</literal> objects between requests, which
-        was limiting usefulness of the <literal>ContextHolder</literal> system
-        to member of the community. For these reasons, the notion of
-        well-known locations was abandoned, the
-        <literal>HttpSessionContextIntegrationFilter</literal> was
-        established, and the purpose of authentication processing mechanisms
-        was explicitly defined and limited to interaction with the
-        <literal>ContextHolder</literal> only. There is no need to refer to
-        well-known locations any more and we hope this clearer separation of
-        responsibilities enhances understanding of the project.</para>
+        was limiting usefulness of the
+        <literal>SecurityContextHolder</literal> system to member of the
+        community. For these reasons, the notion of well-known locations was
+        abandoned, the <literal>HttpSessionContextIntegrationFilter</literal>
+        was established, and the purpose of authentication processing
+        mechanisms was explicitly defined and limited to interaction with the
+        <literal>SecurityContextHolder</literal> only. There is no need to
+        refer to well-known locations any more and we hope this clearer
+        separation of responsibilities enhances understanding of the
+        design.</para>
       </sect2>
     </sect1>
 
@@ -3063,10 +2989,10 @@ key:              A private key to prevent modification of the remember-me token
         <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>SecurityContext</literal> in the
+        <literal>SecurityContextHolder</literal> will be tested by the
+        application's <literal>AuthByAdapterProvider</literal>. There is no
+        requirement for additional authentication providers such as
         <literal>DaoAuthenticationProvider</literal> within the
         application-specific application context, as the only type of
         <literal>Authentication</literal> instance that will be presented by
@@ -3672,7 +3598,7 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
             authentication approach. Usually the
             <literal>HttpSessionIntegrationFilter</literal> will be used to
             associate the <literal>Authentication</literal> object with the
-            <literal>ContextHolder</literal> for the duration of each
+            <literal>SecurityContextHolder</literal> for the duration of each
             request.</para>
           </listitem>
         </orderedlist>
@@ -4108,7 +4034,7 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
         <title>Configuring the X509 Provider</title>
 
         <para>There is a version of the <link
-        linkend="security-sample">contacts sample application</link> which
+        linkend="security-sample">Contacts Sample Application</link> which
         uses X509. Copy the beans and filter setup from this as a starting
         point for configuring your own application. A set of example
         certificates is also included which you can use to configure your
@@ -4273,14 +4199,15 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
         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>
+        <literal>http://www.company.com:8080/app/page</literal>), not relative
+        (eg <literal>/app/page</literal>). During testing it was discovered
+        that Internet Explorer 6 Service Pack 1 has a bug whereby it does not
+        respond correctly to a redirection instruction which also changes the
+        port to use. Accordingly, absolute URLs are used in conjunction with
+        bug detection logic in the <literal>PortResolverImpl</literal> that is
+        wired up by default to many Acegi Security beans. Please refer to the
+        JavaDocs for <literal>PortResolverImpl</literal> for further
+        details.</para>
       </sect2>
 
       <sect2 id="security-channels-usage">
@@ -4349,9 +4276,9 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
               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>
+              <literal>SecurityContextHolder.getContext().getAuthentication()</literal>,
+              you'll be able to access the <literal>Authentication</literal>
+              object.</para>
             </listitem>
 
             <listitem>
@@ -4816,6 +4743,10 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
       <sect2 id="security-filters-filterchainproxy">
         <title>FilterChainProxy</title>
 
+        <para>We strongly recommend to use <literal>FilterChainProxy</literal>
+        instead of adding multiple filters to
+        <literal>web.xml</literal>.</para>
+
         <para>Whilst <literal>FilterToBeanProxy</literal> is a very useful
         class, the problem is that the lines of code required for
         <literal>&lt;filter&gt;</literal> and
@@ -4911,10 +4842,18 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
             need to redirect to a different protocol</para>
           </listitem>
 
+          <listitem>
+            <para><literal>ConcurrentSessionFilter</literal>, because it
+            doesn't use any <literal>SecurityContextHolder</literal>
+            functionality but needs to update the
+            <literal>SessionRegistry</literal> to reflect ongoing requests
+            from the principal</para>
+          </listitem>
+
           <listitem>
             <para><literal>HttpSessionContextIntegrationFilter</literal>, so a
             <literal>Context</literal> can be setup in the
-            <literal>ContextHolder</literal> at the beginning of a web
+            <literal>SecurityContextHolder</literal> at the beginning of a web
             request, and any changes to the Context can be copied to the
             <literal>HttpSession</literal> when the web request ends (ready
             for use with the next web request)</para>
@@ -4926,8 +4865,9 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
             <literal>CasProcessingFilter</literal>,
             <literal>BasicProcessingFilter, HttpRequestIntegrationFilter,
             JbossIntegrationFilter</literal> etc - so that the
-            <literal>ContextHolder</literal> can be modified to contain a
-            valid <literal>Authentication</literal> request token</para>
+            <literal>SecurityContextHolder</literal> can be modified to
+            contain a valid <literal>Authentication</literal> request
+            token</para>
           </listitem>
 
           <listitem>
@@ -4940,16 +4880,17 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
           <listitem>
             <para><literal>RememberMeProcessingFilter</literal>, so that if no
             earlier authentication processing mechanism updated the
-            <literal>ContextHolder</literal>, and the request presents a
-            cookie that enables remember-me services to take place, a suitable
-            remembered <literal><literal>Authentication</literal></literal>
-            object will be put there</para>
+            <literal>SecurityContextHolder</literal>, and the request presents
+            a cookie that enables remember-me services to take place, a
+            suitable remembered
+            <literal><literal>Authentication</literal></literal> object will
+            be put there</para>
           </listitem>
 
           <listitem>
             <para><literal>AnonymousProcessingFilter</literal>, so that if no
             earlier authentication processing mechanism updated the
-            <literal>ContextHolder</literal>, an anonymous
+            <literal>SecurityContextHolder</literal>, an anonymous
             <literal>Authentication</literal> object will be put there</para>
           </listitem>
 
@@ -4972,8 +4913,8 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></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>
+        <literal>SecurityContextHolder</literal> to be populated in time for
+        use by SiteMesh decorators.</para>
       </sect2>
     </sect1>
 
@@ -5016,7 +4957,7 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
       contain a success message similar to the following:</para>
 
       <blockquote>
-        <para>Context on ContextHolder is of type:
+        <para>Context on SecurityContextHolder is of type:
         net.sf.acegisecurity.context.secure.SecureContextImpl</para>
 
         <para>The Context implements SecureContext.</para>
@@ -5090,7 +5031,10 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
       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>
+      simply making suggestions. Please read our project policies web page
+      that is available on the Acegi Security home page. This explains the
+      path to become a committer, and the administration approaches we use
+      with the project.</para>
 
       <para>SourceForge provides CVS services for the project, allowing
       anybody to access the latest code. If you wish to contribute new code,
@@ -5123,6 +5067,10 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
           <para>Use CamelCase</para>
         </listitem>
 
+        <listitem>
+          <para>Add code contributions to JIRA</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