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

リアクティブ移行

リアクティブアプリケーションの最初の移行手順をすでに実行している場合は、リアクティブアプリケーションに固有の手順を実行する準備ができています。

Exploit Protection の移行

次の手順は、CSRF の設定方法に関する変更に関連しています。

tokenFromMultipartDataEnabled を構成する

Spring Security 5.8 では、メソッド tokenFromMultipartDataEnabled が廃止され、ServerCsrfTokenRequestAttributeHandler#setTokenFromMultipartDataEnabled が推奨されました。

非推奨に対処するには、次のコードを使用します。

DSL を使用して tokenFromMultipartDataEnabled を構成する
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.csrf((csrf) -> csrf
			.tokenFromMultipartDataEnabled(true)
		);
	return http.build();
}
@Bean
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
	return http {
		// ...
		csrf {
			tokenFromMultipartDataEnabled = true
		}
	}
}

次のように置き換えることができます:

ServerCsrfTokenRequestAttributeHandler を使用して tokenFromMultipartDataEnabled を構成する
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
	ServerCsrfTokenRequestAttributeHandler requestHandler = new ServerCsrfTokenRequestAttributeHandler();
	requestHandler.setTokenFromMultipartDataEnabled(true);
	http
		// ...
		.csrf((csrf) -> csrf
			.csrfTokenRequestHandler(requestHandler)
		);
	return http.build();
}
@Bean
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
	val requestHandler = ServerCsrfTokenRequestAttributeHandler()
	requestHandler.tokenFromMultipartDataEnabled = true
	return http {
		// ...
		csrf {
			csrfTokenRequestHandler = requestHandler
		}
	}
}

CSRF 違反からの保護

次の構成を使用して、CsrfToken の BREACH 保護に対する Spring Security 6 のデフォルトサポートを選択できます。

CsrfToken 違反保護
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
	XorServerCsrfTokenRequestAttributeHandler requestHandler = new XorServerCsrfTokenRequestAttributeHandler();
	// ...
	http
		// ...
		.csrf((csrf) -> csrf
			.csrfTokenRequestHandler(requestHandler)
		);
	return http.build();
}
@Bean
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
	val requestHandler = XorServerCsrfTokenRequestAttributeHandler()
	// ...
	return http {
		// ...
		csrf {
			csrfTokenRequestHandler = requestHandler
		}
	}
}

オプトアウトの手順

CSRF BREACH 保護を構成すると問題が発生する場合は、次のシナリオを参照して、最適なオプトアウト動作を確認してください。

AngularJS または別の Javascript フレームワークを使用しています

AngularJS と HttpClientXsrfModule (英語) (または別のフレームワークの同様のモジュール) を CookieServerCsrfTokenRepository.withHttpOnlyFalse() と共に使用している場合、自動サポートが機能しなくなることがあります。

この場合、次のように、委譲のあるカスタム ServerCsrfTokenRequestHandler を使用して、レスポンスの CSRF BREACH 保護を維持しながら、Cookie から生の CsrfToken を検証するように Spring Security を構成できます。

生のトークンを検証するために CsrfToken BREACH Protection を構成する
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
	CookieServerCsrfTokenRepository tokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse();
	XorServerCsrfTokenRequestAttributeHandler delegate = new XorServerCsrfTokenRequestAttributeHandler();
	// Use only the handle() method of XorServerCsrfTokenRequestAttributeHandler and the
	// default implementation of resolveCsrfTokenValue() from ServerCsrfTokenRequestHandler
	ServerCsrfTokenRequestHandler requestHandler = delegate::handle;
	http
		// ...
		.csrf((csrf) -> csrf
			.csrfTokenRepository(tokenRepository)
			.csrfTokenRequestHandler(requestHandler)
		);

	return http.build();
}

@Bean
WebFilter csrfCookieWebFilter() {
	return (exchange, chain) -> {
		Mono<CsrfToken> csrfToken = exchange.getAttributeOrDefault(CsrfToken.class.getName(), Mono.empty());
		return csrfToken.doOnSuccess(token -> {
			/* Ensures the token is subscribed to. */
		}).then(chain.filter(exchange));
	};
}
@Bean
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
	val tokenRepository = CookieServerCsrfTokenRepository.withHttpOnlyFalse()
	val delegate = XorServerCsrfTokenRequestAttributeHandler()
	// Use only the handle() method of XorServerCsrfTokenRequestAttributeHandler and the
	// default implementation of resolveCsrfTokenValue() from ServerCsrfTokenRequestHandler
	val requestHandler = ServerCsrfTokenRequestHandler(delegate::handle)
	return http.invoke {
		// ...
		csrf {
			csrfTokenRepository = tokenRepository
			csrfTokenRequestHandler = requestHandler
		}
	}
}

@Bean
fun csrfCookieWebFilter(): WebFilter {
	return WebFilter { exchange, chain ->
		val csrfToken = exchange.getAttribute<Mono<CsrfToken>>(CsrfToken::class.java.name) ?: Mono.empty()
		csrfToken.doOnSuccess {
            /* Ensures the token is subscribed to. */
		}.then(chain.filter(exchange))
	}
}

別の理由で CSRF BREACH 保護をオプトアウトする必要があります

CSRF BREACH 保護が別の理由で機能しない場合は、次の構成を使用してオプトアウトできます。

CsrfToken BREACH 保護をオプトアウトする
  • Java

  • Kotlin

@Bean
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
	ServerCsrfTokenRequestAttributeHandler requestHandler = new ServerCsrfTokenRequestAttributeHandler();
	http
		// ...
		.csrf((csrf) -> csrf
			.csrfTokenRequestHandler(requestHandler)
		);
	return http.build();
}
@Bean
open fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
	val requestHandler = ServerCsrfTokenRequestAttributeHandler()
	return http {
		// ...
		csrf {
			csrfTokenRequestHandler = requestHandler
		}
	}
}

メソッドセキュリティに AuthorizationManager を使用する

メソッドのセキュリティは、AuthorizationManager APISpring AOP の直接使用によって改善されました。

これらの変更を行う際に問題が発生した場合は、このセクションの最後にあるオプトアウトの手順に従ってください。

Spring Security 5.8 では、useAuthorizationManager が @EnableReactiveMethodSecurity (Javadoc) に追加され、アプリケーションが AuthorizationManager の機能にオプトインできるようになりました。

useAuthorizationManager を true に変更

オプトインするには、次のように useAuthorizationManager を true に変更します。

  • Java

  • Kotlin

@EnableReactiveMethodSecurity
@EnableReactiveMethodSecurity

変更:

  • Java

  • Kotlin

@EnableReactiveMethodSecurity(useAuthorizationManager = true)
@EnableReactiveMethodSecurity(useAuthorizationManager = true)

AnnotationConfigurationException のチェック

useAuthorizationManager は、Spring Security の繰り返し不可または互換性のないアノテーションのより厳格な適用を有効にします。useAuthorizationManager を有効にした後、ログに AnnotationConfigurationException が表示される場合は、例外メッセージの指示に従って、アプリケーションのメソッドセキュリティアノテーションの使用をクリーンアップしてください。

オプトアウトの手順

リアクティブメソッドセキュリティの AuthorizationManager で問題が発生した場合は、次のように変更してオプトアウトできます。

  • Java

  • Kotlin

@EnableReactiveMethodSecurity
@EnableReactiveMethodSecurity

to:

  • Java

  • Kotlin

@EnableReactiveMethodSecurity(useAuthorizationManager = false)
@EnableReactiveMethodSecurity(useAuthorizationManager = false)

AuthenticationServiceException の伝搬

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

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

6.0 のデフォルトに備えるには、AuthenticationServiceException を再スローするように httpBasic と oauth2ResourceServer を構成する必要があります。

それぞれについて、httpBasic および oauth2ResourceServer の適切な認証エントリポイントを作成します。

  • Java

  • Kotlin

ServerAuthenticationEntryPoint bearerEntryPoint = new BearerTokenServerAuthenticationEntryPoint();
ServerAuthenticationEntryPoint basicEntryPoint = new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED);
val bearerEntryPoint: ServerAuthenticationEntryPoint = BearerTokenServerAuthenticationEntryPoint()
val basicEntryPoint: ServerAuthenticationEntryPoint = HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)

いずれかまたは両方のメカニズムにカスタム AuthenticationEntryPoint を使用する場合は、残りの手順で代わりにその AuthenticationEntryPoint を使用します。

次に、それぞれの ServerAuthenticationEntryPointFailureHandler を構築して構成します。

  • Java

  • Kotlin

AuthenticationFailureHandler bearerFailureHandler = new ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint);
bearerFailureHandler.setRethrowAuthenticationServiceException(true);
AuthenticationFailureHandler basicFailureHandler = new ServerAuthenticationEntryPointFailureHandler(basicEntryPoint);
basicFailureHandler.setRethrowAuthenticationServiceException(true)
val bearerFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint)
bearerFailureHandler.setRethrowAuthenticationServiceException(true)
val basicFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(basicEntryPoint)
basicFailureHandler.setRethrowAuthenticationServiceException(true)

最後に、次のように、各認証失敗ハンドラーを DSL に接続します。

  • Java

  • Kotlin

http
    .httpBasic((basic) -> basic.authenticationFailureHandler(basicFailureHandler))
    .oauth2ResourceServer((oauth2) -> oauth2.authenticationFailureHandler(bearerFailureHandler))
http {
    httpBasic {
        authenticationFailureHandler = basicFailureHandler
    }
    oauth2ResourceServer {
        authenticationFailureHandler = bearerFailureHandler
    }
}

オプトアウトの手順

6.0 のデフォルトをオプトアウトし、代わりに AuthenticationServiceException を ServerAuthenticationEntryPoint に渡し続けるには、rethrowAuthenticationServiceException を false に設定する以外は上記と同じ手順に従います。

@Configuration アノテーションを追加

6.0 では、@Configuration が @EnableWebFluxSecurity および @EnableReactiveMethodSecurity から削除されています。

これに備えるために、これらのアノテーションのいずれかを使用している場合は、@Configuration を追加する必要がある場合があります。例: @EnableReactiveMethodSecurity の変更:

  • Java

@EnableReactiveMethodSecurity
public class MyConfiguration {
	// ...
}
  • Kotlin

@EnableReactiveMethodSecurity
open class MyConfiguration {
	// ...
}

to:

  • Java

@Configuration
@EnableReactiveMethodSecurity
public class MyConfiguration {
	// ...
}
  • Kotlin

@Configuration
@EnableReactiveMethodSecurity
open class MyConfiguration {
	// ...
}

OAuth2 クライアントの非推奨への対応

ServerOAuth2AuthorizedClientExchangeFilterFunction

メソッド setAccessTokenExpiresSkew(…​) は、次のいずれかに置き換えることができます。

  • ClientCredentialsReactiveOAuth2AuthorizedClientProvider#setClockSkew(…​)

  • RefreshTokenReactiveOAuth2AuthorizedClientProvider#setClockSkew(…​)

  • JwtBearerReactiveOAuth2AuthorizedClientProvider#setClockSkew(…​)

メソッド setClientCredentialsTokenResponseClient(…​) は、コンストラクター ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager) に置き換えることができます。

詳細については、クライアント資格情報を参照してください。

WebSessionOAuth2ServerAuthorizationRequestRepository

メソッド setAllowMultipleAuthorizationRequests(…​) を直接置き換えるものはありません。

UnAuthenticatedServerOAuth2AuthorizedClientRepository

クラス UnAuthenticatedServerOAuth2AuthorizedClientRepository には直接の代替はありません。クラスの使用箇所は AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager に置き換えることができます。

@Configuration から @Enable* へのアノテーションの追加

6.0 では、すべての Spring Security の @Enable* アノテーションから @Configuration が削除されました。便利ではあるものの、残りの Spring プロジェクト、特に Spring Framework の @Enable* アノテーションとは一貫性がありませんでした。さらに、Spring Framework での @Configuration(proxyBeanMethods=false) のサポートの導入により、Spring Security の @Enable* アノテーションから @Configuration メタアノテーションを削除し、ユーザーが推奨する構成モードを選択できるようにする別の理由が提供されます。

次のアノテーションでは、@Configuration が削除されました。

  • @EnableGlobalAuthentication

  • @EnableGlobalMethodSecurity

  • @EnableMethodSecurity

  • @EnableReactiveMethodSecurity

  • @EnableWebSecurity

  • @EnableWebFluxSecurity

例: @EnableWebFluxSecurity を使用している場合は、次のように変更する必要があります。

  • Java

@EnableWebFluxSecurity
public class SecurityConfig {
	// ...
}

to:

  • Java

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
	// ...
}

上記の他のすべてのアノテーションにも同じことが当てはまります。