api - 使用 Spring Boot 和 OAuth2 获取此资源的范围不足

标签 api rest security spring-security-oauth2

我正在尝试使用 Spring Boot 1.2.2 为 REST API 运行一个小的概念证明,并使用 OAuth2 进行保护。为此,我创建了两个项目,一个用于身份验证服务器,另一个用于 REST 服务。

运行项目时,一切顺利。我从身份验证服务器获得一个 token ,然后使用该 token ,我设法调用了该服务并获得了预期的结果。

当我尝试验证服务中的范围时会出现此问题。一旦我添加了这一行:

@PreAuthorize("#oauth2.hasScope('webshop')")

到我的服务,在代码中:

@RestController
public class ProductService {

    @RequestMapping("/product/{productId}")
    @PreAuthorize("#oauth2.hasScope('webshop')")
    public Product getProduct(@PathVariable int productId) {

        return new Product(productId, "name", 123);
    }
}

我得到这个回应:
{
   "error": "insufficient_scope",
   "error_description": "Insufficient scope for this resource",
   "scope": "webshop"
}

认证服务器配置为:

@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("acme")
            .secret("acmesecret")
            .authorizedGrantTypes("authorization_code", "refresh_token", "implicit", "password", "client_credentials")
            .scopes("webshop");
    }
}

这是获取 token 的实际调用:
juan@ubuntu:~/ms/core/product-service$ curl -s acme:acmesecret@localhost:9999/uaa/oauth/token -d grant_type=client_credentials -d scope=webshop
{
  "access_token": "ac3a9768-4ebb-44e3-a49f-21e2f117d0b4",
  "token_type": "bearer",
  "expires_in": 43199,
  "scope": "webshop"
}

然后,调用服务:
juan@ubuntu:~/ms/core/product-service$ TOKEN=ac3a9768-4ebb-44e3-a49f-21e2f117d0b4
juan@ubuntu:~/ms/core/product-service$ curl 'http://localhost:8080/product/32' -H "Authorization: Bearer $TOKEN" -s
{
  "error": "insufficient_scope",
  "error_description": "Insufficient scope for this resource",
  "scope": "webshop"
}

我觉得我只是因为缺乏概念而错过了一些简单的东西。如果客户端已经创建在内存中,应该允许做“网店”,并且token生成成功,为什么会报错?

预先感谢您指出一些方向或帮助。

最佳答案

这是由于 UserInfoTokenServices 类未能从请求中提取范围,因此没有将它们添加到新的 OAuth2Request 中造成的。

具体这个方法

private OAuth2Authentication extractAuthentication(Map<String, Object> map) {
    Object principal = getPrincipal(map);
    List<GrantedAuthority> authorities = this.authoritiesExtractor
            .extractAuthorities(map);
    OAuth2Request request = new OAuth2Request(null, this.clientId, null, true, null,
            null, null, null, null);
    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
            principal, "N/A", authorities);
    token.setDetails(map);
    return new OAuth2Authentication(request, token);
}

忽略从 oauth2Request 映射条目中提取范围映射,然后将范围集合的空值传递给 Oauth2Request 范围参数的构造函数。

这意味着即使您可能已将用户授权到特定范围,当通过 security.oauth2.resource.userInfoUri 端点查询 authserver 时,调用代码中会忽略授权范围,因此 PreAuthorize 检查失败。

这对我来说似乎是一个错误;我已经提出 an issue on github .

关于api - 使用 Spring Boot 和 OAuth2 获取此资源的范围不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36777188/

相关文章:

security - 远程开发中的 VSCode 远程 ssh 扩展是否存储任何信息客户端?

database - 限制 PouchDB 中的数据

php - password_hash 中的默认算法是什么

Android:几个Camera API问题

java - 我应该在 Post 方法中设置哪个 IP 地址?

java - CXF JAX-RS 客户端代理不维护 cookie

java - 自 Java 升级到 8 后,启动 Java 的 Windows 服务无法正常工作

git - 如何通过 API 从 SonarQube 项目中检索分支信息?

c# - Web API JSON 格式

javascript - 为什么 Meteor.call() 无法识别?