28、Authentication request failed: error=“access_denied“, error_description=“Invalid token does not c

主题错误:

 Authentication request failed: error="access_denied", error_description="Invalid token does not contain resource id (oauth2-resource)"

 

发博词

Spring Security OAuth2 架构上分为Authorization Server和Resource Server。我们可以为每一个Resource Server(一个微服务实例)设置一个resourceid。再给client授权的时候,可以设置这个client可以访问哪一些微服务实例,如果没设置,就是对所有的resource都有访问权限。

ResourceID在哪设置

在每个ResourceServer实例上设置。

 

配置文件

经测试,这个不管用,原因待查。

security:

enable-csrf: false

oauth2:

resource:

id: resource1

jwt:

key-uri: http://authorization-server:8080/oauth/token_key

filter-order: 3

 

ResourceServerConfigurerAdapter

@Configuration@EnableResourceServer@EnableOAuth2Client

public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter{

// 改资源服务器id必须在数据库记录中有配置,也就是对应token的用户必须该资源访问权限(密文:test_resource_secret)

// 例如,我的数据库记录:'wx_takeout_client_id','test_resource_id','$2a$10$I28j9B0T/roapkMEqfIHguARt0GgLyXwC/DOnFwPpXuQ0xTkrd632','user_info','authorization_code,refresh_token,implicit,password','http://localhost:7010/uaa/login','ROLE_ADMIN,ROLE_DEVICE,ROLE_VIDEO',3600,7200,'{\"systemInfo\":\"Atlas  System\"}','true'

// 通过授权模式或简化模式获取的token(对应用户为wx_takeout_client_id)具有访问资源服务器test_resource_id的权限,所以将改资源服务器id要与数据库的对应,否则无法访问

private static final String DEMO_RESOURCE_ID = "resource1";



@Override

public void configure(ResourceServerSecurityConfigurer resources) {

resources.resourceId(DEMO_RESOURCE_ID).stateless(true);

}

}

 

ResourceID在哪验证

@EnableResourceServer会给Spring Security的FilterChan添加一个OAuth2AuthenticationProcessingFilter,OAuth2AuthenticationProcessingFilter会使用OAuth2AuthenticationManager来验证token。 

OAuth2AuthenticationManager#authenticate(Authentication authentication)

public Authentication authenticate(Authentication authentication) throws AuthenticationException {



if (authentication == null) {

throw new InvalidTokenException("Invalid token (token not found)");

}

String token = (String) authentication.getPrincipal();

OAuth2Authentication auth = tokenServices.loadAuthentication(token);

if (auth == null) {

throw new InvalidTokenException("Invalid token: " + token);

}



Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds();

if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) {

throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")");

}



checkClientDetails(auth);



if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) {

OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();

// Guard against a cached copy of the same details

if (!details.equals(auth.getDetails())) {

// Preserve the authentication details from the one loaded by token services

details.setDecodedDetails(auth.getDetails());

}

}

auth.setDetails(authentication.getDetails());

auth.setAuthenticated(true);

return auth;



}



下面这段便是验证resourceid的地方;

Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds();

if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) {

throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")");

}

 

注意

(1)在Spring Security的FilterChain中,OAuth2AuthenticationProcessingFilter在FilterSecurityInterceptor的前面,所以会先验证client有没有此resource的权限,只有在有此resource的权限的情况下,才会再去做进一步的判断;

(2)同时配置WebSecurity与ResourceServer的时候,也就是认证服务器和资源服务器在统一机器的时候,会导致授权码模式失效,最根本问题是WebSecurity与ResourceServer冲突,为解决改问题,只要给的配置都指定一个序号,websecurity的优先级高于ResourceServer才行,即WebSecurity的@Order(2)要小于ResourceServer

 

快来成为我的朋友或合作伙伴,一起交流,一起进步!
QQ群:961179337
微信:lixiang6153
邮箱:lixx2048@163.com
公众号:IT技术快餐
更多资料等你来拿!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝壳里的沙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值