Spring Security中用JWT退出登录时遇到的坑


Posted in Java/Android onOctober 16, 2021

最近有个粉丝提了个问题,说他在Spring Security中用JWT做退出登录的时无法获取当前用户,导致无法证明“我就是要退出的那个我”,业务失败!经过我一番排查找到了原因,而且这个错误包括我自己的大部分人都犯过。

Session会话

之所以要说Session会话,是因为Spring Security默认配置就是有会话的,所以当你登录以后Session就会由服务端保持直到你退出登录。只要Session保持住,你的请求只要进入服务器就可以从 ServletRequest 中获取到当前的 HttpSession ,然后会根据 HttpSession 来加载当前的 SecurityContext 。相关的逻辑在Spring Security默认的过滤器 SecurityContextPersistenceFilter 中,有兴趣可以看相关的源码。

而且默认情况下 SecurityContextPersistenceFilter 的优先级是高于退出过滤器 LogoutFilter 的,所以能够保证有Session会话的情况下退出一定能够获取当前用户。

无Session会话

使用了JWT后,每次请求都要携带 Bearer Token 并且被专门的过滤器拦截解析之后才能将用户认证信息保存到 SecurityContext 中去。参考Spring Security实战干货教程中的Token认证实现 JwtAuthenticationFilter ,相关逻辑为:

// 当token匹配         
if (jwtToken.equals(accessToken)) {
    // 解析 权限集合  这里
    JSONArray jsonArray = jsonObject.getJSONArray("roles");
    List<String> roles = jsonArray.toList(String.class);
    String[] roleArr = roles.toArray(new String[0]);

    List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(roleArr);
    User user = new User(username, "[PROTECTED]", authorities);
    // 构建用户认证token
    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user, null, authorities);
    usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
    // 放入安全上下文中
    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
} else {
    // token 不匹配
    if (log.isDebugEnabled()){
        log.debug("token : {}  is  not in matched", jwtToken);
    }
    throw new BadCredentialsException("token is not matched");
}

为什么退出登录无法获取当前用户

分析了两种情况下用户认证信息的安全上下文配置后,我们回到问题的本身。来看看为什么用JWT会出现无法获取当前认证信息的原因。在 HttpSecurity 中,那位同学是这样配置 JwtAuthenticationFilter 的顺序的:

httpSecurity.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
我们再看看 Spring Security 过滤器排序图:

Spring Security中用JWT退出登录时遇到的坑

也就说LogoutFilter执行退出的时候,JWT还没有被 JwtAuthenticationFilter 拦截,当然无法获取当前认证上下文 SecurityContext 。

解决方法

解决方法就是必须在 LogoutFilter 执行前去解析JWT并将成功认证的信息存到 SecurityContext 。我们可以这样配置:

httpSecurity.addFilterBefore(jwtAuthenticationFilter, LogoutFilter.class)
这样问题就解决了,你只要实现把当前JWT作废掉就退出登录了。

到此这篇关于Spring Security中用JWT退出登录时遇到的坑的文章就介绍到这了,更多相关Spring Security JWT退出登录内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Java/Android 相关文章推荐
Spring整合Mybatis的全过程
Jun 28 Java/Android
java设计模式--七大原则详解
Jul 21 Java/Android
SpringBoot+VUE实现数据表格的实战
Aug 02 Java/Android
SpringBoot整合阿里云视频点播的过程详解
Dec 06 Java/Android
利用Sharding-Jdbc进行分库分表的操作代码
Jan 22 Java/Android
Android自定义ScrollView实现阻尼回弹
Apr 01 Java/Android
springboot入门 之profile设置方式
Apr 04 Java/Android
Java中API的使用方法详情
Apr 06 Java/Android
java中为什么说子类的构造方法默认访问的是父类的无参构造方法
Apr 13 Java/Android
详解Flutter网络请求Dio库的使用及封装
Apr 14 Java/Android
Spring IOC容器Bean的作用域及生命周期实例
May 30 Java/Android
Android开发手册TextInputLayout样式使用示例
Jun 10 Java/Android
Java实现房屋出租系统详解
Oct 05 #Java/Android
Java Spring 控制反转(IOC)容器详解
Java spring定时任务详解
JAVA API 实用类 String详解
Oct 05 #Java/Android
SpringCloud之@FeignClient()注解的使用方式
Sep 25 #Java/Android
springboot中rabbitmq实现消息可靠性机制详解
Sep 25 #Java/Android
Spring Cloud 中@FeignClient注解中的contextId属性详解
Sep 25 #Java/Android
You might like
php下关于中英数字混排的字符串分割问题
2010/04/06 PHP
了解PHP的返回引用和局部静态变量
2015/06/04 PHP
PHP的cookie与session原理及用法详解
2019/09/27 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
如何做到打开一个页面,过几分钟自动转到另一页面
2007/04/20 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
node.js中的http.get方法使用说明
2014/12/14 Javascript
浅谈轻量级js模板引擎simplite
2015/02/13 Javascript
拥有一个属于自己的javascript表单验证插件
2016/03/24 Javascript
jquery常用的12个小功能
2016/07/22 Javascript
Javascript 事件冒泡机制详细介绍
2016/10/10 Javascript
实例解析angularjs的filter过滤器
2016/12/14 Javascript
JS常用知识点整理
2017/01/21 Javascript
JS实现向iframe中表单传值的方法
2017/03/24 Javascript
JavaScript数据结构之数组的表示方法示例
2017/04/12 Javascript
详解JS中统计函数执行次数与执行时间
2018/09/04 Javascript
vue.js 2.0实现简单分页效果
2019/07/29 Javascript
jQuery实现的图片点击放大缩小功能案例
2020/01/02 jQuery
JavaScript canvas实现雪花随机动态飘落
2020/02/08 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
2020/11/06 Javascript
Python检测QQ在线状态的方法
2015/05/09 Python
Python使用回溯法子集树模板解决迷宫问题示例
2017/09/01 Python
Python视频爬虫实现下载头条视频功能示例
2018/05/07 Python
解决win64 Python下安装PIL出错问题(图解)
2018/09/03 Python
详解Python中的正斜杠与反斜杠
2019/08/09 Python
没编程基础可以学python吗
2020/06/17 Python
python工具——Mimesis的简单使用教程
2021/01/16 Python
更夫岗位责任制
2014/02/11 职场文书
委托公证书范本
2014/04/03 职场文书
项目合作协议书范本
2014/04/16 职场文书
预备党员转正思想汇报
2014/09/26 职场文书
三八妇女节寄语
2015/02/27 职场文书
大学团日活动总结书
2015/05/11 职场文书
情况说明书怎么写
2015/10/08 职场文书
CSS的calc函数用法小结
2022/06/25 HTML / CSS