授权 ServerHttpRequest
Spring Security 提供了对传入HTTP请求进行授权的支持。默认情况下,Spring Security 的授权机制要求对所有请求进行身份验证。其显式配置如下所示:
- Java
- Kotlin
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange((authorize) -> authorize
.anyExchange().authenticated()
)
.httpBasic(withDefaults())
.formLogin(withDefaults());
return http.build();
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
authorizeExchange {
authorize(anyExchange, authenticated)
}
formLogin { }
httpBasic { }
}
}
我们可以通过按优先级顺序添加更多规则来配置Spring Security,使其拥有不同的规则。
- Java
- Kotlin
import static org.springframework.security.authorization.AuthorityReactiveAuthorizationManager.hasRole;
// ...
@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
http
// ...
.authorizeExchange((authorize) -> authorize 1
.pathMatchers("/resources/**", "/signup", "/about").permitAll() 2
.pathMatchers("/admin/**").hasRole("ADMIN") 3
.pathMatchers("/db/**").access((authentication, context) -> 4
hasRole("ADMIN").check(authentication, context)
.filter(decision -> !decision.isGranted())
.switchIfEmpty(hasRole("DBA").check(authentication, context))
)
.anyExchange().denyAll() 5
);
return http.build();
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
authorizeExchange { 1
authorize(pathMatchers("/resources/**", "/signup", "/about"), permitAll) // <2>
authorize("/admin/**", hasRole("ADMIN")) // <3>
authorize("/db/**", { authentication, context -> // <4>
hasRole("ADMIN").check(authentication, context)
.filter({ decision -> !decision.isGranted() })
.switchIfEmpty(hasRole("DBA").check(authentication, context))
})
authorize(anyExchange, denyAll) // <5>
}
// ...
}
}
指定了多个授权规则。每个规则将按照声明的顺序依次被考虑。
我们指定了多个任何用户都可以访问的 URL 模式。具体来说,如果 URL 以 "/resources/" 开头、等于 "/signup" 或等于 "/about",则任何用户都可以访问该请求。
任何以 "/admin/" 开头的 URL 将被限制为拥有 "ROLE_ADMIN" 权限的用户才能访问。您会注意到,由于我们调用了
hasRole方法,因此无需指定 "ROLE_" 前缀。任何以 "/db/" 开头的 URL 要求用户同时拥有 "ROLE_ADMIN" 和 "ROLE_DBA" 权限。这展示了提供自定义
ReactiveAuthorizationManager的灵活性,允许我们实现任意的授权逻辑。为简化起见,示例使用了 lambda 表达式并委托给现有的AuthorityReactiveAuthorizationManager.hasRole实现。然而,在实际应用中,可能会在一个实现了ReactiveAuthorizationManager的适当类中实现此逻辑。任何尚未匹配到的 URL 都将被拒绝访问。如果您不想意外忘记更新授权规则,这是一个很好的策略。