【发布时间】:2021-10-12 01:04:36
【问题描述】:
我想使用新的 Spring Security Authorization Server 为我的 web 服务实现 OAuth2。
在https://www.baeldung.com/spring-security-oauth-auth-server举个例子,分离
- 授权服务器
- 资源服务器
- 客户
代码可以在https://github.com/Baeldung/spring-security-oauth/tree/master/oauth-authorization-server找到
这三个 Maven 项目在给定版本中运行,当客户端在 web 浏览器中访问 http://localhost:8080/articles 时输出正确
["Article 1","Article 2","Article 3"]
我需要根据用户定义的角色来限制对路径的访问,或者也许有权限也可以。
在这个例子中,它是在资源服务器中实现的
@EnableWebSecurity
public class ResourceServerConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.mvcMatcher("/articles/**")
.authorizeRequests()
.mvcMatchers("/articles/**").access("hasAuthority('SCOPE_articles.read')")
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
}
我改成
http
.authorizeRequests()
.antMatchers("/articles").hasRole("ADMIN")
并且还在授权服务器项目中定义了一个用户admin / admin123 和.roles("ADMIN")
但是,这并没有按预期运行,当客户端访问 http://localhost:8080/articles 我在客户端项目控制台中得到输出
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.reactive.function.client.WebClientResponseException$Forbidden: 403 Forbidden from GET http://localhost:8090/articles] with root cause
org.springframework.web.reactive.function.client.WebClientResponseException$Forbidden: 403 Forbidden from GET http://localhost:8090/articles
at org.springframework.web.reactive.function.client.WebClientResponseException.create(WebClientResponseException.java:183) ~[spring-webflux-5.3.4.jar:5.3.4]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ 403 from GET http://localhost:8090/articles [DefaultWebClient]
我找到了一个示例项目https://blog.jdriven.com/2019/10/spring-security-5-2-oauth-2-exploration-part1/,但不幸的是它使用 Keycloak 作为授权服务器,但实现了相同的想法,即使用用户角色限制对路径的访问。
它定义了一个KeycloakRealmRoleConverter,但是如何为给定的三个Baeldung项目定义一个?
Keycloak 的例子使用了jwt.getClaims().get("realm_access"),它显然访问了一个密钥realm_access,但这与Keycloak 有关。
打印出我在资源服务器 REST 控制器中更改的 JWT 令牌
@GetMapping("/articles")
public String[] getArticles(final @AuthenticationPrincipal Jwt
System.out.println("\n\njwt.getTokenValue():\n" + jwt.getTokenValue());
...
}
在jwt.io 显示
HEADER:ALGORITHM & TOKEN TYPE
{
"kid": "fce0c3e4-a9a6-4e6d-8fbd-c2b774b338f0",
"typ": "JWT",
"alg": "RS256"
}
PAYLOAD:DATA
{
"sub": "admin",
"aud": "articles-client",
"nbf": 1628351323,
"scope": [
"articles.read"
],
"iss": "http://127.0.0.1:9000",
"exp": 1628351623,
"iat": 1628351323,
"jti": "c4bc5f35-e93f-483f-8952-a694a04f8f32"
}
那里没有定义角色。我本来希望在用户名 admin 旁边还有为该用户定义的角色 ADMIN。
不确定如何限制资源服务器中具有用户角色的路径的访问,如果它不在 JWT 中。
【问题讨论】:
标签: spring-boot spring-security spring-security-oauth2