Authorize ServerHttpRequest
Spring Security 提供授权传入 HTTP 请求的支持。默认情况下,Spring Security 的授权要求所有请求都经过身份验证。显式配置如下所示:
Spring Security provides support for authorizing the incoming HTTP requests. By default, Spring Security’s authorization will require all requests to be authenticated. The explicit configuration looks like:
All Requests Require Authenticated User
-
Java
-
Kotlin
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange(exchanges -> exchanges
.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 使其拥有不同的规则。
We can configure Spring Security to have different rules by adding more rules in order of precedence.
Multiple Authorize Requests Rules
-
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)
}
// ...
}
}
1 | 已指定多个授权规则,每个规则按照声明的顺序考虑。 |
2 | There are multiple authorization rules specified. Each rule is considered in the order they were declared. |
3 | 我们指定了任何用户都可以访问的多 URL 模式。具体而言,任何用户都可以访问请求,如果 URL 以 "/resources/" 开头、等于 "/signup" 或等于 "/about"。 |
4 | We specified multiple URL patterns that any user can access. Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". |
5 | 以 "/admin/" 开头的任何 URL 都将限制为拥有 "ROLE_ADMIN" 权限的用户。您会注意到,由于我们调用了 `hasRole`方法,因此我们不需要指定 "ROLE_" 前缀。 |
6 | Any URL that starts with "/admin/" will be restricted to users who have the authority "ROLE_ADMIN".
You will notice that since we are invoking the hasRole method we do not need to specify the "ROLE_" prefix. |
7 | 以 "/db/" 开头的任何 URL 要求用户同时拥有 "ROLE_ADMIN" 和 "ROLE_DBA"。这展示了我们提供的自定义 `ReactiveAuthorizationManager`的灵活性,允许我们实施任意的授权逻辑。为了简单起见,示例使用了一个 lambda 并委托给现有的 `AuthorityReactiveAuthorizationManager.hasRole`实现。但是在实际情况下,应用程序可能会在实现 `ReactiveAuthorizationManager`的适当类中实现逻辑。 |
8 | Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA".
This demonstrates the flexibility of providing a custom ReactiveAuthorizationManager allowing us to implement arbitrary authorization logic.
For simplicity, the sample uses a lambda and delegate to the existing AuthorityReactiveAuthorizationManager.hasRole implementation.
However, in a real world situation applications would likely implement the logic in a proper class implementing ReactiveAuthorizationManager . |
9 | 对于尚未匹配到的任何 URL,都会拒绝访问。如果你不想忘记意外更新授权规则,这是一个好策略。 |
10 | Any URL that has not already been matched on is denied access. This is a good strategy if you do not want to accidentally forget to update your authorization rules. |