9.3. Authorization¶
Caution
This version is already obsolete. Please check the latest guideline.
Table of contents
- Overview
- How to use
- How to extend
9.3.1. Overview¶
This chapter explains authorization function provided by Spring Security.
Authorization process controls the resources that can be accessed by the users of the application. The standard method to control the resources that can be accessed by the user include defining an access policy for each resource (or a group of resources) and control the resources by checking the access policy when the user tries to access a resource.
Access policy defines whether to allow a user to access a particular resource. An access policy for following 3 types of resources is defined in Spring Security.
- Web resource
- Java method
- Domain object [1]
- Screen fields of JSP
This section introduces an implementation example (definition example) wherein authorization process is applied to access “Web resource”, “Java method” and “Screen fields of JSP” and explains the authorization function of Spring Security.
[1] | For authorization function to access domain object , refer Spring Security Reference -Domain Object Security (ACLs)-. |
9.3.1.1. Authorization process architecture¶
Spring Security performs authorization process as per the flow below.
Sr. No. | Description |
---|---|
(1)
|
A client accesses any resource.
|
(2)
|
FilterSecurityInterceptor class calls AccessDecisionManager interface method and checks whether the user has access rights for the resource. |
(3)
|
AffirmativeBased class (Implementation class of AccessDecisionManager used as a default) calls AccessDecisionVoter interface method and votes for whether the user has access rights. |
(4)
|
FilterSecurityInterceptor accesses the resource only if the access rights have been granted by AccessDecisionManager . |
9.3.1.1.1. ExceptionTranslationFilter¶
ExceptionTranslationFilter
is a security filter which handles exceptions generated by authorization process (AccessDecisionManager
) and sends appropriate response to the client.
In the default implementation, a response to ask for authentication in case of access by an unauthenticated user and a response to throw an authorization error in case of an authenticated user are returned.
9.3.1.1.2. FilterSecurityInterceptor¶
FilterSecurityInterceptor
is a security filter to apply an authorization process for HTTP request and delegates actual authorization process to AccessDecisionManager
.
While calling a method of AccessDecisionManager
interface, it is linked with the access policy specified in the resource which a client trying to access.
9.3.1.1.3. AccessDecisionManager¶
AccessDecisionManager
interface checks whether the user has the access rights for the resource which he is trying to access.
Spring Security provides 3 types of implementation classes and all the classes call AccessDecisionVoter
interface method and determine whether the access rights have been granted.
AccessDecisionVoter
votes for “Assign”, “Deny” or Abstain” and then implementation class of AccessDecisionManager
aggregates the voting results and determines final access rights.
AccessDeniedException
exception is thrown and access is denied if determined as “no access rights”.
Note that, if all the voting results indicate “Abstain”, it is determined as “no access rights” in Spring Security by default.
Class name | Description |
---|---|
AffirmativeBased |
An implementation class which assigns the access rights when 1 vote is given to “Assign” during voting by
AccessDecisionVoter .Implementation class used as a default.
|
ConsensusBased |
An implementation class which assigns the access rights when the majority of votes are for “Assign” during voting for all
AccessDecisionVoter .When 1 vote each is given to “Assign” and “Deny” or when it is a tie, it is considered as “Have access rights” by default in Spring Security.
|
UnanimousBased |
An implementation class which does not give access rights when 1 vote is given to “Deny” during voting by
AccessDecisionVoter . |
Note
Selecting AccessDecisionVoter
If only one AccessDecisionVoter
is used, no difference is observed in the operation regardless of the implementation class.
When multiple AccessDecisionVoter
are used, implementation class should be selected in accordance with the requirements.
9.3.1.1.4. AccessDecisionVoter¶
AccessDecisionVoter
is an interface which checks the access policy specified in the resource which the user is trying to access and votes for whether the access rights are to be granted.
Main implementation classes provided by Spring Security are as given below.
Class name | Description |
---|---|
WebExpressionVoter |
An implementation class which carries out voting by checking the rights information retained by authentication information (
Authentication ) through SpEL and request information (HttpServletRequest ). |
RoleVoter |
An implementation class which carries out voting by checking the role of the user.
|
RoleHierarchyVoter |
An implementation class which carries out voting by checking the role hierarchy of a user.
|
AuthenticatedVoter |
An implementation class which carries out voting by checking the authentication status.
|
Note
AccessDecisionVoter to be applied by default
Implementation class of AccessDecisionVoter
interface applied by default is integrated with WebExpressionVoter
from Spring Security 4.0 onwards.
Since WebExpressionVoter
can play the role similar to using RoleVoter
,RoleHierarchyVoter
and AuthenticatedVoter
,
this guideline will also assume the use of default WebExpressionVoter
for explaining authorization process.
9.3.2. How to use¶
A bean definition example (how to specify an access policy) and implementation method required for using authorization function are explained.
9.3.2.1. How to describe an access policy¶
How to describe an access policy is explained.
Spring Security supports Spring Expression Language (SpEL) as a method which describes how to specify an access policy. Although there are other methods which do not use SpEL, this guideline explains how to specify an access policy by using Expression. How to use SpEL is briefly explained in this section, however for detailed description, refer Spring Framework Reference Documentation -Spring Expression Language (SpEL)-.
9.3.2.1.1. Built-In Common Expressions¶
Common Expressions provided by Spring Security are as given below.
Expression | Description |
---|---|
hasRole(String role) |
Return
true when logged in user has a role specified in the argument. |
hasAnyRole(String... roles) |
Return
true when logged in user has one of the roles specified in the argument. |
isAnonymous() |
Return
true in case of an anonymous user who has not logged in. |
isRememberMe() |
Return
true in case of a user logged in by using Remember Me authentication. |
isAuthenticated() |
Return
true in case of a login. |
isFullyAuthenticated() |
Return
true in case of a user who has logged in using normal authentication process instead of Remember Me authentication. |
permitAll |
Always return
true . |
denyAll |
Always return
false . |
principal |
Return user information of authenticated user (an object of a class which implements
UserDetails interface). |
authentication |
Return authentication information of authenticated user (an object of a class which implements
Authentication interface). |
Note
Accessing authentication information which uses Expression
Since user information and authentication information of a logged in user can be accessed when principal
and authentication
are used as Expressions, an access policy can be set by using attributes other than role.
Note
Role name prefix
It was necessary to specify "ROLE_"
prefix to role name till Spring Security 3.2. However, specifying "ROLE_"
prefix is no longer required from Spring Security 4.0 onwards.
Example)
- Before Spring Security 3.2 :
hasRole('ROLE_USER')
- Spring Security 4.0 onwards :
hasRole('USER')
9.3.2.1.2. Built-In Web Expressions¶
Expressions for Web applications provided by Spring Security are as below.
Expression | Description |
---|---|
hasIpAddress(String ipAddress) |
Return
true when requested IP address matches the IP address system specified in the argument. |
9.3.2.1.3. Using operator¶
Determination using an operator can also be performed. In the example below, access can be granted if both role and requested IP address match.
Definition example of spring-security.xml
<sec:http> <sec:intercept-url pattern="/admin/**" access="hasRole('ADMIN') and hasIpAddress('192.168.10.1')"/> <!-- omitted --> </sec:http>
List of operators that can be used
Operator Description [expression-1] and [expression-2]
Return true when both expression-1 and expression-2 are true.[expression-1] or [expression-2]
Return true when one of the expressions is true.![expression]
Return false when expression is true and return true when expression is false.
9.3.2.2. Authorization of Web resource¶
Spring Security performs authorization process for Web resource (HTTP request) using a servlet filter system.
9.3.2.2.1. Applying authorization process¶
Define a bean as below when authorization process is to be applied for a Web resource.
- Definition example of spring-security.xml
<sec:http>
<!-- omitted -->
<sec:intercept-url pattern="/**" access="isAuthenticated()" /> <!-- (1) -->
<!-- omitted -->
</sec:http>
Sr. No. | Description |
---|---|
(1)
|
Define an access policy in
<sec:intercept-url> tag for a HTTP request.Here, an access policy is defined by using SpEL wherein “Only authenticated users are granted access for all the requests under a Web application”.
|
Note
Default definition of use-expressions
Since default value of use-expressions
attribute of <sec:http>
tag is changed to true
from Spring Security 4.0 onwards, it is no longer necessary to explicitly describe while using true
.
9.3.2.2.2. Defining access policy¶
How to define an access policy for a Web resource using a bean definition file is explained.
9.3.2.2.2.1. Specifying a Web resource for applying access policy¶
First, a resource (HTTP request) for which an access policy is to be applied, is specified.
Attribute under <sec:intercept-url>
tag is used for the specification of a resource for which an access policy is to be applied.
Attribute name | Description |
---|---|
pattern |
An attribute which uses a resource matching with path pattern specified in Ant format or regular expression as an application target.
|
method |
An attribute which uses a resource as an application target when access is to be done by using specified HTTP methods (GET, POST etc).
|
requires-channel |
Specify “http” or “https”. An attribute for controlling the access by specified protocol.
if it is not specified, either of these can be accessed.
|
For the attributes other than above, refer <intercept-url>.
- Definition example of
<sec:intercept-url>
tagpattern
attribute (spring-security.xml)
<sec:http >
<sec:intercept-url pattern="/admin/accounts/**" access="..."/>
<sec:intercept-url pattern="/admin/**" access="..."/>
<sec:intercept-url pattern="/**" access="..."/>
<!-- omitted -->
</sec:http>
Spring Security matches the requests in the defined order and the definition which is matched at first is applied. Therefore, definition order must be taken into consideration even while specifying an access policy by using a bean definition file.
Tip
Interpretation of path pattern
Path pattern is interpreted in Ant format, in the default operation of Spring Security.
When the path pattern is to be specified in the regular expression, "regex"
should be specified in request-matcher
attribute of <sec:http>
tag
<sec:http request-matcher="regex"> <sec:intercept-url pattern="/admin/accounts/.*" access=hasRole('ACCOUNT_MANAGER')" /> <!-- omitted --> </sec:http>
Warning
Specifications of path matching for AntPathRequestMatcher used by Spring Security by default are now case sensitive for Spring Security 4.1 and subsequent versions.
For example, as shown below, when an access policy is to be defined for endpoint of Spring MVC which allocates /Todo/List
path,
the values specified in pattern
attribute of <sec:intercept-url>
tag must be aligned for uppercase and lowercase letters like /Todo/List
and /Todo/*
.
If the values not aligned by uppercase and lowercase letters like /todo/list
and /todo/**
are specified accidentally, it should be noted that intended authorization control cannot be performed.
- Implementation example of Spring MVC endpoint
@RequestMapping(value="/Todo/List") public String viewTodoList(){ //... }
- Definition example of access policy
<sec:http> <sec:intercept-url pattern="/Todo/List" access="isAuthenticated()" /> <!-- omitted --> </sec:http>
Warning
In Spring MVC and Spring Security, the mechanism of matching with the request is strictly different, and there is a vulnerability that breaks through the authorization function of Spring Security and can access the handler method using this difference. For details of this vulnerability, refer to “CVE-2016-5007 Spring Security / MVC Path Matching Inconsistency”.
This vulnerability occurs when the Bean of org.springframework.util.AntPathMatcher set true to trimTokens property is applied to Spring MVC. In Spring Framework 4.2 and earlier, the default value of the trimTokens property was set to true , but since the default value was changed to false from Spring Framework 4.3, this vulnerability does not occur unless user intentionally change the property.
In the blank project of TERASOLUNA Server Framework for Java (5.3.x), trimTokens property is set to false like below, However, if user set the property to true , this vulnerability can occur. So don’t change the value.
<mvc:annotation-driven> <!-- ommited --> <mvc:path-matching path-matcher="pathMatcher" /> </mvc:annotation-driven> <bean id="pathMatcher" class="org.springframework.util.AntPathMatcher"> <property name="trimTokens" value="false" /> </bean>
Further, if an access policy for a specific URL is to be specified (wild cards like *
, **
etc are not included in pattern
attribute),
an access policy with a pattern with an extension and a pattern with /
appended at the end of request path must be added.
In the following configuration example, only the users with “ROLE_ADMIN” role are allowed to access by /restrict
.
<sec:http> <sec:intercept-url pattern="/restrict.*" access="hasRole('ADMIN')" /> <!-- (1) --> <sec:intercept-url pattern="/restrict/" access="hasRole('ADMIN')" /> <!-- (2) --> <sec:intercept-url pattern="/restrict" access="hasRole('ADMIN')" /> <!-- (3) --> <!-- omitted --> </sec:http>
Sr. No. Description (1) Define an access policy of the pattern with an extension (/restrict.json
etc) in/restrict
. (2) Define an access policy of the pattern wherein/
appended at the end of the request path (/restrict/
etc) in/restrict
. (3) Define an access policy for/restrict
.
9.3.2.2.2.2. Specifying an access policy¶
Next, an access policy is specified.
Access policy is specified in access
attribute of <sec:intercept-url>
tag.
Definition example of
<sec:intercept-url>
tagaccess
attribute (spring-security.xml
)<sec:http> <sec:intercept-url pattern="/admin/accounts/**" access="hasRole('ACCOUNT_MANAGER')"/> <sec:intercept-url pattern="/admin/configurations/**" access="hasIpAddress('127.0.0.1') and hasRole('CONFIGURATION_MANAGER')" /> <sec:intercept-url pattern="/admin/**" access="hasRole('ADMIN')" /> <!-- omitted --> </sec:http>
¶ Attribute name Description access
Specify access control expression using SpEL and a role that can be accessed.
Definition example of
<sec:intercept-url>
tagpattern
attribute (spring-security.xml)<sec:http> <sec:intercept-url pattern="/reserve/**" access="hasAnyRole('USER','ADMIN')" /> <!-- (1) --> <sec:intercept-url pattern="/admin/**" access="hasRole('ADMIN')" /> <!-- (2) --> <sec:intercept-url pattern="/**" access="denyAll" /> <!-- (3) --> <!-- omitted --> </sec:http>
Sr. No. Description (1)To access “//reserve/**”, either the role “ROLE_USER” or “ROLE_ADMIN” is required.hasAnyRole
will be described later.(2)To access “/admin/**”, the role “ROLE_ADMIN” is required.hasRole
will be described later.(3)denyAll
is set for all patternsAny user should not be able to access a URL for which no rights settings are described.denyAll
will be described later.Note
About description sequence of URL pattern
The request received from client is matched with the pattern in intercept-url, starting from the top and access is granted for the matched pattern. Therefore, pattern should always be described from limited patterns.
SpEL is enabled in Spring Security by default.
SpEL described in access
attribute is determined as a true value. If the expression is true, access is granted.
How to use is shown below.
Definition example of spring-security.xml
<sec:http> <sec:intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/> <!-- (1) --> <!-- omitted --> </sec:http>
Sr. No. Description (1)Return true if the logged in user retains the specified role, by specifyinghasRole('Role name')
.
For main Expression that can be used, refer How to describe an access policy.
9.3.2.2.2.3. Reference of path variables¶
In Spring Security 4.1 and subsequent versions, a path variable [#fPathVariableDescription]_ can be used while specifying a resource which applies the access policy
and can be referred by specifying #path variable name
in the definition of access policy.
In the example below, the access policy is defined so that the login users can access only their own user information.
Definition example of spring-security.xml
<sec:http> <sec:intercept-url pattern="/users/{userName}" access="isAuthenticated() and #userName == principal.username"/> <!-- omitted --> </sec:http>
Warning
Precautions while defining an access policy which uses the path variable
When an access policy which uses a path variable for the path that can be accessed with an extension, is defined, it is necessary to define it in such a way that the extension part is not stored in the path variable value.
For example, when /users/{userName}
is defined in the patten and a request path /users/personName.json
is sent,
personName.json
gets stored in the path variable #userName
referred in the definition of access policy, instead of personName
and unintended authorization control is performed.
In order to prevent this event, “Access policy for the path without extension” must be defined after defining “Access policy for the path with extension” as shown in the example below.
- Definition example of spring-security.xml
<sec:http> <sec:intercept-url pattern="/users/{userName}.*" access="isAuthenticated() and #userName == principal.username"/> <!-- (1) --> <sec:intercept-url pattern="/users/{userName}" access="isAuthenticated() and #userName == principal.username"/> <!-- (2) --> <!-- omitted --> </sec:http>
Sr. No. Description (1) Define “Access policy for the path with extension”. (2) Define “Access policy for the path without extension”.
9.3.2.3. Authorization for the method¶
Spring Security performs authorization process for calling a method of Bean which is managed in DI container by using Spring AOP system.
Authorization process for the method is provided by considering its use for calling a domain layer (service layer) method. If authorization process for the method is used, a detailed access policy can be defined since a property of domain object can be checked.
9.3.2.3.1. Enabling AOP¶
When the authorization process for the method is to be used, a component (AOP) for performing authorization process for calling the method must be enabled. If AOP is enabled, access policy can be defined in the method annotation.
Spring Security supports following annotations.
@PreAuthorize
,@PostAuthorize
,@PreFilter
,@PostFilter
- JSR-250 (
javax.annotation.security
package) annotation (@RolesAllowed
etc.) @Secured
This guideline explains how to use @PreAuthorize
and @PostAuthorize
which enable the use of access policy by Expression.
- Definition example of spring-security.xml
<sec:global-method-security pre-post-annotations="enabled" /> <!-- (1) (2) -->
Sr. No. | Description |
---|---|
(1)
|
AOP which performs authorization process for method calling is enabled if
<sec:global-method-security> tag is assigned. |
(2)
|
Specify
true in pre-post-annotations attribute.If
true is specified in pre-post-annotations attribute, the annotation that can define an access policy by specifying Expression is enabled. |
9.3.2.3.2. Applying authorization process¶
An annotation which specifies an access policy is used and an access policy is defined for each method by applying authorization process for the method.
9.3.2.3.3. Defining access policy¶
9.3.2.3.3.1. Specifying an access policy to be applied prior to method execution¶
When an access policy is to be specified for applying prior to method execution, @PreAuthorize
is used.
When the results of the Expression specified in value
attribute of @PreAuthorize
become true
, execution of the method is allowed.
In the example below, it has been defined that only administrator can access the account information for other persons.
- Definition example of
@PreAuthorize
// (1) (2)
@PreAuthorize("hasRole('ADMIN') or (#username == principal.username)")
public Account findOne(String username) {
return accountRepository.findOne(username);
}
Sr. No. | Description |
---|---|
(1)
|
Assign
@PreAuthorize to the method which needs to be authorized. |
(2)
|
Define an access policy for the method, in
value attribute.Here, an access policy - “Allow access to all accounts for the administrator” and “Allow access to only individual account when other than administrator” is defined.
|
The part wherein a method argument is accessed from the Expression is discussed here.
Specifically, “#username
” part accesses the argument.
A method argument can be accessed by specifying Expression of “# + argument name” format in Expression.
Tip
Annotation which specifies argument name
Spring Security resolves the argument name from debug information output in the class.
However an argument name can be explicitly specified by using an annotation (@org.springframework.security.access.method.P
)
A variable name can be specified explicitly by using the annotation if it is applicable to following cases.
Debug information of variable is not output in the class
When it is to be accessed by using a name different from that of actual variable name in the Expression (for example shortened name)
@PreAuthorize("hasRole('ADMIN') or (#username == principal.username)") public Account findOne(@P("username") String username) { return accountRepository.findOne(username); }
Note that when #username
and a method argument - username
name are identical, @P
can be omitted.
However, since Spring Security resolves the argument name by using an argument name of implementation class, note that the argument name of implementation class should match with #username specified in @PreAuthorize
when @PreAuthorize
annotation is defined in the interface.
When compile option added from JDK 8 (-parameters
) is used, meta data for reflection is generated in the method parameter. Hence argument name is resolved even when the annotation is not specified.
9.3.2.3.3.2. Specifying access policy to be applied after method execution¶
When an access policy to be applied after execution of the method is specified, @PostAuthorize
is used.
When the results of the Expression specified in value
attribute of @PostAuthorize
become true, results of method execution are returned to the call source.
In the example below, it has been defined such that the user is not allowed to access the information of the user belonging to other department.
- Definition example of
@PostAuthorize
@PreAuthorize("...")
@PostAuthorize("(returnObject == null) " +
"or (returnObject.departmentCode == principal.account.departmentCode)")
public Account findOne(String username) {
return accountRepository.findOne(username);
}
The part wherein the return value of the method is accessed from the Expression is discussed here.
Specifically, “returnObject.departmentCode
” part accesses the return value.
The return value of the method can be accessed by specifying returnObject
in the Expression.
9.3.2.4. Authorization for JSP screen fields¶
Spring Security can apply authorization process for JSP screen fields by using a JSP tag library.
Here, a method to apply authorization process for accessing JSP screen fields is explained using a simple definition as an example.
9.3.2.4.1. Defining an access policy¶
A condition to allow display (access policy) is defined in JSP while defining an access policy for JSP screen fields using a JSP tag library.
- Definition example of access policy
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!-- (1) -->
<sec:authorize access="hasRole('ADMIN')"> <!-- (2) -->
<h2>Admin Menu</h2>
<!-- omitted -->
</sec:authorize>
Sr. No. | Description |
---|---|
(1)
|
Enclose part for which an access policy is to be applied with
<sec:authorize> tag. |
(2)
|
Define an access policy in
access attribute. Here, an access policy - “allow display in case of administrator” is defined. |
9.3.2.4.2. Linking with the access policy specified in the Web resource¶
When an access policy is to be defined for buttons or links (screen fields associated with the requests to the server), it is linked with an access policy defined in the Web resource for request.
url
attribute of <sec:authorize>
tag is used for linking with access policy specified in the Web resource.
JSP process implemented in <sec:authorize>
tag is executed only when Web resource specified in url
attribute can be accessed.
- Example of linking with access policy defined in Web resource
<ul>
<!-- (1) -->
<sec:authorize url="/admin/accounts"> <!-- (2) -->
<li>
<a href="<c:url value='/admin/accounts' />">Account Management</a>
</li>
</sec:authorize>
</ul>
Sr. No. | Description |
---|---|
(1)
|
Enclose part which outputs button or link with
<sec:authorize> tag. |
(2)
|
Specify a URL for accessing a Web resource in
url attribute of <sec:authorize> tag.Here, an access policy - “Allow display when a Web resource allocated with
"/admin/accounts" URL can be accessed” is defined however it is not necessary to be directly aware of the access policy defined in Web resource. |
Note
Specifying a policy by HTTP method
When a different access policy is specified by HTTP method while defining an access policy of Web resource, the definition to be linked must be identified by using method
attribute of <sec:authorize>
tag.
Warning
Notes related to display control
When display for a button or link is to be controlled, it should always be linked with an access policy defined in the Web resource.
If an access policy is not defined independently for a Web resource by specifying a direct access policy for button or link, an unauthorized access such as accessing a URL directly cannot be prevented.
9.3.2.4.3. Storing determination results of authorization process in the variable¶
Determination results of authorization process called by using <sec:authorize>
tag can be reused by storing in the variable.
- Implementation example of JSP
<sec:authorize url="/admin/accounts"
var="hasAccountsAuthority"/> <!-- (1) -->
<c:if test="${hasAccountsAuthority}"> <!-- (2) -->
<!-- omitted -->
</c:if>
Sr. No. | Description |
---|---|
(1)
|
Specify a variable name for storing determination results in
var attribute.When access is allowed,
true is set in the variable. |
(2)
|
Refer variable value and implement display process.
|
9.3.2.5. Response at the time of authorization error¶
Spring Security handles the errors as shown in the following flow and controls the response when access to a resource is denied.
Sr. No. | Description |
---|---|
(1)
|
Spring Security generates a
AccessDeniedException for denying access to a resource or a method. |
(2)
|
ExceptionTranslationFilter class catches AccessDeniedException and performs error handling by calling methods of AccessDeniedHandler or AuthenticationEntryPoint interface. |
(3)
|
Perform error handling by calling a method of
AccessDeniedHandler interface in case of an access by authenticated user. |
(4)
|
Perform error handling by calling a method of
AuthenticationEntryPoint interface in case of an access by unauthenticated user. |
9.3.2.5.1. AccessDeniedHandler¶
AccessDeniedHandler
interface handles the error responses when the access is denied to authenticated users.
Spring Security offers following classes as the implementation class of AccessDeniedHandler
interface.
Class name | Description |
---|---|
AccessDeniedHandlerImpl |
Set 403 (Forbidden) in HTTP response code and move to specified error page.
When error page is not specified, send error response (
HttpServletResponse#sendError ) by setting 403 (Forbidden) in HTTP response code. |
InvalidSessionAccessDeniedHandler |
Delegate the process to implementation class of
InvalidSessionStrategy interface.This class is used when the settings to detect a session timeout is enabled by using CSRF countermeasure and session management function at the time when CSRF token does not exist in the session (a session timeout has occurred).
|
DelegatingAccessDeniedHandler |
Map implementation classes of
AccessDeniedException and AccessDeniedHandler interface and delegate the process to the implementation class of AccessDeniedHandler interface corresponding to AccessDeniedException thus occurred.InvalidSessionAccessDeniedHandler is called by using this mechanism. |
In the default setting of Spring Security, AccessDeniedHandlerImpl
is used wherein an error page is not specified.
9.3.2.5.2. AuthenticationEntryPoint¶
AuthenticationEntryPoint
interface handles the error responses when the access is denied to unauthenticated users.
Spring Security offers following class as an implementation class of AuthenticationEntryPoint
interface.
Class Name | Description |
---|---|
LoginUrlAuthenticationEntryPoint |
Display a login form for form authentication.
|
BasicAuthenticationEntryPoint |
Send error response for Basic authentication.
Specifically, set 401 (Unauthorized) in HTTP response code,
WWW-Authenticate header for Basic authentication as a response header and send error response (HttpServletResponse#sendError ). |
DigestAuthenticationEntryPoint |
Send error response for Digest authentication.
Specifically, set 401 (Unauthorised) in the HTTP response code,
WWW-Authenticate header for Digest authentication as a response header and send error response (HttpServletResponse#sendError ). |
Http403ForbiddenEntryPoint |
Set 403 (Forbidden) in HTTP response code and send error response (
HttpServletResponse#sendError ). |
DelegatingAuthenticationEntryPoint |
Map implementation class of
RequestMatcher and AuthenticationEntryPoint interface, and delegate the process to implementation class of AuthenticationEntryPoint interface corresponding to HTTP request. |
Implementation class of AuthenticationEntryPoint
interface corresponding to authentication method is used in the default setup of Spring Security.
9.3.2.5.3. Transition destination at the time of authorization error¶
In the default setting of Spring Security, when the access is denied to the authenticated user, an error page of application server is displayed. If error page of application server is displayed, it is likely to result in system degradation. Hence it is recommended to display an appropriate error screen. Error page can be specified by defining a bean as below.
- Definition example of spring-security.xml
<sec:http>
<!-- omitted -->
<sec:access-denied-handler
error-page="/WEB-INF/views/common/error/accessDeniedError.jsp" /> <!-- (1) -->
<!-- omitted -->
</sec:http>
Sr. No. | Description |
---|---|
(1)
|
Specify an error page for authorization error in
error-page attribute of <sec:access-denied-handler> tag. |
Tip
Using error page function of servlet container
Error page for authorization error can also be specified by using an error page function of servlet container.
When error page function of servlet container is used, error page is specified by using <error-page>
tag of web.xml
.
<error-page> <error-code>403</error-code> <location>/WEB-INF/views/common/error/accessDeniedError.jsp</location> </error-page>
9.3.3. How to extend¶
This section explains customization points and extension methods offered by Spring Security.
Spring Security provides a lot of customization points of which only a few will be introduced here. This section will focus on some typical customization points.
9.3.3.1. Response at the time of authorization error (Authenticated user)¶
Here, a method to customise the operation when an access from authenticated user is denied, is explained.
9.3.3.1.1. Applying AccessDeniedHandler¶
When the requirements are not met only by customising default operation provided by Spring Security, implementation class of AccessDeniedHandler
interface can be directly applied.
For example, when an authorization error occurs in Ajax request (REST API etc), error information is displayed in JSON format instead of displaying an error page (HTML).
In such a case, an implementation class of AccessDeniedHandler
interface can be created and applied in Spring Security.
- How to create an implementation class of AccessDeniedHandler interface
public class JsonDelegatingAccessDeniedHandler implements AccessDeniedHandler {
private final RequestMatcher jsonRequestMatcher;
private final AccessDeniedHandler delegateHandler;
public JsonDelegatingAccessDeniedHandler(
RequestMatcher jsonRequestMatcher, AccessDeniedHandler delegateHandler) {
this.jsonRequestMatcher = jsonRequestMatcher;
this.delegateHandler = delegateHandler;
}
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException)
throws IOException, ServletException {
if (jsonRequestMatcher.matches(request)) {
// response error information of JSON format
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
// omitted
} else {
// response error page of HTML format
delegateHandler.handle(
request, response, accessDeniedException);
}
}
}
- Definition example of spring-security.xml
<!-- (1) -->
<bean id="accessDeniedHandler"
class="com.example.web.security.JsonDelegatingAccessDeniedHandler">
<constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/api/**"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage"
value="/WEB-INF/views/common/error/accessDeniedError.jsp"/>
</bean>
</constructor-arg>
</bean>
<sec:http>
<!-- omitted -->
<sec:access-denied-handler ref="accessDeniedHandler" /> <!-- (2) -->
<!-- omitted -->
</sec:http>
Sr. No. | Description |
---|---|
(1) | Define a bean for implementation class of AccessDeniedHandler interface and register in DI container. |
(2) | Specify a bean for AccessDeniedHandler in ref attribute of <sec:access-denied-handler> tag. |
9.3.3.2. Response at the time of authorization error (Unauthenticated user)¶
Here, a method to customise operation when access is denied to an unauthenticated user, is explained.
9.3.3.2.1. Applying AuthenticationEntryPoint for each request¶
Similarly to authenticated user, when authorization error occurs in Ajax request (REST API etc), error information is displayed in JSON format instead of displaying it in login page (HTML).
In such a case, implementation class of AuthenticationEntryPoint
interface for each pattern of request is applied in Spring Security.
- Definition example of spring-security.xml
<!-- (1) -->
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<constructor-arg>
<map>
<entry>
<key>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg value="/api/**"/>
</bean>
</key>
<bean class="com.example.web.security.JsonAuthenticationEntryPoint"/>
</entry>
</map>
</constructor-arg>
<property name="defaultEntryPoint">
<bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login"/>
</bean>
</property>
</bean>
<sec:http entry-point-ref="authenticationEntryPoint"> <!-- (2) -->
<!-- omitted -->
</sec:http>
Sr. No. | Description |
---|---|
(1)
|
Define a bean for implementation class of
AuthenticationEntryPoint interface and register in DI container.Here, an implementation class of
AuthenticationEntryPoint interface is applied for each pattern of request by using DelegatingAuthenticationEntryPoint class offered by Spring Security. |
(2)
|
Specify a bean for
AuthenticationEntryPoint in entry-point-ref attribute of <sec:http> tag. |
Note
AuthenticationEntryPoint applied by default
When the implementation class of AuthenticationEntryPoint
interface corresponding to request is not specified, the implementation class of AuthenticationEntryPoint
interface defined by Spring Security by default is used.
When form authentication is used as an authentication method, LoginUrlAuthenticationEntryPoint
class is used and login form is displayed.
9.3.3.3. Role hierarchy¶
A hierarchy can be set for a role in the authorization process.
Higher level roles can also access the resources for which access is granted to the lower level roles. When the role relation is complex, hierarchy relation must also be established.
For example, when a hierarchy relation is established wherein “ROLE_ADMIN” is a higher role and “ROLE_USER” is a lower role,
and if an access policy is set as below, user with “ROLE_ADMIN” rights can access a path under "/user"
(a path which can be accessed by a user with “ROLE_USER” rights).
- Definition example of spring-security.xml
<sec:http>
<sec:intercept-url pattern="/user/**" access="hasAnyRole('USER')" />
<!-- omitted -->
</sec:http>
9.3.3.3.1. Setting hierarchy relation¶
Role hierarchy relation is resolved by using implementation class of org.springframework.security.access.hierarchicalroles.RoleHierarchy
interface.
- Definition example of spring-security.xml
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl"> <!-- (1) -->
<property name="hierarchy"> <!-- (2) -->
<value>
ROLE_ADMIN > ROLE_STAFF
ROLE_STAFF > ROLE_USER
</value>
</property>
</bean>
Sr. No. | Description |
---|---|
(1)
|
Specify
org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl class.RoleHierarchyImpl is a default implementation class offered by Spring Security. |
(2)
|
Define the hierarchy relation in
hierarchy property.Format : [Higher role] > [Lower role]
In the example above,
STAFF can also access resources authorised by USER.
ADMIN can also access resources authorised by USER and STAFF.
|
9.3.3.3.2. Applying authorization process of Web resource¶
A method to apply role hierarchy to authorization process for Web resource and JSP screen fields is explained.
Definition example of spring-security.xml
<!-- (1) --> <bean id="webExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"> <property name="roleHierarchy" ref="roleHierarchy"/> <!-- (2) --> </bean> <sec:http> <!-- omitted --> <sec:expression-handler ref="webExpressionHandler" /> <!-- (3) --> </sec:http>
Sr. No.
|
Explanation
|
---|---|
(1)
|
Define a Bean for
org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler . |
(2)
|
Specify a Bean for implementation class of
RoleHierarchy interface in roleHierarchy property. |
(3)
|
Specify a Bean for implementation class of
org.springframework.security.access.expression.SecurityExpressionHandler interface in ref attribute of <sec:expression-handler> tag. |
9.3.3.3.3. Applying authorization process of method¶
A method to apply role hierarchy to authorization process for Java method is explained.
- Definition example of spring-security.xml
<bean id="methodExpressionHandler"
class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"> <!-- (1) -->
<property name="roleHierarchy" ref="roleHierarchy"/> <!-- (2) -->
</bean>
<sec:global-method-security pre-post-annotations="enabled">
<sec:expression-handler ref="methodExpressionHandler" /> <!-- (3) -->
</sec:global-method-security>
Sr. No. | Description |
---|---|
(1)
|
Define a Bean for
org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler . |
(2)
|
Specify a Bean for implementation class of
RoleHierarchy interface in roleHierarchy property. |
(3)
|
Specify a Bean for implementation class of
org.springframework.security.access.expression.SecurityExpressionHandler interface in ref attribute of <sec:expression-handler> tag. |