客户端带 Token 情况
1 客户端携带 token 访问 A 服务。
2 A服务通过 FeginClient 调用 B 服务获取相关依赖数据。
3 所以只要带 token 访问 A 无论后边链路有多长 ABCD 都可以获取当
4 前用户信息权限需要有这些整个链路接口的全部权限才能成功
有 token 调用不需要加 Inner /FROM_IN 等 !!!!!
核心代码
feign 拦截器将本服务的 token 通过 copyToken 的形式传递给下游服务
public class GczjtFeignClientInterceptor extends OAuth2FeignRequestInterceptor {
private final OAuth2ClientContext oAuth2ClientContext;
private final AccessTokenContextRelay accessTokenContextRelay;
/**
* Default constructor which uses the provided OAuth2ClientContext and Bearer tokens
* within Authorization header
* @param oAuth2ClientContext provided context
* @param resource type of resource to be accessed
* @param accessTokenContextRelay
*/
public GczjtFeignClientInterceptor(OAuth2ClientContext oAuth2ClientContext, OAuth2ProtectedResourceDetails resource,
AccessTokenContextRelay accessTokenContextRelay) {
super(oAuth2ClientContext, resource);
this.oAuth2ClientContext = oAuth2ClientContext;
this.accessTokenContextRelay = accessTokenContextRelay;
}
/**
* Create a template with the header of provided name and extracted extract 1. 如果使用
* 非web 请求,header 区别 2. 根据authentication 还原请求token
* @param template
*/
@Override
public void apply(RequestTemplate template) {
Collection<String> fromHeader = template.headers().get(SecurityConstants.FROM);
if (CollUtil.isNotEmpty(fromHeader) && fromHeader.contains(SecurityConstants.FROM_IN)) {
return;
}
accessTokenContextRelay.copyToken();
if (oAuth2ClientContext != null && oAuth2ClientContext.getAccessToken() != null) {
super.apply(template);
}
}
}
很多情况下,比如定时任务 服务内部发起情况处理。A 服务并没有 token 去请求 B 服务
FeignClient 需要带一个请求 token,FROM_IN 声明是内部调用
remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN);
@Inner 注解
通过 inner 注解使得目标接口对内外调用进行限制,这样就避免接口对外暴露的安全问题。只能通过内部调用才能使用,浏览器不能直接访问该接口
@Inner
@PostMapping
public R save(@Valid @RequestBody SysLog sysLog) {
return new R<>(sysLogService.save(sysLog));
}
文档更新时间: 2021-08-10 17:00 作者:admin