1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Simplify Java Configuration RequestMatcher Usage

If Spring MVC is present in the classpath, use MvcRequestMatcher by default. This commit also adds a new securityMatcher method in HttpSecurity

Closes gh-11347
Closes gh-9159
This commit is contained in:
Marcus Da Coregio
2022-09-21 10:09:35 -03:00
committed by Marcus Hert Da Coregio
parent bf59d7c374
commit 039e0328e1
18 changed files with 1395 additions and 46 deletions
@@ -109,13 +109,14 @@ SecurityFilterChain web(HttpSecurity http, AuthorizationManager<RequestAuthoriza
@Bean
AuthorizationManager<RequestAuthorizationContext> requestMatcherAuthorizationManager(HandlerMappingIntrospector introspector) {
MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
RequestMatcher permitAll =
new AndRequestMatcher(
new MvcRequestMatcher(introspector, "/resources/**"),
new MvcRequestMatcher(introspector, "/signup"),
new MvcRequestMatcher(introspector, "/about"));
RequestMatcher admin = new MvcRequestMatcher(introspector, "/admin/**");
RequestMatcher db = new MvcRequestMatcher(introspector, "/db/**");
mvcMatcherBuilder.pattern("/resources/**"),
mvcMatcherBuilder.pattern("/signup"),
mvcMatcherBuilder.pattern("/about"));
RequestMatcher admin = mvcMatcherBuilder.pattern("/admin/**");
RequestMatcher db = mvcMatcherBuilder.pattern("/db/**");
RequestMatcher any = AnyRequestMatcher.INSTANCE;
AuthorizationManager<HttpRequestServlet> manager = RequestMatcherDelegatingAuthorizationManager.builder()
.add(permitAll, (context) -> new AuthorizationDecision(true))
@@ -145,7 +145,7 @@ You could refer to the method using:
----
http
.authorizeHttpRequests(authorize -> authorize
.antMatchers("/user/**").access("@webSecurity.check(authentication,request)")
.requestMatchers("/user/**").access("@webSecurity.check(authentication,request)")
...
)
----
@@ -211,7 +211,7 @@ You could refer to the method using:
----
http
.authorizeHttpRequests(authorize -> authorize
.antMatchers("/user/{userId}/**").access("@webSecurity.checkUserId(authentication,#userId)")
.requestMatchers("/user/{userId}/**").access("@webSecurity.checkUserId(authentication,#userId)")
...
);
----
@@ -139,8 +139,8 @@ If we wanted to restrict access to this controller method to admin users, a deve
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.antMatchers("/admin").hasRole("ADMIN")
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/admin").hasRole("ADMIN")
);
return http.build();
}
@@ -152,8 +152,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests {
authorize(AntPathRequestMatcher("/admin"), hasRole("ADMIN"))
authorizeHttpRequests {
authorize("/admin", hasRole("ADMIN"))
}
}
return http.build()
@@ -177,21 +177,24 @@ Additionally, depending on our Spring MVC configuration, the URL `/admin/` will
The problem is that our security rule is only protecting `/admin`.
We could add additional rules for all the permutations of Spring MVC, but this would be quite verbose and tedious.
Instead, we can leverage Spring Security's `MvcRequestMatcher`.
The following configuration will protect the same URLs that Spring MVC will match on by using Spring MVC to match on the URL.
Fortunately, when using the `requestMatchers` DSL method, Spring Security automatically creates a `MvcRequestMatcher` if it detects that Spring MVC is available in the classpath.
Therefore, it will protect the same URLs that Spring MVC will match on by using Spring MVC to match on the URL.
One common requirement when using Spring MVC is to specify the servlet path property, for that you can use the `MvcRequestMatcher.Builder` to create multiple `MvcRequestMatcher` instances that share the same servlet path:
====
.Java
[source,java,role="primary"]
----
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector).servletPath("/path");
http
.authorizeHttpRequests(authorize -> authorize
.mvcMatchers("/admin").hasRole("ADMIN")
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers(mvcMatcherBuilder.pattern("/admin")).hasRole("ADMIN")
.requestMatchers(mvcMatcherBuilder.pattern("/user")).hasRole("USER")
);
// ...
return http.build();
}
----
@@ -199,25 +202,19 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
[source,kotlin,role="secondary"]
----
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
open fun filterChain(http: HttpSecurity, introspector: HandlerMappingIntrospector): SecurityFilterChain {
val mvcMatcherBuilder = MvcRequestMatcher.Builder(introspector)
http {
authorizeRequests {
authorize("/admin", hasRole("ADMIN"))
authorizeHttpRequests {
authorize(mvcMatcherBuilder.pattern("/admin"), hasRole("ADMIN"))
authorize(mvcMatcherBuilder.pattern("/user"), hasRole("USER"))
}
}
// ...
return http.build()
}
----
====
or in XML
[source,xml]
----
<http request-matcher="mvc">
<intercept-url pattern="/admin" access="hasRole('ADMIN')"/>
</http>
----
[[mvc-authentication-principal]]
== @AuthenticationPrincipal
@@ -567,7 +567,7 @@ public class WebSecurityConfig {
http
.csrf(csrf -> csrf
// ignore our stomp endpoints since they are protected using Stomp headers
.ignoringAntMatchers("/chat/**")
.ignoringRequestMatchers("/chat/**")
)
.headers(headers -> headers
// allow same origin to frame our site to support iframe SockJS
@@ -591,7 +591,7 @@ open class WebSecurityConfig {
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
csrf {
ignoringAntMatchers("/chat/**")
ignoringRequestMatchers("/chat/**")
}
headers {
frameOptions {
+2
View File
@@ -11,3 +11,5 @@ Below are the highlights of the release.
* https://github.com/spring-projects/spring-security/pull/11232[gh-11232] - `ClientRegistrations#rest` defines 30s connect and read timeouts
* https://github.com/spring-projects/spring-security/pull/11464[gh-11464] - Remember Me supports SHA256 algorithm
* https://github.com/spring-projects/spring-security/pull/11908[gh-11908] - Make X-Xss-Protection header value configurable in ServerHttpSecurity
* https://github.com/spring-projects/spring-security/issues/11347[gh-11347] - Simplify Java Configuration `RequestMatcher` Usage
* https://github.com/spring-projects/spring-security/issues/9159[gh-9159] - Add `securityMatcher` as an alias on `requestMatcher` in `HttpSecurity`