In this article , we will take a closer look at the Spring security authorization workflow and architecture. This is part of our spring security tutorial, so make sure you are following the complete series for better understanding.
Spring Security Authorization
In the previous part of this series, we saw how Authentication works with Spring security. We also saw how the AuthenticationManager will user details service will create a list of granted authorities and save it in the Authentication object. In this part, we will see how the Spring security authorization works and how it use different underlying artifacts. Spring security use the FilterSecurityInterceptor servlet filter, this filter is responsible to provide a decision if a particular request to access a given resource is accepted or rejected.
Keep in mind that before authorization process in invoked, the user is already authenticated and security framework is aware that user is a logged in user. As part of the authentication, we will also provide a list of GrantedAuthorities
(List<GrantedAuthority> getAuthorities()
) which will be used by the spring security authentication to decide if a request is allowed or not.
1. AccessDecisionManager
The AccessDecisionManager
interface is responsible to take a decision on whether the invocation is allowed to proceed. The AccessDecisionMamanger
is called by the FilterSecurityInterceptor
. Let’s take a look at the AcsessDecisionManager
interface.
public interface AccessDecisionManager {
void decide(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes) throws AccessDeniedException,
InsufficientAuthenticationException;
boolean supports(ConfigAttribute attribute);
boolean supports(Class<?> clazz);
}
Let’s take a look at the different method available in the interface:
support
– This method tell decision manager if it supports the current request.decide
– This tells theAccessDecisionManager
to verify if the given request should be allowed or not. Keep in mind that this method does not have any return value but throws an exception to report denial.
2. Voting Based AccessDecisionManager
Spring Security provides a number of AccessDecisionManager
to help us work on the authorization in Spring security. It also provides the flexibility to create our own DecisionManager
if required. Here is the high level overview of the Spring security access decision manager.
With voting based decision manager, 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 AcessDecisionManger interface have the following 3 methods:
int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attrs);
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
Here is an overview of the voting decision manager workflow:
3. Configuring AcessDecisionManager
By default Spring security use the AffirmativeBased
decision manager but it also provide us the flexibility to configure a different decision manager. We need customize the http
element to override the default access decision manager. Let’s take a look at the following example to see how to change the access decision manger to UnanimousBased
from AffirmativeBased
decision manager.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.accessDecisionManager(accessDecisionManager());
}
/**
* How to change the default access decision manager in Spring security
* @return
*/
@Bean
public AccessDecisionManager accessDecisionManager() {
List < AccessDecisionVoter << ? extends Object >> decisionVoters = Arrays.asList(
new AuthenticatedVoter(),
new RoleVoter(),
new WebExpressionVoter()
);
return new UnanimousBased(decisionVoters);
}
There are few important things to understand:
- The
decisionVoter
property is auto configured by Spring security until we defined our own configuration. Remember, Spring security by default configureAffirmativeBased
decision manager. - We need to provide list of decision voter to the AccessDecisionManager who will be consulted to take the authorization decision. The voter will decide if given request is authorized or not.
4. Authorize HttpServletRequest
To better understand Spring security authorization workflow, let’s take a look at the following workflow
- The
FilterSecurityInterceptor
filter is responsible to provide a decision if a particular request to access a given resource is accepted or rejected. - The
FilterSecurityInterceptor
filter will obtain theAuthenticated
object from theSecurityContextHolder
. In most cases Authorization is performed after authentication. - The
AccessDecisionManager
will use the Authentication,FilterInvocation
andConfigAttribute
to take the decision. AccessDeniedException
will be thrown in case the request is not authorized.- If access is granted
FilterSecurityInterceptor
continues with the FilterChain which allows the application to process normally.
Summary
In this article, we understood the basic of Spring security authorization workflow and architecture. We leaned how Spring security use the different DecisionManager
and decision voters during the authorization workflow. The source code for this series is available on our GitHub repository.