このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Security 6.4.5 を使用してください! |
Web 移行
相対 URI を優先する
ログインエンドポイントにリダイレクトする場合、Spring Security はこれまで絶対 URI を優先してきました。例: ログインページを次のように設定した場合:
Java
Kotlin
XML
http
// ...
.formLogin((form) -> form.loginPage("/my-login"))
// ...
http {
formLogin {
loginPage = "/my-login"
}
}
<http ...>
<form-login login-page="/my-login"/>
</http>
/my-login
にリダイレクトする場合、Spring Security は次のような Location:
を使用します。
302 Found
// ...
Location: https://myapp.example.org/my-login
ただし、基になった RFC が廃止されたため、これはもはや必要ありません。
Spring Security 7 では、次のように相対 URI を使用するように変更されます。
302 Found
// ...
Location: /my-login
ほとんどのアプリケーションでは違いはわかりません。ただし、この変更によって問題が発生する場合は、favorRelativeUrls
値を設定して Spring Security 6 の動作に戻すことができます。
Java
Kotlin
XML
LoginUrlAuthenticationEntryPoint entryPoint = new LoginUrlAuthenticationEntryPoint("/my-login");
entryPoint.setFavorRelativeUris(false);
http
// ...
.exceptionHandling((exceptions) -> exceptions.authenticaitonEntryPoint(entryPoint))
// ...
LoginUrlAuthenticationEntryPoint entryPoint = LoginUrlAuthenticationEntryPoint("/my-login")
entryPoint.setFavorRelativeUris(false)
http {
exceptionHandling {
authenticationEntryPoint = entryPoint
}
}
<http entry-point-ref="myEntryPoint">
<!-- ... -->
</http>
<b:bean id="myEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<b:property name="favorRelativeUris" value="true"/>
</b:bean>
PortResolver
Spring Security は、Internet Explorer のバグの回避策を提供するために、PortResolver
という API を使用します。この回避策は不要になり、一部のシナリオではユーザーに問題を引き起こす可能性があります。このため、Spring Security 7 は PortResolver
インターフェースを削除します。
この変更に備えて、ユーザーは PortResolver.NO_OP
を portResolver
という名前の Bean として公開する必要があります。これにより、使用される PortResolver
実装が no-op(つまり何もしない)となり、PortResolver
の削除をシミュレートします。設定例を以下に示します。
Java
Kotlin
XML
@Bean
PortResolver portResolver() {
return PortResolver.NO_OP;
}
@Bean
open fun portResolver(): PortResolver {
return PortResolver.NO_OP
}
<util:constant id="portResolver"
static-field="org.springframework.security.web.PortResolver.NO_OP">
デフォルトで PathPatternRequestMatcher を使用する
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:
Java
Kotlin
XML
@Bean
PathPatternRequestMatcherBuilderFactoryBean requestMatcherBuilder() {
return new PathPatternRequestMatcherBuilderFactoryBean();
}
@Bean
fun requestMatcherBuilder(): PathPatternRequestMatcherBuilderFactoryBean {
return PathPatternRequestMatcherBuilderFactoryBean()
}
<b:bean class="org.springframework.security.config.web.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.
Migrate exitUserUrl
and switchUserUrl
Request Matchers in SwitchUserFilter
SwitchUserFilter
, constructs an AntPathRequestMatcher
in its setExitUserUrl
and setSwitchUserUrl
methods. This will change to use PathPatternRequestMatcher
in Spring Security 7.
To prepare for this change, call setExitUserMatcher
and setSwithcUserMatcher
to provide this PathPatternRequestMatcher
in advance. That is, change this:
Java
Kotlin
SwitchUserFilter switchUser = new SwitchUserFilter();
// ... other configuration
switchUser.setExitUserUrl("/exit/impersonate");
val switchUser = SwitchUserFilter()
// ... other configuration
switchUser.setExitUserUrl("/exit/impersonate")
これに:
Java
Kotlin
SwitchUserFilter switchUser = new SwitchUserFilter();
// ... other configuration
switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/exit/impersonate"));
val switchUser = SwitchUserFilter()
// ... other configuration
switchUser.setExitUserMatcher(PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/exit/impersonate"))
Migrate filterProcessingUrl
Request Matcher in AbstractAuthenticationProcessingFilter
Implementations
Spring Security 6 converts any processing endpoint configured through setFilterProcessingUrl
to an AntPathRequestMatcher
. In Spring Security 7, this will change to PathPatternRequestMatcher
.
If you are directly invoking setFilterProcessingUrl
on a filter that extends AbstractAuthenticationProcessingFilter
, like UsernamePasswordAuthenticationFilter
、OAuth2LoginAuthenticationFilter
、Saml2WebSsoAuthenticationFilter
、OneTimeTokenAuthenticationFilter
, or WebAuthnAuthenticationFilter
, call setRequiredAuthenticationRequestMatcher
instead to provide this PathPatternRequestMatcher
in advance.
That is, change this:
Java
Kotlin
UsernamePasswordAuthenticationFilter usernamePassword = new UsernamePasswordAuthenticationFilter(authenticationManager);
usernamePassword.setFilterProcessingUrl("/my/processing/url");
val usernamePassword = UsernamePasswordAuthenticationFilter(authenticationManager)
usernamePassword.setFilterProcessingUrl("/my/processing/url")
これに:
Java
Kotlin
UsernamePasswordAuthenticationFilter usernamePassword = new UsernamePasswordAuthenticationFilter(authenticationManager);
RequestMatcher requestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/my/processing/url");
usernamePassword.setRequest(requestMatcher);
val usernamePassword = UsernamePasswordAuthenticationFilter(authenticationManager)
val requestMatcher = PathPatternRequestMatcher.withDefaults().matcher("/my/processing/url")
usernamePassword.setRequest(requestMatcher)
Most applications use the DSL instead of setting the `filterProcessingUrl` directly on a filter instance.
Migrate CAS Proxy Receptor Request Matcher
Spring Security 6 converts any configured proxyReceptorUrl
to a request matcher that matches the end of the request, that is /**/proxy/receptor
. In Spring Security 7, this pattern is not allowed and will change to using PathPatternRequestMatcher
. Also in Spring Security 7m the URL should by absolute, excluding any context path, like so: /proxy/receptor
.
So to prepare for these change, you can use setProxyReceptorRequestMatcher
instead of setProxyReceptorUrl
.
That is, change this:
Java
Kotlin
casAuthentication.setProxyReceptorUrl("/proxy/receptor");
casAuthentication.setProxyReceptorUrl("/proxy/receptor")
これに:
Java
Kotlin
casAuthentication.setProxyReceptorUrl(PathPatternRequestMatcher.withDefaults().matcher("/proxy/receptor"));
casAuthentication.setProxyReceptorUrl(PathPatternRequestMatcher.withDefaults().matcher("/proxy/receptor"))
Migrate your WebInvocationPrivilegeEvaluator
If you are using Spring Security’s JSP Taglibs or are using WebInvocationPrivilegeEvaluator
directly, be aware of the following changes:
RequestMatcherWebInvocationPrivilegeEvaluator
is deprecated in favor ofAuthorizationManagerWebInvocationPrivilegeEvaluator
HandlerMappingIntrospectorRequestTransformer
is deprecated in favor ofPathPatternRequestTransformer
If you are not constructing these directly, you can opt-in to both changes in advance by publishing a PathPatternRequestTransformer
like so:
Java
Kotlin
XML
@Bean
HttpServletRequestTransformer pathPatternRequestTransformer() {
return new PathPatternRequestTransformer();
}
@Bean
fun pathPatternRequestTransformer(): HttpServletRequestTransformer {
return PathPatternRequestTransformer()
}
<b:bean class="org.springframework.security.web.access.PathPatternRequestTransformer"/>
Spring Security will take this as a signal to use the new implementations.
One difference you may notice is that `AuthorizationManagerWebPrivilegeInvocationEvaluator` allows the authentication to be `null` if the authorization rule is `permitAll`. Test your endpoints that `permitAll` in case JSP requests using this same require should not, in fact, be permitted.
Include the Servlet Path Prefix in Authorization Rules
For many applications 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, 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:
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:
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.
Use RedirectToHttps Instead of Channel Security
Years ago, HTTPS at large was enough of a performance and configuration concern that applications wanted to be able to decide which segments of an application would require HTTPS.
requires-channel
in XML and requiresChannel
in Java Config allowed configurating an application with that in mind:
Java
Kotlin
XML
http
.requiresChannel((channel) -> channel
.requestMatchers("/secure/**").requiresSecureChannel()
.requestMatchers("/insecure/**").requiresInsecureChannel()
)
http {
requiresChannel {
secure("/secure/**")
seccure("/insecure/**", "REQUIRES_INSECURE_CHANNEL")
}
}
<http>
<intercept-url pattern="/secure/**" access="authenticated" requires-channel="REQUIRES_SECURE_CHANNEL"/>
<intercept-url pattern="/insecure/**" access="authenticated" requires-channel="REQUIRES_INSECURE_CHANNEL"/>
</http>
Modern applications should either always require HTTPS. However, there are times, like when developing locally, when one would like the application to use HTTP. Or, you may have continuing circumstances that require part of your application to be HTTP.
In any case, you can migrate to redirect-to-https-request-matcher-ref
and redirectToHttps
by first constructing a RequestMatcher
that contains all circumstances where redirecting to HTTPS is needed. Then you can reference that request matcher like so:
Java
Kotlin
XML
http
.redirectToHttps((https) -> https.requestMatchers("/secure/**"))
// ...
var secure: RequestMatcher = PathPatternRequestMatcher.withDefaults().pattern("/secure/**")
http {
redirectToHttps {
requestMatchers = secure
}
// ...
}
<b:bean id="builder" class="org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher$Builder"/>
<b:bean id="secure" class="org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher" factory-bean="builder" factory-method="matcher">
<b:constructor-arg value="/secure/**"/>
</b:bean>
<http redirect-to-https-request-matcher-ref="secure">
<intercept-url pattern="/secure/**" access="authenticated"/>
<intercept-url pattern="/insecure/**" access="authenticated"/>
<!-- ... -->
</http>
If you have several circumstances where HTTP is needed, consider using |