我有一个授权服务器和一个资源服务器。我在授权服务器上创建访问令牌,并尝试在资源服务器上使用oauth2中的RemoteTokenServices,在内部命中'/ oauth / check_token'到授权服务器,它只检查令牌是否存在及其到期。但是它没有根据对于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。 有没有办法实现基于角色/范围的授权?
答案 0 :(得分:0)
如果有其他人使用基于XML的配置遇到JWT
令牌实现的类似问题,我已经通过以下方式解决了这个问题
哦,我可以找到关于如何使用基于XML的配置实现Spring OAuth2的详细帖子here
一些假设
JwtAccessTokenConvertor
的自定义实现,后者又实现了TokenEnhancer
接口(随意实现AccessTokenConvertor和TokenEnhancer接口,而无需使用JwtAccessTokenConvertor)仔细查看CheckTokenEndpoint
source code会显示以下内容
private AccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
查看DefaultAccessTokenConvertor
的{{3}},它是AccessTokenConvertor
接口的默认实现,基本上有以下合同
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
会做一些检查,例如如
除了上述内容之外,我还需要检查自定义声明,例如范围(即基本上角色及其相关权限)在数据库中是否相同(确保角色没有更改)因为令牌已经发出)。
根据我的调试,当命中/oauth/check_token
端点时,分别调用extractAccessToken
后跟extractAuthentication
方法(至少在JWT实现时)。
因为我扩展了JwtAccessTokenConvertor
(后者又实现了AccessTokenConvertor
&amp; TokenEnhancer
接口)以增强我的JWT令牌以通过覆盖向其添加自定义声明(即范围) 增强方法如下所示
@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;
}
}
我可以轻松验证JWT访问令牌在extractAccessToken
方法中是否具有所需的用户角色范围。如果我检测到任何违规,那么我抛出InvalidTokenException
(也可以是自定义异常)。