<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="authz-arch"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <info>
    <title>Authorization Architecture</title>
  </info>
  <section xml:id="authz-authorities">
    <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
        <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="authz-pre-invocation">
    <info>
      <title>Pre-Invocation Handling</title>
    </info>
    <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 xml:id="authz-access-decision-manager">
      <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>
 void decide(Authentication authentication, Object secureObject,
     List&lt;ConfigAttribute&gt; config) throws AccessDeniedException;
 boolean supports(ConfigAttribute attribute);
 boolean supports(Class clazz);
      </programlisting>
        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>
    <section xml:id="authz-voting-based">
      <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>
            <imagedata align="center" fileref="images/access-decision-voting.png"
              format="PNG" scale="75"/>
          </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 xml:id="authz-role-voter">
        <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 <interfacename>ConfigAttribute</interfacename> 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 the
          prefix <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.</para>
      </section>
      <section xml:id="authz-authenticated-voter">
        <title><classname>AuthenticatedVoter</classname></title>
        <para> Another voter which we've implicitly seen is the
            <classname>AuthenticatedVoter</classname>, which can be used to differentiate between
          anonymous, fully-authenticated and remember-me authenticated users. Many sites allow
          certain limited access under remember-me authentication, but require a user to confirm
          their identity by logging in for full access.</para>
        <para>When we've used the attribute <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> to grant
          anonymous access, this attribute was being processed by the
            <classname>AuthenticatedVoter</classname>. See the Javadoc for this class for more
          information. </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 xml:id="authz-after-invocation-handling">
    <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" fileref="images/after-invocation.png" format="PNG" scale="75"/>
          </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.</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>
    <!-- TODO: Move to ACL section and add reference here -->
    <!--
    <section xml:id="after-invocation-acl-aware">
      <info>
        <title>ACL-Aware AfterInvocationProviders</title>
      </info>

      <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"/>
  <constructor-arg>
    <list>
      <ref local="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
      <ref local="org.springframework.security.acls.domain.BasePermission.READ"/>
    </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[
<bean id="afterAclCollectionRead"
  class="org.springframework.security.acls.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider">
  <constructor-arg ref="aclService"/>
  <constructor-arg>
    <list>
      <ref local="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
      <ref local="org.springframework.security.acls.domain.BasePermission.READ"/>
    </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>
      <para>The Contacts sample application demonstrates these two
          <literal>AfterInvocationProvider</literal>s.</para>
          </section>   -->
  </section>
  <!-- TODO: Move taglibs to a separate chapter which describes them all
  <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>
    <para>The following JSP fragment illustrates how to use the
      <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">
        <listitem>
          <para><literal>ifAllGranted</literal>: All the listed roles must be granted for the tag to
            output its body.</para>
        </listitem>
        <listitem>
          <para><literal>ifAnyGranted</literal>: Any of the listed roles must be granted for the tag
            to output its body.</para>
        </listitem>
        <listitem>
          <para><literal>ifNotGranted</literal>: None of the listed roles must be granted for the
            tag to output its body.</para>
        </listitem>
      </itemizedlist>
    </para>
    <para>You'll note that in each attribute you can list multiple roles. Simply separate the roles
      using a comma. The <literal>authorize</literal> tag ignores whitespace in attributes.</para>
    <para>The tag library logically ANDs all of it's parameters together. This means that if you
      combine two or more attributes, all attributes must be true for the tag to output it's body.
      Don't add an <literal>ifAllGranted="ROLE_SUPERVISOR"</literal>, followed by an
        <literal>ifNotGranted="ROLE_SUPERVISOR"</literal>, or you'll be surprised to never see the
      tag's body.</para>
    <para>By requiring all attributes to return true, the authorize tag allows you to create more
      complex authorization scenarios. For example, you could declare an
        <literal>ifAllGranted="ROLE_SUPERVISOR"</literal> and an
        <literal>ifNotGranted="ROLE_NEWBIE_SUPERVISOR"</literal> in the same tag, in order to
      prevent new supervisors from seeing the tag body. However it would no doubt be simpler to use
        <literal>ifAllGranted="ROLE_EXPERIENCED_SUPERVISOR"</literal> rather than inserting NOT
      conditions into your design.</para>
    <para>One last item: the tag verifies the authorizations in a specific order: first
        <literal>ifNotGranted</literal>, then <literal>ifAllGranted</literal>, and finally,
        <literal>if AnyGranted</literal>.</para>
    <para><literal>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[
<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>
  </section> -->
</chapter>
