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
,用於匹配任何請求。