gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 01:21:16 28 4
gpt4 key购买 nike

我正在尝试使用 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com