使用资源服务器中的用户角色限制路径上的访问 [英] Using user roles in resource server to restrict acces on path

查看:33
本文介绍了使用资源服务器中的用户角色限制路径上的访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望使用新的Spring安全授权服务器为我的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")

还在授权服务器项目中使用.roles("ADMIN")

定义了admin / admin123用户

然而,当客户端访问我在客户端项目控制台中获得的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/,但不幸的是,它使用Keyshaak作为授权服务器,但实现了相同的想法,即限制访问具有用户角色的路径。

它定义了一个KeycloakRealmRoleConverter,但是如何为给定的三个Baeldung项目定义一个?

使用Keyshaak的示例使用jwt.getClaims().get("realm_access"),这显然是访问密钥realm_access,但这与Keyshaak相关。

要打印出我在资源服务器REST控制器中更改的JWT令牌

@GetMapping("/articles")
public String[] getArticles(final @AuthenticationPrincipal Jwt 
    System.out.println("

jwt.getTokenValue():
" + 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 Security中权限、角色和作用域之间的关系。

角色只是以ROLE_为前缀的权限。
配置.antMatchers("/articles/**").hasRole("ADMIN")等同于.antMatchers("/articles/**").hasAuthority("ROLE_ADMIN")

默认情况下,资源服务器通过在每个值前面加上SCOPE_前缀,根据";作用域";声明填充授权。
在您提供的示例中,";作用域";声明包含";articles.read";,这意味着唯一的权限是SCOPE_articles.read
使用默认设置时,资源服务器没有角色概念,因为它没有以ROLE_为前缀的权限(它们都以SCOPE_为前缀)。

授权服务器中提供了授予&admin";用户的角色&admin";。
它不是令牌的一部分,因为令牌不代表用户,而是授权客户端访问用户数据的特定部分。

如果资源服务器需要用户信息,我建议查看OpenID Connect Protocol

Here是一个类似的问题,解释了为什么不应将作用域用于此目的。

这篇关于使用资源服务器中的用户角色限制路径上的访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆