对于最新的稳定版本,请使用 Spring Security 6.4.3! |
WebFlux 安全性
Spring Security 的 WebFlux 支持依赖于WebFilter
并且对 Spring WebFlux 和 Spring WebFlux.Fn 的工作方式相同。
一些示例应用程序演示了代码:
-
你好 WebFlux.Fn hellowebfluxfn
-
Hello WebFlux 方法 hellowebflux-method
最小 WebFlux 安全配置
下面的清单显示了一个最小的 WebFlux Security 配置:
-
Java
-
Kotlin
@Configuration
@EnableWebFluxSecurity
public class HelloWebfluxSecurityConfig {
@Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("user")
.roles("USER")
.build();
return new MapReactiveUserDetailsService(user);
}
}
@Configuration
@EnableWebFluxSecurity
class HelloWebfluxSecurityConfig {
@Bean
fun userDetailsService(): ReactiveUserDetailsService {
val userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("user")
.roles("USER")
.build()
return MapReactiveUserDetailsService(userDetails)
}
}
此配置提供表单和 HTTP 基本身份验证,设置授权以要求经过身份验证的用户访问任何页面,设置默认登录页面和默认注销页面,设置与安全相关的 HTTP 标头,添加 CSRF 保护等等。
显式 WebFlux 安全配置
以下页面显示了最小 WebFlux Security 配置的显式版本:
-
Java
-
Kotlin
@Configuration
@EnableWebFluxSecurity
public class HelloWebfluxSecurityConfig {
@Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("user")
.roles("USER")
.build();
return new MapReactiveUserDetailsService(user);
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange(exchanges -> exchanges
.anyExchange().authenticated()
)
.httpBasic(withDefaults())
.formLogin(withDefaults());
return http.build();
}
}
import org.springframework.security.config.web.server.invoke
@Configuration
@EnableWebFluxSecurity
class HelloWebfluxSecurityConfig {
@Bean
fun userDetailsService(): ReactiveUserDetailsService {
val userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("user")
.roles("USER")
.build()
return MapReactiveUserDetailsService(userDetails)
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
authorizeExchange {
authorize(anyExchange, authenticated)
}
formLogin { }
httpBasic { }
}
}
}
Make sure that you import the invoke
function in your Kotlin class, sometimes the IDE will not auto-import it causing compilation issues.
This configuration explicitly sets up all the same things as our minimal configuration.
From here, you can more easily make changes to the defaults.
You can find more examples of explicit configuration in unit tests, by searching for EnableWebFluxSecurity
in the config/src/test/
directory.
Multiple Chains Support
You can configure multiple SecurityWebFilterChain
instances to separate configuration by RequestMatcher
instances.
For example, you can isolate configuration for URLs that start with /api
:
-
Java
-
Kotlin
@Configuration
@EnableWebFluxSecurity
static class MultiSecurityHttpConfig {
@Order(Ordered.HIGHEST_PRECEDENCE) (1)
@Bean
SecurityWebFilterChain apiHttpSecurity(ServerHttpSecurity http) {
http
.securityMatcher(new PathPatternParserServerWebExchangeMatcher("/api/**")) (2)
.authorizeExchange((exchanges) -> exchanges
.anyExchange().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerSpec::jwt); (3)
return http.build();
}
@Bean
SecurityWebFilterChain webHttpSecurity(ServerHttpSecurity http) { (4)
http
.authorizeExchange((exchanges) -> exchanges
.anyExchange().authenticated()
)
.httpBasic(withDefaults()); (5)
return http.build();
}
@Bean
ReactiveUserDetailsService userDetailsService() {
return new MapReactiveUserDetailsService(
PasswordEncodedUser.user(), PasswordEncodedUser.admin());
}
}
import org.springframework.security.config.web.server.invoke
@Configuration
@EnableWebFluxSecurity
open class MultiSecurityHttpConfig {
@Order(Ordered.HIGHEST_PRECEDENCE) (1)
@Bean
open fun apiHttpSecurity(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
securityMatcher(PathPatternParserServerWebExchangeMatcher("/api/**")) (2)
authorizeExchange {
authorize(anyExchange, authenticated)
}
oauth2ResourceServer {
jwt { } (3)
}
}
}
@Bean
open fun webHttpSecurity(http: ServerHttpSecurity): SecurityWebFilterChain { (4)
return http {
authorizeExchange {
authorize(anyExchange, authenticated)
}
httpBasic { } (5)
}
}
@Bean
open fun userDetailsService(): ReactiveUserDetailsService {
return MapReactiveUserDetailsService(
PasswordEncodedUser.user(), PasswordEncodedUser.admin()
)
}
}
1
Configure a SecurityWebFilterChain
with an @Order
to specify which SecurityWebFilterChain
Spring Security should consider first
2
Use PathPatternParserServerWebExchangeMatcher
to state that this SecurityWebFilterChain
will only apply to URL paths that start with /api/
3
Specify the authentication mechanisms that will be used for /api/**
endpoints
4
Create another instance of SecurityWebFilterChain
with lower precedence to match all other URLs
5
Specify the authentication mechanisms that will be used for the rest of the application
Spring Security selects one SecurityWebFilterChain
@Bean
for each request.
It matches the requests in order by the securityMatcher
definition.
In this case, that means that, if the URL path starts with /api
, Spring Security uses apiHttpSecurity
.
If the URL does not start with /api
, Spring Security defaults to webHttpSecurity
, which has an implied securityMatcher
that matches any request.