WebFlux Security
Spring Security 的 WebFlux 支持依赖于一个 WebFilter
,并且对于 Spring WebFlux 和 Spring WebFlux.Fn 的工作方式相同。一些示例应用展示了相关代码
-
Hello WebFlux hellowebflux
-
Hello WebFlux.Fn hellowebfluxfn
-
Hello WebFlux Method hellowebflux-method
最简 WebFlux 安全配置
以下清单显示了一个最简 WebFlux 安全配置
-
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 Basic 身份验证,设置了授权以要求经身份验证的用户访问任何页面,设置了默认登录页和默认注销页,设置了安全相关的 HTTP 头,添加了 CSRF 防护等等。
显式 WebFlux 安全配置
以下页面显示了最简 WebFlux 安全配置的显式版本
-
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 { }
}
}
}
请确保导入 org.springframework.security.config.web.server.invoke 函数以在你的类中启用 Kotlin DSL,因为 IDE 不总是会自动导入该方法,这可能会导致编译问题。 |
此配置显式设置了所有与最简配置相同的内容。从这里,你可以更容易地修改默认设置。
你可以在单元测试中找到更多显式配置的示例,方法是在 config/src/test/
目录下搜索 EnableWebFluxSecurity
。
多链支持
你可以配置多个 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
,用于匹配任何请求。