瀏覽代碼

Minor doc updates

Luke Taylor 16 年之前
父節點
當前提交
40efe6db57

+ 284 - 366
docs/manual/src/docbook/authorization-common.xml

@@ -1,293 +1,244 @@
-<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="authorization-common" xmlns:xlink="http://www.w3.org/1999/xlink">
-  <info><title>Common Authorization Concepts</title></info>
-
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="authorization-common"
+  xmlns:xlink="http://www.w3.org/1999/xlink">
+  <info>
+    <title>Common Authorization Concepts</title>
+  </info>
   <section xml:id="authorities">
-    <info><title>Authorities</title></info>
-
-    <para>As briefly mentioned in the Authentication section, all
-    <interfacename>Authentication</interfacename> implementations are required to
-    store an array of <interfacename>GrantedAuthority</interfacename> objects. These
-    represent the authorities that have been granted to the principal. The
-    <interfacename>GrantedAuthority</interfacename> objects are inserted into the
-    <interfacename>Authentication</interfacename> object by the
-    <interfacename>AuthenticationManager</interfacename> and are later read by
-    <interfacename>AccessDecisionManager</interfacename>s when making authorization
-    decisions.</para>
-
-    <para><interfacename>GrantedAuthority</interfacename> is an interface with only
-    one method:
+    <info>
+      <title>Authorities</title>
+    </info>
+    <para>As we saw in the <link xlink:href="#tech-granted-authority">technical overview</link>, all
+        <interfacename>Authentication</interfacename> implementations store a list of
+        <interfacename>GrantedAuthority</interfacename> objects. These represent the authorities
+      that have been granted to the principal. The <interfacename>GrantedAuthority</interfacename>
+      objects are inserted into the <interfacename>Authentication</interfacename> object by the
+        <interfacename>AuthenticationManager</interfacename> and are later read by
+        <interfacename>AccessDecisionManager</interfacename>s when making authorization
+      decisions.</para>
+    <para><interfacename>GrantedAuthority</interfacename> is an interface with only one method:
       <programlisting>
   String getAuthority();
-    </programlisting>
-    This method allows <interfacename>AccessDecisionManager</interfacename>s to
-    obtain a precise <literal>String</literal> representation of the
-    <interfacename>GrantedAuthority</interfacename>. By returning a representation as
-    a <literal>String</literal>, a <interfacename>GrantedAuthority</interfacename> can
-    be easily "read" by most <interfacename>AccessDecisionManager</interfacename>s. If
-    a <interfacename>GrantedAuthority</interfacename> cannot be precisely represented
-    as a <literal>String</literal>, the
-    <interfacename>GrantedAuthority</interfacename> is considered "complex" and
-    <literal>getAuthority()</literal> must return
-    <literal>null</literal>.</para>
-
-    <para>An example of a "complex" <interfacename>GrantedAuthority</interfacename>
-    would be an implementation that stores a list of operations and
-    authority thresholds that apply to different customer account numbers.
-    Representing this complex <interfacename>GrantedAuthority</interfacename> 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
-    <interfacename>AccessDecisionManager</interfacename> that it will need to
-    specifically support the <interfacename>GrantedAuthority</interfacename>
-    implementation in order to understand its contents.</para>
-
-    <para>Spring Security includes one concrete
-    <interfacename>GrantedAuthority</interfacename> implementation,
-    <literal>GrantedAuthorityImpl</literal>. This allows any
-    user-specified <literal>String</literal> to be converted into a
-    <interfacename>GrantedAuthority</interfacename>. All
-    <classname>AuthenticationProvider</classname>s included with the security
-    architecture use <literal>GrantedAuthorityImpl</literal> to populate
-    the <interfacename>Authentication</interfacename> object.</para>
+    </programlisting> This method allows
+        <interfacename>AccessDecisionManager</interfacename>s to obtain a precise
+        <literal>String</literal> representation of the
+        <interfacename>GrantedAuthority</interfacename>. By returning a representation as a
+        <literal>String</literal>, a <interfacename>GrantedAuthority</interfacename> can be easily
+        <quote>read</quote> by most <interfacename>AccessDecisionManager</interfacename>s. If a
+        <interfacename>GrantedAuthority</interfacename> cannot be precisely represented as a
+        <literal>String</literal>, the <interfacename>GrantedAuthority</interfacename> is considered
+        <quote>complex</quote> and <literal>getAuthority()</literal> must return
+        <literal>null</literal>.</para>
+    <para>An example of a <quote>complex</quote>
+      <interfacename>GrantedAuthority</interfacename> would be an implementation that stores a list
+      of operations and authority thresholds that apply to different customer account numbers.
+      Representing this complex <interfacename>GrantedAuthority</interfacename> as a
+        <literal>String</literal> would be quite difficult, and as a result the
+        <literal>getAuthority()</literal> method should return <literal>null</literal>. This will
+      indicate to any <interfacename>AccessDecisionManager</interfacename> that it will need to
+      specifically support the <interfacename>GrantedAuthority</interfacename> implementation in
+      order to understand its contents.</para>
+    <para>Spring Security includes one concrete <interfacename>GrantedAuthority</interfacename>
+      implementation, <literal>GrantedAuthorityImpl</literal>. This allows any user-specified
+        <literal>String</literal> to be converted into a
+        <interfacename>GrantedAuthority</interfacename>. All
+        <classname>AuthenticationProvider</classname>s included with the security architecture use
+        <literal>GrantedAuthorityImpl</literal> to populate the
+        <interfacename>Authentication</interfacename> object.</para>
   </section>
-
   <section xml:id="pre-invocation">
     <info>
       <title>Pre-Invocation Handling</title>
     </info>
-    <para>
-      As we'll see in the <link xlink:href="#secure-objects" >Technical Overview</link> chapter, Spring
-      Security provides interceptors which control access to secure objects such as method invocations
-      or web requests. A pre-invocation decision on whether the invocation is allowed to proceed is made by
-      the <interfacename>AccessDecisionManager</interfacename>.
-    </para>
-
+    <para> As we've also seen in the <link xlink:href="#secure-objects">Technical Overview</link>
+      chapter, Spring Security provides interceptors which control access to secure objects such as
+      method invocations or web requests. A pre-invocation decision on whether the invocation is
+      allowed to proceed is made by the <interfacename>AccessDecisionManager</interfacename>. </para>
     <section>
       <title>The AccessDecisionManager</title>
-    <para>The <interfacename>AccessDecisionManager</interfacename> is called by the
-    <classname>AbstractSecurityInterceptor</classname> and is responsible for
-    making final access control decisions. The
-    <interfacename>AccessDecisionManager</interfacename> interface contains three
-    methods:
-      <programlisting>
+      <para>The <interfacename>AccessDecisionManager</interfacename> is called by the
+          <classname>AbstractSecurityInterceptor</classname> and is responsible for making final
+        access control decisions. The <interfacename>AccessDecisionManager</interfacename> interface
+        contains three methods:
+        <programlisting>
  void decide(Authentication authentication, Object secureObject, 
      List&lt;ConfigAttribute&gt; config) throws AccessDeniedException;
  boolean supports(ConfigAttribute attribute);
  boolean supports(Class clazz);
       </programlisting>
-    As can be seen from the first method, the
-    <interfacename>AccessDecisionManager</interfacename> 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 <classname>MethodInvocation</classname>. It
-    would be easy to query the <classname>MethodInvocation</classname> for any
-    <literal>Customer</literal> argument, and then implement some sort of
-    security logic in the <interfacename>AccessDecisionManager</interfacename> 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 <classname>AbstractSecurityInterceptor</classname> at
-    startup time to determine if the
-    <interfacename>AccessDecisionManager</interfacename> can process the passed
-    <literal>ConfigAttribute</literal>. The
-    <literal>supports(Class)</literal> method is called by a security
-    interceptor implementation to ensure the configured
-    <interfacename>AccessDecisionManager</interfacename> supports the type of secure
-    object that the security interceptor will present.</para>
-
-    <section>
-      <title>Voting-Based AccessDecisionManager Implementations</title>
-    <para>Whilst users can implement their own <interfacename>AccessDecisionManager</interfacename> to control all aspects of
-    authorization, Spring Security includes several <interfacename>AccessDecisionManager</interfacename> implementations that are
-    based on voting. <xref linkend="authz-access-voting"/> illustrates the relevant classes.</para>
-      <figure xml:id="authz-access-voting">
-        <title>Voting Decision Manager</title>
-      <mediaobject>
-<!--        
+        The <interfacename>AccessDecisionManager</interfacename>'s <methodname>decide</methodname>
+        method is passed all the relevant information it needs in order to make 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 <classname>MethodInvocation</classname>. It would be
+        easy to query the <classname>MethodInvocation</classname> for any
+          <literal>Customer</literal> argument, and then implement some sort of security logic in
+        the <interfacename>AccessDecisionManager</interfacename> 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
+          <classname>AbstractSecurityInterceptor</classname> at startup time to determine if the
+          <interfacename>AccessDecisionManager</interfacename> can process the passed
+          <literal>ConfigAttribute</literal>. The <literal>supports(Class)</literal> method is
+        called by a security interceptor implementation to ensure the configured
+          <interfacename>AccessDecisionManager</interfacename> supports the type of secure object
+        that the security interceptor will present.</para>
+      <section>
+        <title>Voting-Based AccessDecisionManager Implementations</title>
+        <para>Whilst users can implement their own
+            <interfacename>AccessDecisionManager</interfacename> to control all aspects of
+          authorization, Spring Security includes several
+            <interfacename>AccessDecisionManager</interfacename> implementations that are based on
+          voting. <xref linkend="authz-access-voting"/> illustrates the relevant classes.</para>
+        <figure xml:id="authz-access-voting">
+          <title>Voting Decision Manager</title>
+          <mediaobject>
+            <!--        
         <imageobject role="fo">
           <imagedata align="center" fileref="resources/images/AccessDecisionVoting.gif" format="GIF"/>
         </imageobject>
--->        
-        <imageobject>
-          <imagedata align="center" scalefit="1" fileref="images/AccessDecisionVoting.gif" format="GIF"/>
-        </imageobject>
-      </mediaobject>
-      </figure>
-    <para>Using this approach, a series of
-    <interfacename>AccessDecisionVoter</interfacename> implementations are polled on
-    an authorization decision. The
-    <interfacename>AccessDecisionManager</interfacename> then decides whether or not
-    to throw an <literal>AccessDeniedException</literal> based on its
-    assessment of the votes.</para>
-
-    <para>The <interfacename>AccessDecisionVoter</interfacename> interface has three
-    methods:
-<programlisting>
+-->
+            <imageobject>
+              <imagedata align="center" scalefit="1" fileref="images/AccessDecisionVoting.gif"
+                format="GIF"/>
+            </imageobject>
+          </mediaobject>
+        </figure>
+        <para>Using this approach, a series of <interfacename>AccessDecisionVoter</interfacename>
+          implementations are polled on an authorization decision. The
+            <interfacename>AccessDecisionManager</interfacename> then decides whether or not to
+          throw an <literal>AccessDeniedException</literal> based on its assessment of the
+          votes.</para>
+        <para>The <interfacename>AccessDecisionVoter</interfacename> interface has three methods:
+          <programlisting>
 int vote(Authentication authentication, Object object, List&lt;ConfigAttribute&gt; config);
 boolean supports(ConfigAttribute attribute);
 boolean supports(Class clazz);
 </programlisting>
-    Concrete implementations return an <literal>int</literal>, with
-    possible values being reflected in the
-    <interfacename>AccessDecisionVoter</interfacename> 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
-    <interfacename>AccessDecisionManager</interfacename>s provided with Spring
-    Security that tally the votes. The <literal>ConsensusBased</literal>
-    implementation will grant or deny access based on the consensus of
-    non-abstain votes. Properties are provided to control behavior in the
-    event of an equality of votes or if all votes are abstain. The
-    <literal>AffirmativeBased</literal> implementation will grant access
-    if one or more <literal>ACCESS_GRANTED</literal> votes were received
-    (i.e. 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
-    <interfacename>AccessDecisionManager</interfacename> that tallies votes
-    differently. For example, votes from a particular
-    <interfacename>AccessDecisionVoter</interfacename> might receive additional
-    weighting, whilst a deny vote from a particular voter may have a veto
-    effect.</para>
-
-    <section>
-      <title><classname>RoleVoter</classname></title>
-      <para>
-        The most commonly used <interfacename>AccessDecisionVoter</interfacename>
-      provided with Spring Security is the simple <classname>RoleVoter</classname>, which treats
-      configuration attributes as simple role names and votes to grant access if the user has been assigned
-      that role.</para>
-      <para>It will vote if any ConfigAttribute begins with the prefix <literal>ROLE_</literal>.
-        It will vote to grant access if there is a <interfacename>GrantedAuthority</interfacename> 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>
-    </section>
-
-      <section>
-        <title>Custom Voters</title>
-    <para>It is also possible to implement a custom
-    <interfacename>AccessDecisionVoter</interfacename>. Several examples are provided
-    in Spring Security unit tests, including
-    <literal>ContactSecurityVoter</literal> and
-    <literal>DenyVoter</literal>. The
-    <literal>ContactSecurityVoter</literal> abstains from voting decisions
-    where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal>
-    <literal>ConfigAttribute</literal> is not found. If voting, it queries
-    the <classname>MethodInvocation</classname> 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
-    <interfacename>Authentication</interfacename> object. It could have just as easily
-    compared the <literal>Contact</literal> owner with some
-    <interfacename>GrantedAuthority</interfacename> the
-    <interfacename>Authentication</interfacename> object presented. All of this is
-    achieved with relatively few lines of code and demonstrates the
-    flexibility of the authorization model.</para>
+          Concrete implementations return an <literal>int</literal>, with possible values being
+          reflected in the <interfacename>AccessDecisionVoter</interfacename> 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 <interfacename>AccessDecisionManager</interfacename>s
+          provided with Spring Security that tally the votes. The <literal>ConsensusBased</literal>
+          implementation will grant or deny access based on the consensus of non-abstain votes.
+          Properties are provided to control behavior in the event of an equality of votes or if all
+          votes are abstain. The <literal>AffirmativeBased</literal> implementation will grant
+          access if one or more <literal>ACCESS_GRANTED</literal> votes were received (i.e. 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
+            <interfacename>AccessDecisionManager</interfacename> that tallies votes differently. For
+          example, votes from a particular <interfacename>AccessDecisionVoter</interfacename> might
+          receive additional weighting, whilst a deny vote from a particular voter may have a veto
+          effect.</para>
+        <section>
+          <title><classname>RoleVoter</classname></title>
+          <para> The most commonly used <interfacename>AccessDecisionVoter</interfacename> provided
+            with Spring Security is the simple <classname>RoleVoter</classname>, which treats
+            configuration attributes as simple role names and votes to grant access if the user has
+            been assigned that role.</para>
+          <para>It will vote if any ConfigAttribute begins with the prefix <literal>ROLE_</literal>.
+            It will vote to grant access if there is a
+              <interfacename>GrantedAuthority</interfacename> 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>
+        </section>
+        <section>
+          <title>Custom Voters</title>
+          <para>It is also possible to implement a custom
+              <interfacename>AccessDecisionVoter</interfacename>. Several examples are provided in
+            Spring Security unit tests, including <literal>ContactSecurityVoter</literal> and
+              <literal>DenyVoter</literal>. The <literal>ContactSecurityVoter</literal> abstains
+            from voting decisions where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal>
+            <literal>ConfigAttribute</literal> is not found. If voting, it queries the
+              <classname>MethodInvocation</classname> 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 <interfacename>Authentication</interfacename> object. It could have just as easily
+            compared the <literal>Contact</literal> owner with some
+              <interfacename>GrantedAuthority</interfacename> the
+              <interfacename>Authentication</interfacename> object presented. All of this is
+            achieved with relatively few lines of code and demonstrates the flexibility of the
+            authorization model.</para>
         </section>
-    </section>
       </section>
+    </section>
   </section>
-
   <section xml:id="after-invocation">
-    <info><title>After Invocation Handling</title></info>
-    <para>Whilst the <interfacename>AccessDecisionManager</interfacename> is called by
-    the <classname>AbstractSecurityInterceptor</classname> before proceeding
-    with the secure object invocation, some applications need a way of
-    modifying the object actually returned by the secure object
-    invocation. Whilst you could easily implement your own AOP concern to
-    achieve this, Spring Security provides a convenient hook that has
-    several concrete implementations that integrate with its ACL
-    capabilities.</para>
-
+    <info>
+      <title>After Invocation Handling</title>
+    </info>
+    <para>Whilst the <interfacename>AccessDecisionManager</interfacename> is called by the
+        <classname>AbstractSecurityInterceptor</classname> before proceeding with the secure object
+      invocation, some applications need a way of modifying the object actually returned by the
+      secure object invocation. Whilst you could easily implement your own AOP concern to achieve
+      this, Spring Security provides a convenient hook that has several concrete implementations
+      that integrate with its ACL capabilities.</para>
     <para><xref linkend="authz-after-invocation"/> illustrates Spring Security's
-    <literal>AfterInvocationManager</literal> and its concrete
-    implementations.
-
-    <figure xml:id="authz-after-invocation">
-      <title>After Invocation Implementation</title>
-      <mediaobject>
-        <imageobject>
-          <imagedata  align="center" scalefit="1" fileref="images/AfterInvocation.gif" format="GIF"/>
-        </imageobject>
-      </mediaobject>
-
-    </figure>
-    </para>
-
-    <para>Like many other parts of Spring Security,
-    <literal>AfterInvocationManager</literal> has a single concrete
-    implementation, <literal>AfterInvocationProviderManager</literal>,
-    which polls a list of <literal>AfterInvocationProvider</literal>s.
-    Each <literal>AfterInvocationProvider</literal> is allowed to modify
-    the return object or throw an
-    <literal>AccessDeniedException</literal>. Indeed multiple providers
-    can modify the object, as the result of the previous provider is
-    passed to the next in the list. Let's now consider our ACL-aware
-    implementations of <literal>AfterInvocationProvider</literal>.</para>
-
-    <para>Please be aware that if you're using
-    <literal>AfterInvocationManager</literal>, you will still need
-    configuration attributes that allow the
-    <classname>MethodSecurityInterceptor</classname>'s
-    <interfacename>AccessDecisionManager</interfacename> to allow an operation. If
-    you're using the typical Spring Security included
-    <interfacename>AccessDecisionManager</interfacename> implementations, having no
-    configuration attributes defined for a particular secure method
-    invocation will cause each <interfacename>AccessDecisionVoter</interfacename> to
-    abstain from voting. In turn, if the
-    <interfacename>AccessDecisionManager</interfacename> property
-    "<literal>allowIfAllAbstainDecisions</literal>" is
-    <literal>false</literal>, an <literal>AccessDeniedException</literal>
-    will be thrown. You may avoid this potential issue by either (i)
-    setting "<literal>allowIfAllAbstainDecisions</literal>" to
-    <literal>true</literal> (although this is generally not recommended)
-    or (ii) simply ensure that there is at least one configuration
-    attribute that an <interfacename>AccessDecisionVoter</interfacename> will vote to
-    grant access for. This latter (recommended) approach is usually
-    achieved through a <literal>ROLE_USER</literal> or
-    <literal>ROLE_AUTHENTICATED</literal> configuration attribute</para>
-
-    <section xml:id="after-invocation-acl-aware"><info><title>ACL-Aware AfterInvocationProviders</title></info>
-<!-- TODO: Move to ACL section and add reference here -->
-      <para>A common services layer method we've all written at one stage
-      or another looks like this:</para>
-
-      <para><programlisting>public Contact getById(Integer id);</programlisting></para>
-
-      <para>Quite often, only principals with permission to read the
-      <literal>Contact</literal> should be allowed to obtain it. In this
-      situation the <interfacename>AccessDecisionManager</interfacename> approach
-      provided by the <classname>AbstractSecurityInterceptor</classname> will
-      not suffice. This is because the identity of the
-      <literal>Contact</literal> is all that is available before the
-      secure object is invoked. The
-        <classname>AclEntryAfterInvocationProvider</classname> delivers a solution,
-      and is configured as follows:
-<programlisting><![CDATA[
+        <literal>AfterInvocationManager</literal> and its concrete implementations. <figure
+        xml:id="authz-after-invocation">
+        <title>After Invocation Implementation</title>
+        <mediaobject>
+          <imageobject>
+            <imagedata align="center" scalefit="1" fileref="images/AfterInvocation.gif" format="GIF"
+            />
+          </imageobject>
+        </mediaobject>
+      </figure></para>
+    <para>Like many other parts of Spring Security, <literal>AfterInvocationManager</literal> has a
+      single concrete implementation, <literal>AfterInvocationProviderManager</literal>, which polls
+      a list of <literal>AfterInvocationProvider</literal>s. Each
+        <literal>AfterInvocationProvider</literal> is allowed to modify the return object or throw
+      an <literal>AccessDeniedException</literal>. Indeed multiple providers can modify the object,
+      as the result of the previous provider is passed to the next in the list. Let's now consider
+      our ACL-aware implementations of <literal>AfterInvocationProvider</literal>.</para>
+    <para>Please be aware that if you're using <literal>AfterInvocationManager</literal>, you will
+      still need configuration attributes that allow the
+        <classname>MethodSecurityInterceptor</classname>'s
+        <interfacename>AccessDecisionManager</interfacename> to allow an operation. If you're using
+      the typical Spring Security included <interfacename>AccessDecisionManager</interfacename>
+      implementations, having no configuration attributes defined for a particular secure method
+      invocation will cause each <interfacename>AccessDecisionVoter</interfacename> to abstain from
+      voting. In turn, if the <interfacename>AccessDecisionManager</interfacename> property
+        "<literal>allowIfAllAbstainDecisions</literal>" is <literal>false</literal>, an
+        <literal>AccessDeniedException</literal> will be thrown. You may avoid this potential issue
+      by either (i) setting "<literal>allowIfAllAbstainDecisions</literal>" to
+        <literal>true</literal> (although this is generally not recommended) or (ii) simply ensure
+      that there is at least one configuration attribute that an
+        <interfacename>AccessDecisionVoter</interfacename> will vote to grant access for. This
+      latter (recommended) approach is usually achieved through a <literal>ROLE_USER</literal> or
+        <literal>ROLE_AUTHENTICATED</literal> configuration attribute</para>
+    <section xml:id="after-invocation-acl-aware">
+      <info>
+        <title>ACL-Aware AfterInvocationProviders</title>
+      </info>
+      <!-- TODO: Move to ACL section and add reference here -->
+      <para>A common services layer method we've all written at one stage or another looks like
+        this:</para>
+      <para>
+        <programlisting>public Contact getById(Integer id);</programlisting>
+      </para>
+      <para>Quite often, only principals with permission to read the <literal>Contact</literal>
+        should be allowed to obtain it. In this situation the
+          <interfacename>AccessDecisionManager</interfacename> approach provided by the
+          <classname>AbstractSecurityInterceptor</classname> will not suffice. This is because the
+        identity of the <literal>Contact</literal> is all that is available before the secure object
+        is invoked. The <classname>AclEntryAfterInvocationProvider</classname> delivers a solution,
+        and is configured as follows: <programlisting><![CDATA[
 <bean id="afterAclRead"
    class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationProvider">
   <constructor-arg ref="aclService"/>
@@ -298,26 +249,19 @@ boolean supports(Class clazz);
     </list>
   </constructor-arg>
 </bean>
-]]></programlisting>
-        In the above example, the <literal>Contact</literal> will be
-      retrieved and passed to the
-      <classname>AclEntryAfterInvocationProvider</classname>. The provider
-      will thrown an <classname>AccessDeniedException</classname> if one of
-      the listed <literal>requirePermission</literal>s is not held by the
-      <interfacename>Authentication</interfacename>. The
-      <classname>AclEntryAfterInvocationProvider</classname> queries the
-      acl service to determine the ACL that applies for
-      this domain object to this <interfacename>Authentication</interfacename>.</para>
-
-      <para>Similar to the
-      <classname>AclEntryAfterInvocationProvider</classname> is
-      <classname>AclEntryAfterInvocationCollectionFilteringProvider</classname>.
-      It is designed to remove <literal>Collection</literal> or array
-      elements for which a principal does not have access. It never thrown
-      an <classname>AccessDeniedException</classname> - simply silently
-      removes the offending elements. The provider is configured as
-      follows:
-<programlisting><![CDATA[
+]]></programlisting> In the above example, the <literal>Contact</literal> will be retrieved and
+        passed to the <classname>AclEntryAfterInvocationProvider</classname>. The provider will
+        thrown an <classname>AccessDeniedException</classname> if one of the listed
+          <literal>requirePermission</literal>s is not held by the
+          <interfacename>Authentication</interfacename>. The
+          <classname>AclEntryAfterInvocationProvider</classname> queries the acl service to
+        determine the ACL that applies for this domain object to this
+          <interfacename>Authentication</interfacename>.</para>
+      <para>Similar to the <classname>AclEntryAfterInvocationProvider</classname> is
+          <classname>AclEntryAfterInvocationCollectionFilteringProvider</classname>. It is designed
+        to remove <literal>Collection</literal> or array elements for which a principal does not
+        have access. It never thrown an <classname>AccessDeniedException</classname> - simply
+        silently removes the offending elements. The provider is configured as follows: <programlisting><![CDATA[
 <bean id="afterAclCollectionRead"
   class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
   <constructor-arg ref="aclService"/>
@@ -328,109 +272,83 @@ boolean supports(Class clazz);
     </list>
   </constructor-arg>
 </bean>
-]]>    </programlisting>
-        As you can imagine, the returned <literal>Object</literal>
-      must be a <literal>Collection</literal> or array for this provider
-      to operate. It will remove any element if the
-      <literal>AclManager</literal> indicates the
-      <interfacename>Authentication</interfacename> does not hold one of the listed
-      <literal>requirePermission</literal>s.</para>
-
+]]>    </programlisting> As you can imagine, the returned <literal>Object</literal> must be a
+          <literal>Collection</literal> or array for this provider to operate. It will remove any
+        element if the <literal>AclManager</literal> indicates the
+          <interfacename>Authentication</interfacename> does not hold one of the listed
+          <literal>requirePermission</literal>s.</para>
       <para>The Contacts sample application demonstrates these two
-      <literal>AfterInvocationProvider</literal>s.</para>
+          <literal>AfterInvocationProvider</literal>s.</para>
     </section>
   </section>
-
   <section xml:id="authorization-taglibs">
-    <info><title>Authorization Tag Libraries</title></info>
-
-    <para><literal>AuthorizeTag</literal> is used to include content if
-    the current principal holds certain
-    <interfacename>GrantedAuthority</interfacename>s.</para>
-
+    <info>
+      <title>Authorization Tag Libraries</title>
+    </info>
+    <para><literal>AuthorizeTag</literal> is used to include content if the current principal holds
+      certain <interfacename>GrantedAuthority</interfacename>s.</para>
     <para>The following JSP fragment illustrates how to use the
-    <literal>AuthorizeTag</literal>:</para>
-
-    <para><programlisting>
+      <literal>AuthorizeTag</literal>:</para>
+    <para>
+      <programlisting>
 <![CDATA[
 <security:authorize ifAllGranted="ROLE_SUPERVISOR">
 <td>
   <a href="del.htm?id=<c:out value="${contact.id}"/>">Del</a>
 </td>
 </security:authorize>
-]]></programlisting></para>
-
-    <para>This tag would cause the tag's body to be output if the
-    principal has been granted ROLE_SUPERVISOR.</para>
-
-    <para>The <literal>security:authorize</literal> tag declares the
-    following attributes:</para>
-
-    <para><itemizedlist spacing="compact">
+]]></programlisting>
+    </para>
+    <para>This tag would cause the tag's body to be output if the principal has been granted
+      ROLE_SUPERVISOR.</para>
+    <para>The <literal>security: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>
+          <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>
+          <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>
+          <para><literal>ifNotGranted</literal>: None of the listed roles must be granted for the
+            tag to output its body.</para>
         </listitem>
-      </itemizedlist></para>
-
-    <para>You'll note that in each attribute you can list multiple roles.
-    Simply separate the roles using a comma. The
-    <literal>authorize</literal> tag ignores whitespace in
-    attributes.</para>
-
-    <para>The tag library logically ANDs all of it's parameters together.
-    This means that if you combine two or more attributes, all attributes
-    must be true for the tag to output it's body. Don't add an
-    <literal>ifAllGranted="ROLE_SUPERVISOR"</literal>, followed by an
-    <literal>ifNotGranted="ROLE_SUPERVISOR"</literal>, or you'll be
-    surprised to never see the tag's body.</para>
-
-    <para>By requiring all attributes to return true, the authorize tag
-    allows you to create more complex authorization scenarios. For
-    example, you could declare an
-    <literal>ifAllGranted="ROLE_SUPERVISOR"</literal> and an
-    <literal>ifNotGranted="ROLE_NEWBIE_SUPERVISOR"</literal> in the same
-    tag, in order to prevent new supervisors from seeing the tag body.
-    However it would no doubt be simpler to use
-    <literal>ifAllGranted="ROLE_EXPERIENCED_SUPERVISOR"</literal> rather
-    than inserting NOT conditions into your design.</para>
-
-    <para>One last item: the tag verifies the authorizations in a specific
-    order: first <literal>ifNotGranted</literal>, then
-    <literal>ifAllGranted</literal>, and finally, <literal>if
-    AnyGranted</literal>.</para>
-
-    <para><literal>AccessControlListTag</literal> is used to include
-    content if the current principal has an ACL to the indicated domain
-    object.</para>
-
+      </itemizedlist>
+    </para>
+    <para>You'll note that in each attribute you can list multiple roles. Simply separate the roles
+      using a comma. The <literal>authorize</literal> tag ignores whitespace in attributes.</para>
+    <para>The tag library logically ANDs all of it's parameters together. This means that if you
+      combine two or more attributes, all attributes must be true for the tag to output it's body.
+      Don't add an <literal>ifAllGranted="ROLE_SUPERVISOR"</literal>, followed by an
+        <literal>ifNotGranted="ROLE_SUPERVISOR"</literal>, or you'll be surprised to never see the
+      tag's body.</para>
+    <para>By requiring all attributes to return true, the authorize tag allows you to create more
+      complex authorization scenarios. For example, you could declare an
+        <literal>ifAllGranted="ROLE_SUPERVISOR"</literal> and an
+        <literal>ifNotGranted="ROLE_NEWBIE_SUPERVISOR"</literal> in the same tag, in order to
+      prevent new supervisors from seeing the tag body. However it would no doubt be simpler to use
+        <literal>ifAllGranted="ROLE_EXPERIENCED_SUPERVISOR"</literal> rather than inserting NOT
+      conditions into your design.</para>
+    <para>One last item: the tag verifies the authorizations in a specific order: first
+        <literal>ifNotGranted</literal>, then <literal>ifAllGranted</literal>, and finally,
+        <literal>if AnyGranted</literal>.</para>
+    <para><literal>AccessControlListTag</literal> is used to include content if the current
+      principal has an ACL to the indicated domain object.</para>
     <para>The following JSP fragment illustrates how to use the
-    <literal>AccessControlListTag</literal>:
-<programlisting><![CDATA[
+        <literal>AccessControlListTag</literal>: <programlisting><![CDATA[
 <security:accesscontrollist domainObject="${contact}" hasPermission="8,16">
 <td><a href="<c:url value="del.htm"><c:param name="contactId" value="${contact.id}"/></c:url>">Del</a></td>
 </security:accesscontrollist>
-]]></programlisting>
-    This tag would cause the tag's body to be output if the
-    principal holds either permission 16 or permission 1 for the "contact"
-    domain object. The numbers are actually integers that are used with
-    <literal>BasePermission</literal> bit masking. Please refer to the ACL
-    section of this reference guide to understand more about the ACL
-    capabilities of Spring Security.</para>
-
-    <para><literal>AclTag</literal> is part of the old ACL module and
-    should be considered deprecated. For the sake of historical reference,
-    works exactly the samae as
-    <literal>AccessControlListTag</literal>.</para>
+]]></programlisting> This tag would cause the tag's body to be output if the principal holds either
+      permission 16 or permission 1 for the "contact" domain object. The numbers are actually
+      integers that are used with <literal>BasePermission</literal> bit masking. Please refer to the
+      ACL section of this reference guide to understand more about the ACL capabilities of Spring
+      Security.</para>
+    <para><literal>AclTag</literal> is part of the old ACL module and should be considered
+      deprecated. For the sake of historical reference, works exactly the samae as
+        <literal>AccessControlListTag</literal>.</para>
   </section>
 </chapter>

+ 0 - 14
docs/manual/src/docbook/namespace-config.xml

@@ -637,20 +637,6 @@
           in the list of pointcuts, as the first matching expression will be used. </para>
       </section>
     </section>
-    <section xml:id="ns-intercept-methods">
-      <title>The <literal>intercept-methods</literal> Bean Decorator</title>
-      <para> This alternative syntax allows you to specify security for a specific bean by adding
-        this element within the bean itself. <programlisting language="xml"><![CDATA[
-<bean:bean id="target" class="com.mycompany.myapp.MyBean">
-    <intercept-methods>
-        <protect method="set*" access="ROLE_ADMIN" />
-        <protect method="get*" access="ROLE_ADMIN,ROLE_USER" />
-        <protect method="doSomething" access="ROLE_USER" />
-    </intercept-methods>
-</bean:bean>  
-]]></programlisting> This allows you to configure security attributes for individual methods on the
-        bean or simple wildcarded patterns. </para>
-    </section>
   </section>
   <section xml:id="ns-access-manager">
     <title>The Default AccessDecisionManager</title>

+ 2 - 2
docs/manual/src/docbook/technical-overview.xml

@@ -76,7 +76,7 @@ if (principal instanceof UserDetails) {
 }</programlisting>
         <para>The object returned by the call to <methodname>getContext()</methodname> is an
           instance of the <interfacename>SecurityContext</interfacename> interface. This is the
-          object that is kept in thread-local storage.  As we'll see below, Most authentication
+          object that is kept in thread-local storage. As we'll see below, Most authentication
           mechanisms withing Spring Security return an instance of
             <interfacename>UserDetails</interfacename> as the principal. </para>
       </section>
@@ -127,7 +127,7 @@ if (principal instanceof UserDetails) {
           <interfacename>Authentication</interfacename> is <literal>getAuthorities(</literal>). This
         method provides an array of <interfacename>GrantedAuthority</interfacename> objects. A
           <interfacename>GrantedAuthority</interfacename> is, not surprisingly, an authority that is
-        granted to the principal. Such authorities are usually "roles", such as
+        granted to the principal. Such authorities are usually <quote>roles</quote>, such as
           <literal>ROLE_ADMINISTRATOR</literal> or <literal>ROLE_HR_SUPERVISOR</literal>. These
         roles are later on configured for web authorization, method authorization and domain object
         authorization. Other parts of Spring Security are capable of interpreting these authorities,