最新の安定バージョンについては、Spring Security 6.3.3 を使用してください!

認証の移行

次の手順は、認証の実行方法に関する変更に関連しています。

自分を記憶 で SHA-256 を使用する

TokenBasedRememberMeServices 実装は、自分を記憶 トークンの SHA-256 をサポートするようになりました。これが Spring Security 6 のデフォルトです。MD5 は弱いハッシュアルゴリズムであり、衝突攻撃やモジュラー差分攻撃に対して脆弱であることがすでに証明されているため、この変更によりデフォルトで実装がより安全になります。

新しく生成されたトークンには、トークンの生成に使用されたアルゴリズムの情報が含まれており、その情報はそれを照合するために使用されます。アルゴリズム名が存在しない場合は、matchingAlgorithm プロパティを使用してトークンをチェックします。これにより、MD5 から SHA-256 へのスムーズな移行が可能になります。

MD5 でエンコードされたトークンをデコードしながらトークンをエンコードする新しい Spring Security 6 デフォルトを選択するには、encodingAlgorithm プロパティを SHA-256 に設定し、matchingAlgorithm プロパティを MD5 に設定します。詳細については、リファレンスドキュメントAPI ドキュメントを参照してください。

エンコーディングには Spring Security 6 デフォルトを使用し、エンコーディングには SHA-256 を使用し、照合には MD5 を使用します。
  • Java

  • XML

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http, RememberMeServices rememberMeServices) throws Exception {
        http
                // ...
                .rememberMe((remember) -> remember
                    .rememberMeServices(rememberMeServices)
                );
        return http.build();
    }

    @Bean
    RememberMeServices rememberMeServices(UserDetailsService userDetailsService) {
        RememberMeTokenAlgorithm encodingAlgorithm = RememberMeTokenAlgorithm.SHA256;
        TokenBasedRememberMeServices rememberMe = new TokenBasedRememberMeServices(myKey, userDetailsService, encodingAlgorithm);
        rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.MD5);
        return rememberMe;
    }

}
<http>
  <remember-me services-ref="rememberMeServices"/>
</http>

<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
    <property name="userDetailsService" ref="myUserDetailsService"/>
    <property name="key" value="springRocks"/>
    <property name="matchingAlgorithm" value="MD5"/>
    <property name="encodingAlgorithm" value="SHA256"/>
</bean>

ある時点で、Spring Security 6 のデフォルトに完全に移行したくなるでしょう。しかし、そうしても安全な時期をどうやって知るのでしょうか ? 11 月 1 日にエンコードアルゴリズムとして SHA-256 を使用して (ここで行ったように) アプリケーションをデプロイしたとします。tokenValiditySeconds プロパティの値を N 日 (デフォルトは 14) に設定すると、SHA-256 11 月 1 日から N 日後 (この例では 11 月 15 日)。その時までに、MD5 で生成されたすべてのトークンは期限切れになります。

エンコーディングとマッチングの両方に Spring Security 6 のデフォルトである SHA-256 を使用する
  • Java

  • XML

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http, RememberMeServices rememberMeServices) throws Exception {
        http
                // ...
                .rememberMe((remember) -> remember
                    .rememberMeServices(rememberMeServices)
                );
        return http.build();
    }

    @Bean
    RememberMeServices rememberMeServices(UserDetailsService userDetailsService) {
        RememberMeTokenAlgorithm encodingAlgorithm = RememberMeTokenAlgorithm.SHA256;
        TokenBasedRememberMeServices rememberMe = new TokenBasedRememberMeServices(myKey, userDetailsService, encodingAlgorithm);
        rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.SHA256);
        return rememberMe;
    }

}
<http>
  <remember-me services-ref="rememberMeServices"/>
</http>

<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
    <property name="userDetailsService" ref="myUserDetailsService"/>
    <property name="key" value="springRocks"/>
    <property name="matchingAlgorithm" value="SHA256"/>
    <property name="encodingAlgorithm" value="SHA256"/>
</bean>

Spring Security 6 のデフォルトに問題がある場合は、次の構成を使用して明示的に 5.8 のデフォルトを選択できます。

エンコーディングアルゴリズムとマッチングアルゴリズムの両方に MD5 を使用する
  • Java

  • XML

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http, RememberMeServices rememberMeServices) throws Exception {
        http
                // ...
                .rememberMe((remember) -> remember
                    .rememberMeServices(rememberMeServices)
                );
        return http.build();
    }

    @Bean
    RememberMeServices rememberMeServices(UserDetailsService userDetailsService) {
        RememberMeTokenAlgorithm encodingAlgorithm = RememberMeTokenAlgorithm.MD5;
        TokenBasedRememberMeServices rememberMe = new TokenBasedRememberMeServices(myKey, userDetailsService, encodingAlgorithm);
        rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.MD5);
        return rememberMe;
    }

}
<http>
  <remember-me services-ref="rememberMeServices"/>
</http>

<bean id="rememberMeServices" class=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
    <property name="userDetailsService" ref="myUserDetailsService"/>
    <property name="key" value="springRocks"/>
    <property name="matchingAlgorithm" value="MD5"/>
    <property name="encodingAlgorithm" value="MD5"/>
</bean>

AuthenticationServiceException の伝搬

AuthenticationFilter (Javadoc) AuthenticationServiceException (Javadoc) AuthenticationEntryPoint (Javadoc) に伝搬します。AuthenticationServiceException はクライアント側のエラーではなくサーバー側のエラーを表すため、6.0 では、これを変更してコンテナーに伝達します。

AuthenticationServiceException を再スローするように AuthenticationFailureHandler を構成する

6.0 デフォルトの準備をするには、次のように AuthenticationServiceException を再スローする AuthenticationFailureHandler で AuthenticationFilter インスタンスを接続します。

  • Java

  • Kotlin

  • XML

AuthenticationFilter authenticationFilter = new AuthenticationFilter(...);
AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(...);
handler.setRethrowAuthenticationServiceException(true);
authenticationFilter.setAuthenticationFailureHandler(handler);
val authenticationFilter: AuthenticationFilter = new AuthenticationFilter(...)
val handler: AuthenticationEntryPointFailureHandler = new AuthenticationEntryPointFailureHandler(...)
handler.setRethrowAuthenticationServiceException(true)
authenticationFilter.setAuthenticationFailureHandler(handler)
<bean id="authenticationFilter" class="org.springframework.security.web.authentication.AuthenticationFilter">
    <!-- ... -->
    <property ref="authenticationFailureHandler"/>
</bean>

<bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler">
    <property name="rethrowAuthenticationServiceException" value="true"/>
</bean>

オプトアウトの手順

AuthenticationServiceException を再度スローすると問題が発生する場合は、次のように、6.0 のデフォルトを使用する代わりに、値を false に設定できます。

  • Java

  • Kotlin

  • XML

AuthenticationFilter authenticationFilter = new AuthenticationFilter(...);
AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler(...);
handler.setRethrowAuthenticationServiceException(false);
authenticationFilter.setAuthenticationFailureHandler(handler);
val authenticationFilter: AuthenticationFilter = new AuthenticationFilter(...)
val handler: AuthenticationEntryPointFailureHandler = new AuthenticationEntryPointFailureHandler(...)
handler.setRethrowAuthenticationServiceException(false)
authenticationFilter.setAuthenticationFailureHandler(handler)
<bean id="authenticationFilter" class="org.springframework.security.web.authentication.AuthenticationFilter">
    <!-- ... -->
    <property ref="authenticationFailureHandler"/>
</bean>

<bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler">
    <property name="rethrowAuthenticationServiceException" value="false"/>
</bean>