资讯专栏INFORMATION COLUMN

Spring Cloud OAuth 微服务内部Token传递的源码实现解析

Michael_Ding / 2581人阅读

摘要:源码非常简单谈谈实现的问题当请求上线文没有如果调用会直接,这个肯定会报错,因为上下文失败如果设置线程隔离,这里也会报错。导致安全上下问题传递不到子线程中。欢迎关注我们获得更多的好玩实践

背景分析

1.客户端携带认证中心发放的token,请求资源服务器A(Spring Security OAuth 发放Token 源码解析)

2.客户端携带令牌直接访问资源服务器,资源服务器通过对token 的校验 ([Spring Cloud OAuth2 资源服务器CheckToken 源码解析

](https://my.oschina.net/giegie...) 判断用户的合法性,并保存到上下文中

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 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 客户端的配置

总结

以上源码参考个人项目 基于Spring Cloud、OAuth2.0开发基于Vue前后分离的开发平台

QQ: 2270033969 一起来聊聊你们是咋用 spring cloud 的吧。

欢迎关注我们获得更多的好玩JavaEE 实践

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74136.html

相关文章

  • 使用 OAuth 2 和 JWT 为服务提供安全保障

    摘要:作为目前最主流的微服务框架,发展速度很快,成为了最全面的微服务解决方案。通过认证后,转发给内部相应的服务器。所有远程访问资源服务器相关的必须提供。 Part 1 - 理论相关 作者 freewolf 关键词 微服务、Spring Cloud、OAuth 2.0、JWT、Spring Security、SSO、UAA 写在前面 作为从业了十多年的IT行业和程序的老司机,今天如果你说你不懂...

    littleGrow 评论0 收藏0
  • 使用 OAuth 2 和 JWT 为服务提供安全保障

    摘要:作为目前最主流的微服务框架,发展速度很快,成为了最全面的微服务解决方案。通过认证后,转发给内部相应的服务器。所有远程访问资源服务器相关的必须提供。 Part 1 - 理论相关 作者 freewolf 关键词 微服务、Spring Cloud、OAuth 2.0、JWT、Spring Security、SSO、UAA 写在前面 作为从业了十多年的IT行业和程序的老司机,今天如果你说你不懂...

    xzavier 评论0 收藏0
  • 基于oauth 2.0 实现第三方开放平台

    摘要:本文单纯从简单的技术实现来讲,不涉及开放平台的多维度的运营理念。它的特点就是通过客户端的后台服务器,与服务提供商的认证服务器进行互动能够满足绝大多数开放平台认证授权的需求。 本文单纯从简单的技术实现来讲,不涉及开放平台的多维度的运营理念。 什么是开放平台 通过开放自己平台产品服务的各种API接口,让其他第三方开发者在开发应用时根据需求直接调用,例如微信登录、QQ登录、微信支付、微博登录...

    Simon 评论0 收藏0
  • 基于oauth 2.0 实现第三方开放平台

    摘要:本文单纯从简单的技术实现来讲,不涉及开放平台的多维度的运营理念。它的特点就是通过客户端的后台服务器,与服务提供商的认证服务器进行互动能够满足绝大多数开放平台认证授权的需求。 本文单纯从简单的技术实现来讲,不涉及开放平台的多维度的运营理念。 什么是开放平台 通过开放自己平台产品服务的各种API接口,让其他第三方开发者在开发应用时根据需求直接调用,例如微信登录、QQ登录、微信支付、微博登录...

    xiaodao 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<