oauth/check_token 不检查与端点关联的角色/范围 [英] oauth/check_token does not check for roles/scopes associated with endpoint

查看:248
本文介绍了oauth/check_token 不检查与端点关联的角色/范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一台授权服务器和一台资源服务器.我正在授权服务器上创建访问令牌,并尝试在 oauth2 中使用 RemoteTokenServices 在资源服务器上使用它,该服务在内部将/oauth/check_token"命中授权服务器,在那里它只检查令牌是否存在及其到期.但它不会根据给定的端点和针对 access_token 的角色/范围检查角色/范围.

I have one Authorization server and one resource server. I am creating access token at authorization server and try to use it at Resource server using RemoteTokenServices in oauth2 which hits '/oauth/check_token' internally to authorization server, where it only checks for token existence and its expiry. But it does not check for roles/scopes against endpoint given vs roles/scopes against access_token.

@FrameworkEndpoint
public class CheckTokenEndpoint {
@RequestMapping(value = "/oauth/check_token")
@ResponseBody
public Map<String, ?> checkToken(@RequestParam("token") String value) {

    OAuth2AccessToken token = resourceServerTokenServices.readAccessToken(value);
    if (token == null) {
        throw new InvalidTokenException("Token was not recognised");
    }

    if (token.isExpired()) {
        throw new InvalidTokenException("Token has expired");
    }

    OAuth2Authentication authentication = resourceServerTokenServices.loadAuthentication(token.getValue());

    Map<String, ?> response = accessTokenConverter.convertAccessToken(token, authentication);

    return response;
   }
}

以上代码片段来自 CheckTokenEndpoint.java.还有什么方法可以实现基于角色/范围的授权?

Above code snippet is from CheckTokenEndpoint.java. Is there any way to achieve roles/scopes based authorization also?

推荐答案

如果其他人在使用基于 XML 的配置的 JWT 令牌实现方面遇到类似问题,我已经通过以下方式解决了它

If anyone else come across a similar issue with JWT token implementation using XML-based configuration, I have solved it the following way

哦,我关于如何使用基于 XML 的配置实现 Spring OAuth2 的详细帖子可以在 此处

Oh and my detailed post on how to implement Spring OAuth2 using XML-based configuration can be found here

一些假设

  1. 您正在使用具有自定义声明的 JWT 令牌
  2. 您提供了 JwtAccessTokenConvertor 的自定义实现,该实现又实现了 TokenEnhancer 接口(可以随意实现 AccessTokenConvertor 和 TokenEnhancer 接口,而无需使用 JwtAccessTokenConvertor)
  3. 您正在使用基于 XML 的配置
  1. You are using JWT tokens that have custom claims
  2. You have provided a custom implementation of JwtAccessTokenConvertor which in turn implements TokenEnhancer interface (feel free to implement AccessTokenConvertor & TokenEnhancer interfaces without having to use JwtAccessTokenConvertor)
  3. You are using XML-based configuration

仔细看看 CheckTokenEndpoint 源码揭示如下

private AccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();

并查看 源码DefaultAccessTokenConvertor,它是的默认实现AccessTokenConvertor 接口里面基本有如下合约

And looking at the source code of DefaultAccessTokenConvertor, it is the default implementation of AccessTokenConvertor interface which basically have the following contracts

Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication);
OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map);
OAuth2Authentication extractAuthentication(Map<String, ?> map);

就我而言,我使用了 JWT 令牌,这意味着我传递给 /oauth/token_check 端点的令牌值是一个签名的(使用 RSA 密钥对)JWT 和 TokenCheckEndpoint 会做一些检查,比如

In my case, I used JWT tokens, meaning that the token value that I pass to the /oauth/token_check endpoint is a signed (with RSA keypair) JWT and the TokenCheckEndpoint will do a few checks such as

  • 检查令牌是否在 db(oauth_access_token 表)中,这不适用于 JWT 实现,因为它们不一定存储在 db 中
  • 首先检查其有效的 JWT 令牌
  • 检查令牌的签名是否正确且未被篡改
  • 检查是否过期
  • 我不知道的其他检查

除上述之外,我还需要检查数据库中的诸如范围(即基本上角色及其相关权限)之类的自定义声明是否相同(确保角色没有改变)因为令牌已发行).

In addition to the above, I needed to check that the custom claim such as scope (i.e. basically role and its associated permissions) is same in the database (making sure that roles didn't change since token was issued).

根据我的调试,当 /oauth/check_token 端点被命中时,分别调用 extractAccessTokenextractAuthentication 方法(在至少使用 JWT 实现).

Based on my debugging, when the /oauth/check_token endpoint is hit, the extractAccessToken followed by extractAuthentication methods is called respectively (at least with JWT implementation).

因为我扩展了 JwtAccessTokenConvertor(它依次实现了 AccessTokenConvertorTokenEnhancer 接口)以增强我的 JWT 令牌以添加自定义通过覆盖 enhance 方法来声明(即范围),如下所示

Since I have extended JwtAccessTokenConvertor (which in turn implements AccessTokenConvertor & TokenEnhancer interfaces) in order to enhance my JWT token to add custom claims (i.e. scope) to it by overriding the enhance method as shown below

 @Component
 public class MyJwtAccessTokenConvertor extends JwtAccessTokenConverter {
        @Override
         public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
                 DefaultOAuth2AccessToken result = new DefaultOAuth2AccessToken(accessToken);
                //enhance the token with custom claims (i.e. user role scope) 
               //then return it 
               return result; 
          }

    @Override
    public OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map) {
            OAuth2AccessToken mytoken = tokenConverter.extractAccessToken(value, map);

            /* validate the custom claims of token i.e. user role scopes
             * and if any issue throw an exception
             */

            return token; 
         }
  }

我可以在 extractAccessToken 方法中轻松验证 JWT 访问令牌是否具有所需的用户角色范围.如果我检测到任何违规,则抛出 InvalidTokenException (也可以是自定义异常).

I could easily validate that the JWT access token has the required user role scopes in the extractAccessToken method. If I detect any violation then I throw InvalidTokenException (can be custom exception too).

这篇关于oauth/check_token 不检查与端点关联的角色/范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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