此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.3! |
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.3! |
如果您已经为 Reactive 应用程序执行了初始迁移步骤,那么现在可以执行特定于 Reactive 应用程序的步骤了。
Exploit Protection 迁移
以下步骤与有关如何配置 CSRF 的更改有关。
配置tokenFromMultipartDataEnabled
在 Spring Security 5.8 中,该方法已被弃用,取而代之的是 .tokenFromMultipartDataEnabled
ServerCsrfTokenRequestAttributeHandler#setTokenFromMultipartDataEnabled
要解决弃用问题,请使用以下代码:
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
}
}
}
可以替换为:
tokenFromMultipartDataEnabled
ServerCsrfTokenRequestAttributeHandler
-
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 BREACH
您可以使用以下配置选择加入 Spring Security 6 对 BREACH 保护的默认支持:CsrfToken
CsrfToken
BREACH 保护-
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()
在这种情况下,你可以配置 Spring Security 来验证 cookie 中的原始数据,同时使用带有委托的自定义来保持响应的 CSRF BREACH 保护,如下所示:CsrfToken
ServerCsrfTokenRequestHandler
CsrfToken
-
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
-
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
API 和直接使用 Spring AOP 改进了方法安全性。
如果您在进行这些更改时遇到问题,可以按照本节末尾的选择退出步骤进行操作。
在 Spring Security 5.8 中,已添加到 @EnableReactiveMethodSecurity
中,以允许应用程序选择加入 的功能。useAuthorizationManager
AuthorizationManager
更改为useAuthorizationManager
true
要选择加入,请更改为 LIKE:useAuthorizationManager
true
-
Java
-
Kotlin
@EnableReactiveMethodSecurity
@EnableReactiveMethodSecurity
更改为:
-
Java
-
Kotlin
@EnableReactiveMethodSecurity(useAuthorizationManager = true)
@EnableReactiveMethodSecurity(useAuthorizationManager = true)
传播 sAuthenticationServiceException
AuthenticationFilter
将AuthenticationServiceException
传播到ServerAuthenticationEntryPoint
。
由于 s 表示服务器端错误而不是客户端错误,因此在 6.0 中,这会更改以将它们传播到容器。AuthenticationServiceException
配置为重新抛出ServerAuthenticationFailureHandler
AuthenticationServiceException
要为 6.0 默认值做准备,并且应该配置为 rethrow s。httpBasic
oauth2ResourceServer
AuthenticationServiceException
对于每个 API,为 和 为 构建适当的身份验证入口点 :httpBasic
oauth2ResourceServer
-
Java
-
Kotlin
ServerAuthenticationEntryPoint bearerEntryPoint = new BearerTokenServerAuthenticationEntryPoint();
ServerAuthenticationEntryPoint basicEntryPoint = new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED);
val bearerEntryPoint: ServerAuthenticationEntryPoint = BearerTokenServerAuthenticationEntryPoint()
val basicEntryPoint: ServerAuthenticationEntryPoint = HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)
如果您将 custom 用于其中一个或两个机制,请改用该 custom 来执行其余步骤。 |
然后,为每个 API 构造并配置 a: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
}
}
如果您将 custom 用于其中一个或两个机制,请改用该 custom 来执行其余步骤。 |
添加注释@Configuration
在 6.0 中,已从 和 中删除。@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
为此,无论您在何处使用这些注释之一,都可能需要添加 .
例如,从以下位置更改:@Configuration
@EnableReactiveMethodSecurity
-
Java
@EnableReactiveMethodSecurity
public class MyConfiguration {
// ...
}
-
Kotlin
@EnableReactiveMethodSecurity
open class MyConfiguration {
// ...
}
自:
-
Java
@Configuration
@EnableReactiveMethodSecurity
public class MyConfiguration {
// ...
}
-
Kotlin
@Configuration
@EnableReactiveMethodSecurity
open class MyConfiguration {
// ...
}
解决 OAuth2 客户端弃用问题
ServerOAuth2AuthorizedClientExchangeFilterFunction
该方法可替换为以下之一:setAccessTokenExpiresSkew(…)
-
ClientCredentialsReactiveOAuth2AuthorizedClientProvider#setClockSkew(…)
-
RefreshTokenReactiveOAuth2AuthorizedClientProvider#setClockSkew(…)
-
JwtBearerReactiveOAuth2AuthorizedClientProvider#setClockSkew(…)
该方法可以替换为 constructor 。setClientCredentialsTokenResponseClient(…)
ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)
有关更多信息,请参阅 客户端凭证 。 |
有关更多信息,请参阅 客户端凭证 。 |
添加到注释@Configuration
@Enable*
在 6.0 中,所有 Spring Security 的 Comments 都已删除。
虽然方便,但它与其他 Spring 项目不一致,尤其是 Spring Framework 的注释。
此外,在 Spring Framework 中引入对的支持提供了另一个原因,可以从 Spring Security 的注释中删除元注释,并允许用户选择进入他们喜欢的配置模式。@Enable*
@Configuration
@Enable*
@Configuration(proxyBeanMethods=false)
@Configuration
@Enable*
以下注释已删除:@Configuration
-
@EnableGlobalAuthentication
-
@EnableGlobalMethodSecurity
-
@EnableMethodSecurity
-
@EnableReactiveMethodSecurity
-
@EnableWebSecurity
-
@EnableWebFluxSecurity
例如,如果您使用的是 ,则需要更改:@EnableWebFluxSecurity
-
Java
@EnableWebFluxSecurity
public class SecurityConfig {
// ...
}
自:
-
Java
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
// ...
}
这同样适用于上面列出的所有其他 Comments。