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 を使用する
Spring Security 7 では、AntPathRequestMatcher
と MvcRequestMatcher
はサポートされなくなり、Java DSL ではすべての URI が絶対 URI(コンテキストルートを除く)であることが必須となります。その時点で、Spring Security 7 はデフォルトで PathPatternRequestMatcher
を使用するようになります。
この変更に対する準備状況を確認するには、次の 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"/>
これにより、Spring Security DSL は、構築するすべてのリクエストマッチャーに PathPatternRequestMatcher
を使用するように指示されます。
setRequestMatcher
メソッドを持つオブジェクトを直接構築する場合 (DSL で構築するのではなく)、そこでも積極的に PathPatternRequestMatcher
を指定する必要があります。
exitUserUrl
および switchUserUrl
リクエストマッチャーを SwitchUserFilter
に移行します
SwitchUserFilter
は、setExitUserUrl
および setSwitchUserUrl
メソッドで AntPathRequestMatcher
を構築します。これは、Spring Security 7 では PathPatternRequestMatcher
を使用するように変更されます。
この変更に備えて、setExitUserMatcher
と setSwithcUserMatcher
を呼び出して、事前にこの PathPatternRequestMatcher
を用意してください。つまり、以下の変更を行います。
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"))
AbstractAuthenticationProcessingFilter
実装における filterProcessingUrl
リクエストマッチャーの移行
Spring Security 6 は、setFilterProcessingUrl
で設定された処理エンドポイントを AntPathRequestMatcher
に変換します。Spring Security 7 では、これは PathPatternRequestMatcher
に変更されます。
UsernamePasswordAuthenticationFilter
、OAuth2LoginAuthenticationFilter
、Saml2WebSsoAuthenticationFilter
、OneTimeTokenAuthenticationFilter
や WebAuthnAuthenticationFilter
など、AbstractAuthenticationProcessingFilter
を継承するフィルターで setFilterProcessingUrl
を直接呼び出す場合は、代わりに setRequiredAuthenticationRequestMatcher
を呼び出して、この PathPatternRequestMatcher
を事前に用意してください。
つまり、これを変更してください:
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.
CAS プロキシレセプターリクエストマッチャーの移行
Spring Security 6 は、設定された proxyReceptorUrl
を、リクエストの末尾に一致するリクエストマッチャー(つまり /**/proxy/receptor
)に変換します。Spring Security 7 ではこのパターンは許可されておらず、PathPatternRequestMatcher
を使用するように変更されます。また、Spring Security 7m では、URL はコンテキストパスを含まない絶対パスでなければなりません(例: /proxy/receptor
)。
これらの変更に備えるために、setProxyReceptorUrl
の代わりに setProxyReceptorRequestMatcher
を使用できます。
つまり、これを変更してください:
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"))
WebInvocationPrivilegeEvaluator の移行
Spring Security の JSP タグライブラリを使用している場合、または WebInvocationPrivilegeEvaluator
を直接使用している場合は、次の変更に注意してください。
RequestMatcherWebInvocationPrivilegeEvaluator
はAuthorizationManagerWebInvocationPrivilegeEvaluator
に置き換えられて非推奨になりましたHandlerMappingIntrospectorRequestTransformer
はPathPatternRequestTransformer
に置き換えられて非推奨になりました
これらを直接構築していない場合は、次のように PathPatternRequestTransformer
を公開することで、両方の変更を事前にオプトインできます。
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 はこれを新しい実装を使用する合図とみなします。
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.
認可ルールにサーブレットパスプレフィックスを含める
多くのアプリケーションでは、リストされている URI のほとんどすべてがデフォルトのサーブレットによって一致するため、上記は違いを生じません。
ただし、サーブレットパスプレフィックスを持つ他のサーブレットがある場合は、これらのパスを個別に指定する必要があります。
例: Spring MVC コントローラーと @RequestMapping("/orders")
があり、MVC アプリケーションが(デフォルトのサーブレットではなく) /mvc
にデプロイされている場合、このエンドポイントの URI は /mvc/orders
になります。これまで、Java DSL にはサーブレットのパスプレフィックスを指定する簡単な方法がなく、Spring Security はそれを推測しようとしていました。
時間の経過とともに、これらの推論が開発者を驚かせることが分かりました。開発者からこの責任を取り除く代わりに、次のようにサーブレットパスのプレフィックスを指定する方が簡単になりました。
PathPatternRequestParser.Builder servlet = PathPatternRequestParser.withDefaults().basePath("/mvc"); http .authorizeHttpRequests((authorize) -> authorize .requestMatchers(servlet.pattern("/orders/**").matcher()).authenticated() )
デフォルトのサーブレットに属するパスの場合は、代わりに PathPatternRequestParser.withDefaults()
を使用します。
PathPatternRequestParser.Builder request = PathPatternRequestParser.withDefaults(); http .authorizeHttpRequests((authorize) -> authorize .requestMatchers(request.pattern("/js/**").matcher()).authenticated() )
すべてのサーブレットがパスプレフィックスを持っているわけではないため、これはすべての種類のサーブレットに当てはまるわけではないことに注意してください。例: JSP サーブレットに一致する式では、ant パターン /*/.jsp
が使用される場合があります。
これらに代わる汎用的なものはまだないため、regexMatcher("\\.jsp$")
のように RegexRequestMatcher
を使用することをお勧めします。
多くのアプリケーションでは、リストされている URI のほとんどすべてがデフォルトのサーブレットに一致するため、これは問題になりません。
チャネルセキュリティの代わりに RedirectToHttps を使用する
数年前、HTTPS はパフォーマンスと構成に関して大きな関心事であったため、アプリケーションのどのセグメントに HTTPS が必要かをアプリケーション側で決定する必要がありました。
XML の requires-channel
と Java 構成 の requiresChannel
を使用すると、それを念頭に置いてアプリケーションを構成できます。
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>
現代のアプリケーションは、常に HTTPS を使用するべきです。しかし、ローカル開発など、アプリケーションで HTTP を使用したい場合もあります。あるいは、アプリケーションの一部を HTTP で動作させなければならない状況が継続的に発生する場合もあります。
いずれにせよ、HTTPS へのリダイレクトが必要なすべての状況を含む RequestMatcher
をまず構築することで、redirect-to-https-request-matcher-ref
および redirectToHttps
に移行できます。その後、次のようにしてそのリクエストマッチャーを参照できます。
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>
HTTP が必要な状況が複数ある場合は、 |
個別の setter の代わりに setCookieCustomizer
を使用する
よりシンプルな API を優先して、CookieCsrfTokenRepository#setCookieCustomizer
を使用すると、setCookieHttpOnly
、setCookieMaxAge
、setSecure
、setCookieDomain
を置き換えて Cookie のあらゆる側面を変更できます。
これを変更します:
Java
Kotlin
CookeCsrfTokenRepository csrf = CookeCsrfTokenRepository.withHttpOnlyFalse();
csrf.setCookieMaxAge(86400)
val csrf = CookeCsrfTokenRepository.withHttpOnlyFalse()
csrf.setCookieMaxAge(86400)
これに:
Java
Kotlin
CookeCsrfTokenRepository csrf = CookeCsrfTokenRepository.withHttpOnlyFalse();
csrf.setCookieCustomizer((c) -> c.maxAge(86400));
val csrf = CookeCsrfTokenRepository.withHttpOnlyFalse()
csrf.setCookieCustomizer { -> it.maxAge(86400) }