Spring Cloud OAuth 微服务内部Token传递的源码实现解析
背景分析
- 1.客户端携带认证中心发放的token,请求资源服务器A(Spring Security OAuth 发放Token 源码解析)
- 2.客户端携带令牌直接访问资源服务器,资源服务器通过对token 的校验 ([Spring Cloud OAuth2 资源服务器CheckToken 源码解析
](https://my.oschina.net/giegie/blog/3005999)) 判断用户的合法性,并保存到上下文中 - 3.A服务接口接收到请求,需要通过Feign或者其他RPC框架调用B服务来组装返回数据
本文主要来探讨第三部 A --> B ,token 自定维护的源码实现
如何实现token 传递
配置OAuth2FeignRequestInterceptor 即可
- 此类是Feign 的拦截器实现
@Bean
@ConditionalOnProperty("security.oauth2.client.client-id")
public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oAuth2ClientContext,
OAuth2ProtectedResourceDetails resource,) {
return new OAuth2FeignRequestInterceptor(oAuth2ClientContext, resource);
}
源码解析
- 获取上下文中的token ,组装到请求头
public class OAuth2FeignRequestInterceptor implements RequestInterceptor {
// 给请求增加 token
@Override
public void apply(RequestTemplate template) {
template.header(header, extract(tokenType));
}
protected String extract(String tokenType) {
OAuth2AccessToken accessToken = getToken();
return String.format("%s %s", tokenType, accessToken.getValue());
}
// 从spring security 上下文中获取token
public OAuth2AccessToken getToken() {
OAuth2AccessToken accessToken = oAuth2ClientContext.getAccessToken();
if (accessToken == null || accessToken.isExpired()) {
try {
accessToken = acquireAccessToken();
}
}
return accessToken;
}
}
- 再来看AccessTokenContextRelay, 上下文token 中转器.非常简单从上下文获取认证信息得到把 token 放到上下文
public class AccessTokenContextRelay {
private OAuth2ClientContext context;
public AccessTokenContextRelay(OAuth2ClientContext context) {
this.context = context;
}
public boolean copyToken() {
if (context.getAccessToken() == null) {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (authentication != null) {
Object details = authentication.getDetails();
if (details instanceof OAuth2AuthenticationDetails) {
OAuth2AuthenticationDetails holder = (OAuth2AuthenticationDetails) details;
String token = holder.getTokenValue();
DefaultOAuth2AccessToken accessToken = new DefaultOAuth2AccessToken(
token);
String tokenType = holder.getTokenType();
if (tokenType != null) {
accessToken.setTokenType(tokenType);
}
context.setAccessToken(accessToken);
return true;
}
}
}
return false;
}
}
- 什么时候执行中转,oauth2 资源服务器非常简单暴力,加了个拦截器给转发。
源码非常简单
谈谈spring security oauth 实现的问题
- 当请求上线文没有Token,如果调用feign 会直接,这个OAuth2FeignRequestInterceptor 肯定会报错,因为上下文copy 失败
- 如果设置线程隔离,这里也会报错。导致安全上下问题传递不到子线程中。
- 强制使用拦截器去处理 token 转发到这里上下文,使用的业务场景只有这里,影响性能高
这三个问题,大家在使用的过程中一定会遇到
自定义OAuth2FeignRequestInterceptor
- 通过外部条件是否执行token中转
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);
}
}
- 手动调用accessTokenContextRelay的copy,当然需要覆盖原生oauth 客户端的配置

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Arthas排查Kubernetes中的应用频繁挂掉重启问题
前言 其实最终定位到的问题还是蛮好解决的,但是因为应用在Kubernetes容器中的特殊性,导致在使用Arthas过程中出现了各种问题,所以单独成文和大家分享下。照例先讲下问题发生的背景,一个很老的web系统部署在tomcat容器里。近期打成了镜像丢到了Kubernetes环境中运行,总是各种挂,在Kubernetes层面定位了很久没找到具体问题,但是初步定位到是因为系统中的报表导出接口导致的问题,最后使用Arthas找到问题并解决。 Kubernetes容器的特殊性 首先说下,我们的Kubernetes容器中运行的应用都是基于自己构建的基础镜像打包的,如JDK,和tomcat基础镜像,为了减小打包后应用的体积,我们对JDK进行了大量的删减,只保留了最小的jre运行时环境。这样导致的后果是在应用出现问题需要使用jdk工具时,如jinfo、jmap、jstack等都没了,没了这些工具就相当于一个战士没了武器,束手无策了,但是最后忽然想到了Arthas,java线上排错利器。 使用到的工具Arthas Arthas是阿里巴巴开源的一款在线诊断java应用程序的工具,是greys工具的升级版...
-
下一篇
iOS ipa包瘦身,iOS8及以下text段超60MB
前沿很早之前写过一篇相关文章,不过博客主机上跑路了之后数据没了,凭着记忆补了下相关资料 ipa安装包瘦身清理无用图片,图片压缩(PNG换WebP和JPG),处于某种不可抗拒的原因,导致有部分3X图没有被App Thining处理,这部分3x图是否可以删除只用2x图。(这一条一般收益很小,因为大部分团队都会注意)特殊字体文件如果有自己封装的库,检查下静态库和动态库情况,不要该打静态库的不注意输出的是动态库,这个我们之前犯过错App Code重构,找出无用代码(这个工作量大,但是对下面text段也有好处)检查编译优化设置(有些设置项最好检查下因为老工程很多都是以前老版本Xcode建立的,会导致设置还是以前老Xcode的设置),可参考: BuildSettings->Optimization Level,Xcode默认设置 为“Fastest ,Smallest”,保持默认即可。Build Settings-> Linking->Dead Code Stripping 设置成 YESDeployment Postprocessing 设置成YESStrip Linked P...
相关文章
文章评论
共有0条评论来说两句吧...