Spring Security Oauth2源码BUG认证并发用户身份信息混乱问题

1.背景:

随着业务的增长,线上系统qps越来越高,起初市场同事和客户偶尔会反馈用户看到的信息出现的不是自己的信息,但是重新刷新之后就好了,当时我们就对这个问题进行分析,但是都是无疾而终,没有找到问题所在,随着用户增长的基数越来越大,出现这个问题的现象也就更加频繁,所以我们团队对于这个线上事故就非常重视,开始对于整个请求链路分析,我们用户端使用的是一款我们自研的客户端,当时我们分析出来可能存在的几个原因:

  • 同一个客户端,不同用户登录,本地缓存的token混乱。
  • 客户端因为某种特定场景下拿到了别人的token,或者是登录接口直接颁发的token就是错的
  • 接口请求token认证过程中,由于线程的原因,导致线程中用户信息错乱(分析过Spring security oauth2的源码,请求接口是会验证token的有效性——通过访问认证服务器去识别token的有效性,并采用的ThreadLocal模式存储用户身份信息),这边错乱的信息主要是因为,接口请求结束的时候ThreadLocal信息没有清理导致的(tomcat采用线程池)。

2. 验证阶段

首先我们上线了一个紧急修复措施,写了一个统一拦截器,拦截接口请求,验证token中的身份信息(jwt的token认证方式,可以通过payload解析出来用户身份-Base64解码)和Spring security oauth2 认证后获取到身份信息比较,对比成功的放行,失败的拦截,同时打印相关日志。具体代码如下:

@Slf4j
@Component
public class RequestInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 框架集成方法,可以自行源码,其实就是threadLocal 方式存储用户身份信息
        String clientId = (String)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (checkToken(request, clientId)) {
            return super.preHandle(request, response, handler);
        }
        Map<String, Object> map = Maps.newHashMap();
        map.put("code", 40412);
        map.put("message", "请退出,重新登录!");
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(JSON.toJSONString(map));
        return false;
    }

    private boolean checkToken(HttpServletRequest request,
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值