|
For the latest stable version, please use Spring Security 6.3.3! |
|
For the latest stable version, please use Spring Security 6.3.3! |
FilterSecurityInterceptor is in the process of being replaced by AuthorizationFilter.
Consider using that instead.
|
This section builds on Servlet Architecture and Implementation by digging deeper into how authorization works within Servlet based applications.
The FilterSecurityInterceptor provides authorization for HttpServletRequests.
It is inserted into the FilterChainProxy as one of the Security Filters.
-
First, the FilterSecurityInterceptorobtains an Authentication from the SecurityContextHolder. -
Second, FilterSecurityInterceptorcreates aFilterInvocationfrom theHttpServletRequest,HttpServletResponse, andFilterChainthat are passed into theFilterSecurityInterceptor. -
Next, it passes the FilterInvocationtoSecurityMetadataSourceto get theConfigAttributes. -
Finally, it passes the Authentication,FilterInvocation, andConfigAttributes to the xref:servlet/authorization.adoc#authz-access-decision-manager`AccessDecisionManager`.-
If authorization is denied, an AccessDeniedExceptionis thrown. In this case theExceptionTranslationFilterhandles theAccessDeniedException. -
If access is granted, FilterSecurityInterceptorcontinues with the FilterChain which allows the application to process normally.
-
By default, Spring Security’s authorization will require all requests to be authenticated. The explicit configuration looks like:
We can configure Spring Security to have different rules by adding more rules in order of precedence.
-
Java
-
XML
-
Kotlin
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.authorizeRequests(authorize -> authorize (1)
.mvcMatchers("/resources/**", "/signup", "/about").permitAll() (2)
.mvcMatchers("/admin/**").hasRole("ADMIN") (3)
.mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") (4)
.anyRequest().denyAll() (5)
);
return http.build();
}
<http> (1)
<!-- ... -->
(2)
<intercept-url pattern="/resources/**" access="permitAll"/>
<intercept-url pattern="/signup" access="permitAll"/>
<intercept-url pattern="/about" access="permitAll"/>
<intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/> (3)
<intercept-url pattern="/db/**" access="hasRole('ADMIN') and hasRole('DBA')"/> (4)
<intercept-url pattern="/**" access="denyAll"/> (5)
</http>
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests { (1)
authorize("/resources/**", permitAll) (2)
authorize("/signup", permitAll)
authorize("/about", permitAll)
authorize("/admin/**", hasRole("ADMIN")) (3)
authorize("/db/**", "hasRole('ADMIN') and hasRole('DBA')") (4)
authorize(anyRequest, denyAll) (5)
}
}
return http.build()
}
| 1 | There are multiple authorization rules specified. Each rule is considered in the order they were declared. |
| 2 | We specified multiple URL patterns that any user can access. Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". |
| 3 | Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN".
You will notice that since we are invoking the hasRole method we do not need to specify the "ROLE_" prefix. |
| 4 | Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA".
You will notice that since we are using the hasRole expression we do not need to specify the "ROLE_" prefix. |
| 5 | Any URL that has not already been matched on is denied access. This is a good strategy if you do not want to accidentally forget to update your authorization rules. |
FilterSecurityInterceptor is in the process of being replaced by AuthorizationFilter.
Consider using that instead.
|
| 1 | There are multiple authorization rules specified. Each rule is considered in the order they were declared. |
| 2 | We specified multiple URL patterns that any user can access. Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". |
| 3 | Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN".
You will notice that since we are invoking the hasRole method we do not need to specify the "ROLE_" prefix. |
| 4 | Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA".
You will notice that since we are using the hasRole expression we do not need to specify the "ROLE_" prefix. |
| 5 | Any URL that has not already been matched on is denied access. This is a good strategy if you do not want to accidentally forget to update your authorization rules. |
Apply FilterSecurityInterceptor to every request
By default, the FilterSecurityInterceptor only applies once to a request.
This means that if a request is dispatched from a request that was already filtered, the FilterSecurityInterceptor will back-off and not perform any authorization checks.
In some scenarios, you may want to apply the filter to every request.
You can configure Spring Security to apply the authorization rules to every request by using the filterSecurityInterceptorOncePerRequest method:
-
Java
-
XML
@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.authorizeRequests((authorize) -> authorize
.filterSecurityInterceptorOncePerRequest(false)
.anyRequest.authenticated()
)
// ...
return http.build();
}
<http once-per-request="false">
<intercept-url pattern="/**" access="authenticated"/>
</http>
You can also configure authorization based on the request dispatcher type:
-
Java
-
XML
@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.authorizeRequests((authorize) -> authorize
.filterSecurityInterceptorOncePerRequest(false)
.dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll()
.anyRequest.authenticated()
)
// ...
return http.build();
}
<http auto-config="true" once-per-request="false">
<intercept-url request-matcher-ref="dispatcherTypeMatcher" access="permitAll" />
<intercept-url pattern="/**" access="authenticated"/>
</http>
<b:bean id="dispatcherTypeMatcher" class="org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher">
<b:constructor-arg value="ASYNC"/>
</b:bean>