# Authorization Architecture

## Authorities

As we saw in the technical overview, all Authentication implementations store a list of GrantedAuthority objects. These represent the authorities that have been granted to the principal. The GrantedAuthority objects are inserted into the Authentication object by the AuthenticationManager and are later read by AccessDecisionManagers when making authorization decisions.

GrantedAuthority is an interface with only one method:

      String getAuthority();

This method allows AccessDecisionManagers to obtain a precise `String` representation of the GrantedAuthority. By returning a representation as a `String`, a GrantedAuthority can be easily read by most AccessDecisionManagers. If a GrantedAuthority cannot be precisely represented as a `String`, the GrantedAuthority is considered complex and `getAuthority()` must return `null`.

An example of a complex GrantedAuthority would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers. Representing this complex GrantedAuthority as a `String` would be quite difficult, and as a result the `getAuthority()` method should return `null`. This will indicate to any AccessDecisionManager that it will need to specifically support the GrantedAuthority implementation in order to understand its contents.

Spring Security includes one concrete GrantedAuthority implementation, `GrantedAuthorityImpl`. This allows any user-specified `String` to be converted into a GrantedAuthority. All `AuthenticationProvider`s included with the security architecture use `GrantedAuthorityImpl` to populate the Authentication object.

## Pre-Invocation Handling

As we've also seen in the Technical Overview 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 AccessDecisionManager.

### The AccessDecisionManager

The AccessDecisionManager is called by the `AbstractSecurityInterceptor` and is responsible for making final access control decisions. The AccessDecisionManager interface contains three methods:

     void decide(Authentication authentication, Object secureObject,
         Collection<ConfigAttribute> attrs) throws AccessDeniedException;
     boolean supports(ConfigAttribute attribute);
     boolean supports(Class clazz);

The AccessDecisionManager's `decide` method is passed all the relevant information it needs in order to make an authorization decision. In particular, passing the secure `Object` enables those arguments contained in the actual secure object invocation to be inspected. For example, let's assume the secure object was a `MethodInvocation`. It would be easy to query the `MethodInvocation` for any `Customer` argument, and then implement some sort of security logic in the AccessDecisionManager to ensure the principal is permitted to operate on that customer. Implementations are expected to throw an `AccessDeniedException` if access is denied.

The `supports(ConfigAttribute)` method is called by the `AbstractSecurityInterceptor` at startup time to determine if the AccessDecisionManager can process the passed `ConfigAttribute`. The `supports(Class)` method is called by a security interceptor implementation to ensure the configured AccessDecisionManager supports the type of secure object that the security interceptor will present.

### Voting-Based AccessDecisionManager Implementations

Whilst users can implement their own AccessDecisionManager to control all aspects of authorization, Spring Security includes several AccessDecisionManager implementations that are based on voting. illustrates the relevant classes.

#### Voting Decision Manager

Using this approach, a series of AccessDecisionVoter implementations are polled on an authorization decision. The AccessDecisionManager then decides whether or not to throw an `AccessDeniedException` based on its assessment of the votes.

The AccessDecisionVoter interface has three methods:

    int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attrs);
    boolean supports(ConfigAttribute attribute);
    boolean supports(Class clazz);

Concrete implementations return an `int`, with possible values being reflected in the AccessDecisionVoter static fields `ACCESS_ABSTAIN`, `ACCESS_DENIED` and `ACCESS_GRANTED`. A voting implementation will return `ACCESS_ABSTAIN` if it has no opinion on an authorization decision. If it does have an opinion, it must return either `ACCESS_DENIED` or `ACCESS_GRANTED`.

There are three concrete AccessDecisionManagers provided with Spring Security that tally the votes. The `ConsensusBased` 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 `AffirmativeBased` implementation will grant access if one or more `ACCESS_GRANTED` votes were received (i.e. a deny vote will be ignored, provided there was at least one grant vote). Like the `ConsensusBased` implementation, there is a parameter that controls the behavior if all voters abstain. The `UnanimousBased` provider expects unanimous `ACCESS_GRANTED` votes in order to grant access, ignoring abstains. It will deny access if there is any `ACCESS_DENIED` vote. Like the other implementations, there is a parameter that controls the behaviour if all voters abstain.

It is possible to implement a custom AccessDecisionManager that tallies votes differently. For example, votes from a particular AccessDecisionVoter might receive additional weighting, whilst a deny vote from a particular voter may have a veto effect.

#### `RoleVoter`

The most commonly used AccessDecisionVoter provided with Spring Security is the simple `RoleVoter`, which treats configuration attributes as simple role names and votes to grant access if the user has been assigned that role.

It will vote if any ConfigAttribute begins with the prefix `ROLE_`. It will vote to grant access if there is a GrantedAuthority which returns a `String` representation (via the `getAuthority()` method) exactly equal to one or more `ConfigAttributes` starting with the prefix `ROLE_`. If there is no exact match of any `ConfigAttribute` starting with `ROLE_`, the `RoleVoter` will vote to deny access. If no `ConfigAttribute` begins with `ROLE_`, the voter will abstain.

#### `AuthenticatedVoter`

Another voter which we've implicitly seen is the `AuthenticatedVoter`, 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.

When we've used the attribute `IS_AUTHENTICATED_ANONYMOUSLY` to grant anonymous access, this attribute was being processed by the `AuthenticatedVoter`. See the Javadoc for this class for more information.

#### Custom Voters

Obviously, you can also implement a custom AccessDecisionVoter and you can put just about any access-control logic you want in it. It might be specific to your application (business-logic related) or it might implement some security administration logic. For example, you'll find a blog article on the SpringSource web site which describes how to use a voter to deny access in real-time to users whose accounts have been suspended.

## After Invocation Handling

Whilst the AccessDecisionManager is called by the `AbstractSecurityInterceptor` 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.

illustrates Spring Security's `AfterInvocationManager` and its concrete implementations.

### After Invocation Implementation

Like many other parts of Spring Security, `AfterInvocationManager` has a single concrete implementation, `AfterInvocationProviderManager`, which polls a list of `AfterInvocationProvider`s. Each `AfterInvocationProvider` is allowed to modify the return object or throw an `AccessDeniedException`. Indeed multiple providers can modify the object, as the result of the previous provider is passed to the next in the list.

Please be aware that if you're using `AfterInvocationManager`, you will still need configuration attributes that allow the `MethodSecurityInterceptor`'s AccessDecisionManager to allow an operation. If you're using the typical Spring Security included AccessDecisionManager implementations, having no configuration attributes defined for a particular secure method invocation will cause each AccessDecisionVoter to abstain from voting. In turn, if the AccessDecisionManager property "`allowIfAllAbstainDecisions`" is `false`, an `AccessDeniedException` will be thrown. You may avoid this potential issue by either (i) setting "`allowIfAllAbstainDecisions`" to `true` (although this is generally not recommended) or (ii) simply ensure that there is at least one configuration attribute that an AccessDecisionVoter will vote to grant access for. This latter (recommended) approach is usually achieved through a `ROLE_USER` or `ROLE_AUTHENTICATED` configuration attribute.

## Hierarchical Roles

It is a common requirement that a particular role in an application should automatically include other roles. For example, in an application which has the concept of an admin and a user role, you may want an admin to be able to do everything a normal user can. To achieve this, you can either make sure that all admin users are also assigned the user role. Alternatively, you can modify every access constraint which requires the user role to also include the admin role. This can get quite complicated if you have a lot of different roles in your application.

The use of a role-hierarchy allows you to configure which roles (or authorities) should include others. An extended version of Spring Security's `RoleVoter`, `RoleHierarchyVoter`, is configured with a RoleHierarchy, from which it obtains all the reachable authorities which the user is assigned. A typical configuration might look like this:

    <bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
        <constructor-arg ref="roleHierarchy" />
    </class>
    <bean id="roleHierarchy"
            class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
        <property name="hierarchy">
            ROLE_ADMIN > ROLE_STAFF
            ROLE_STAFF > ROLE_USER
            ROLE_USER > ROLE_GUEST
        </property>
    </bean>

Here we have four roles in a hierarchy `ROLE_ADMIN => ROLE_STAFF => ROLE_USER => ROLE_GUEST`. A user who is authenticated with `ROLE_ADMIN`, will behave as if they have all four roles when security contraints are evaluated against an AccessDecisionManager cconfigured with the above `RoleHierarchyVoter`. The `>` symbol can be thought of as meaning includes.

Role hierarchies offer a convenient means of simplifying the access-control configuration data for your application and/or reducing the number of authorities which you need to assign to a user. For more complex requirements you may wish to define a logical mapping between the specific access-rights your application requires and the roles that are assigned to users, translating between the two when loading the user information.