WebFlux Security
Spring Security 的 WebFlux 支持依赖于 WebFilter
,并且对于 Spring WebFlux 和 Spring WebFlux.Fn 来说工作原理相同。几个示例应用程序演示了该代码:
-
Hello WebFlux hellowebflux
-
Hello WebFlux.Fn hellowebfluxfn
-
Hello WebFlux Method hellowebflux-method
Minimal WebFlux Security Configuration
下面的清单展示了最小的 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 保护,等等。
Explicit WebFlux Security Configuration
以下页面展示了最小 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 |
该配置显式地设置的所有内容与我们的最小配置相同。从这里,您可以更容易地对默认值进行更改。
您可以在单元测试中找到更多显式配置示例,方法是在 config/src/test/
目录中搜索 link:https://github.com/spring-projects/spring-security/search?q=path%3Aconfig%2Fsrc%2Ftest%2F+EnableWebFluxSecurity[EnableWebFluxSecurity
。
Multiple Chains Support
您可以配置多个 SecurityWebFilterChain
实例以按 RequestMatcher
实例对配置进行分离。
例如,您可以为以 /api
开头的 URL 隔离配置:
-
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 | 使用 @Order`配置 `SecurityWebFilterChain ,以指定要由 Spring Security 首先生成的 SecurityWebFilterChain |
2 | 使用 `PathPatternParserServerWebExchangeMatcher`来指定此 `SecurityWebFilterChain`仅适用于以 `/api/`开头的 URL 路径 |
3 | 指定要用于 `/api/**`端的身份验证机制 |
4 | 创建另一个优先级较低的 `SecurityWebFilterChain`实例,以匹配所有其他 URL |
5 | 指定要用于其余应用程序的身份验证机制 |
Spring Security 为每个请求选择一个 SecurityWebFilterChain
@Bean
。它按 securityMatcher
定义的顺序匹配请求。
在这种情况下,这意味着如果 URL 路径以 /api
开头,则 Spring Security 将使用 apiHttpSecurity
。如果 URL 没有以 /api
开头,则 Spring Security 将默认为 webHttpSecurity
,其中有一个隐含的 securityMatcher
,它匹配任何请求。