1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- = Web Migrations
- [[use-path-pattern]]
- == Use PathPatternRequestMatcher by Default
- In Spring Security 7, `AntPathRequestMatcher` and `MvcRequestMatcher` are no longer supported and the Java DSL requires that all URIs be absolute (less any context root).
- At that time, Spring Security 7 will use `PathPatternRequestMatcher` by default.
- To check how prepared you are for this change, you can publish this bean:
- [tabs]
- ======
- Java::
- +
- [source,java,role="primary"]
- ----
- @Bean
- PathPatternRequestMatcherBuilderFactoryBean requestMatcherBuilder() {
- return new PathPatternRequestMatcherBuilderFactoryBean();
- }
- ----
- Kotlin::
- +
- [source,kotlin,role="secondary"]
- ----
- @Bean
- fun requestMatcherBuilder(): PathPatternRequestMatcherBuilderFactoryBean {
- return PathPatternRequestMatcherBuilderFactoryBean()
- }
- ----
- ======
- This will tell the Spring Security DSL to use `PathPatternRequestMatcher` for all request matchers that it constructs.
- In the event that you are directly constructing an object (as opposed to having the DSL construct it) that has a `setRequestMatcher` method. you should also proactively specify a `PathPatternRequestMatcher` there as well.
- For example, in the case of `LogoutFilter`, it constructs an `AntPathRequestMatcher` in Spring Security 6:
- [method,java]
- ----
- private RequestMatcher logoutUrl = new AntPathRequestMatcher("/logout");
- ----
- and will change this to a `PathPatternRequestMatcher` in 7:
- [method,java]
- ----
- private RequestMatcher logoutUrl = PathPatternRequestMatcher.path().matcher("/logout");
- ----
- If you are constructing your own `LogoutFilter`, consider calling `setLogoutRequestMatcher` to provide this `PathPatternRequestMatcher` in advance.
- == Include the Servlet Path Prefix in Authorization Rules
- For many applications <<use-path-pattern, the above>> will make no difference since most commonly all URIs listed are matched by the default servlet.
- However, if you have other servlets with servlet path prefixes, xref:servlet/authorization/authorize-http-requests.adoc[then these paths now need to be supplied separately].
- For example, if I have a Spring MVC controller with `@RequestMapping("/orders")` and my MVC application is deployed to `/mvc` (instead of the default servlet), then the URI for this endpoint is `/mvc/orders`.
- Historically, the Java DSL hasn't had a simple way to specify the servlet path prefix and Spring Security attempted to infer it.
- Over time, we learned that these inference would surprise developers.
- Instead of taking this responsibility away from developers, now it is simpler to specify the servlet path prefix like so:
- [method,java]
- ----
- PathPatternRequestParser.Builder servlet = PathPatternRequestParser.servletPath("/mvc");
- http
- .authorizeHttpRequests((authorize) -> authorize
- .requestMatchers(servlet.pattern("/orders/**").matcher()).authenticated()
- )
- ----
- For paths that belong to the default servlet, use `PathPatternRequestParser.path()` instead:
- [method,java]
- ----
- PathPatternRequestParser.Builder request = PathPatternRequestParser.path();
- http
- .authorizeHttpRequests((authorize) -> authorize
- .requestMatchers(request.pattern("/js/**").matcher()).authenticated()
- )
- ----
- Note that this doesn't address every kind of servlet since not all servlets have a path prefix.
- For example, expressions that match the JSP Servlet might use an ant pattern `/**/*.jsp`.
- There is not yet a general-purpose replacement for these, and so you are encouraged to use `RegexRequestMatcher`, like so: `regexMatcher("\\.jsp$")`.
- For many applications this will make no difference since most commonly all URIs listed are matched by the default servlet.
|