java 拦截器-用户无操作超时退出利用Redis

1、授权过滤,只要实现AuthConfigAdapter接口
2、利用Redis token超时时间,用户访问后台续时

效果
在这里插入图片描述

@Component
public class AuthFilter implements Filter {private static Logger logger = LoggerFactory.getLogger(AuthFilter.class);@Autowiredprivate AuthConfigAdapter authConfigAdapter;@Autowired(required = false)private HttpHandler httpHandler;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;List<String> excludePathPatterns = authConfigAdapter.excludePathPatterns();// 如果匹配不需要授权的路径,就不需要校验是否需要授权if (CollectionUtil.isNotEmpty(excludePathPatterns)) {for (String excludePathPattern : excludePathPatterns) {AntPathMatcher pathMatcher = new AntPathMatcher();if (pathMatcher.match(excludePathPattern, req.getRequestURI())) {chain.doFilter(req, resp);return;}}}String accessToken = req.getHeader("Authorization");String sysType = req.getHeader("SysType");if (StrUtil.isBlank(accessToken)) {logger.error("{} : {}", ResponseEnum.UNAUTHORIZED, req.getRequestURI());httpHandler.printServerResponseToWeb(ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED));return;}if(StrUtil.isBlank(sysType)){logger.error("{} : {}", ResponseEnum.UNAUTHORIZED, req.getRequestURI());httpHandler.printServerResponseToWeb(ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED));return;}// 校验token,并返回用户信息ServerResponseEntity<UserInfoInTokenBO> userInfoInTokenVoServerResponseEntity = TokenSecurity.checkToken(accessToken);if (!userInfoInTokenVoServerResponseEntity.isSuccess()) {logger.error("{} : {}", ServerResponseEntity.transform(userInfoInTokenVoServerResponseEntity), req.getRequestURI());httpHandler.printServerResponseToWeb(ServerResponseEntity.transform(userInfoInTokenVoServerResponseEntity));return;}if(userInfoInTokenVoServerResponseEntity.getData().getSysType() != Integer.parseInt(sysType)){httpHandler.printServerResponseToWeb(ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED));return;}AuthUserContext.set(BeanUtil.copyProperties(userInfoInTokenVoServerResponseEntity.getData(), UserInfoInTokenBO.class));try {chain.doFilter(req, resp);} finally {AuthUserContext.clean();}}
}@Component
@RefreshScope
public class TokenSecurity {private static final Logger logger = LoggerFactory.getLogger(TokenSecurity.class);private static RedisTemplate<Object, Object> redisTemplate = null;private static StringRedisTemplate stringRedisTemplate;public TokenSecurity(RedisTemplate<Object, Object> redisTemplate, StringRedisTemplate stringRedisTemplate) {TokenSecurity.redisTemplate = redisTemplate;TokenSecurity.stringRedisTemplate = stringRedisTemplate;}public static ServerResponseEntity<UserInfoInTokenBO> checkToken(String accessToken) {ServerResponseEntity<UserInfoInTokenBO> userInfoByAccessTokenResponse = getUserInfoByAccessToken(accessToken, true);if (!userInfoByAccessTokenResponse.isSuccess()) {return ServerResponseEntity.transform(userInfoByAccessTokenResponse);}return ServerResponseEntity.success(userInfoByAccessTokenResponse.getData());}public static ServerResponseEntity<UserInfoInTokenBO> getUserInfoByAccessToken(String accessToken, boolean needDecrypt) {if (StrUtil.isBlank(accessToken)) {return ServerResponseEntity.showFailMsg("accessToken is blank");}String realAccessToken;if (needDecrypt) {ServerResponseEntity<String> decryptTokenEntity = decryptToken(accessToken);if (!decryptTokenEntity.isSuccess()) {return ServerResponseEntity.transform(decryptTokenEntity);}realAccessToken = decryptTokenEntity.getData();}else {realAccessToken = accessToken;}UserInfoInTokenBO userInfoInTokenBO = (UserInfoInTokenBO) redisTemplate.opsForValue().get(getAccessKey(realAccessToken));if (userInfoInTokenBO == null) {return ServerResponseEntity.fail(ResponseEnum.CLEAN_TOKEN);}String refreshToken = stringRedisTemplate.opsForValue().get(CacheNames.REFRESH_TO_ACCESS + userInfoInTokenBO.getMobile());if (StrUtil.isBlank(refreshToken)) {return ServerResponseEntity.fail(ResponseEnum.CLEAN_TOKEN);}// 存在则token续时7200秒redisTemplate.opsForValue().getAndExpire(getAccessKey(realAccessToken), 7200L, TimeUnit.SECONDS);return ServerResponseEntity.success(userInfoInTokenBO);}public static String getAccessKey(String accessToken) {return CacheNames.ACCESS + accessToken;}private static ServerResponseEntity<String> decryptToken(String data) {String decryptStr;String decryptToken;try {decryptStr = Base64.decodeStr(data);decryptToken = decryptStr.substring(0,32);// 创建token的时间,token使用时效性,防止攻击者通过一堆的尝试找到aes的密码,虽然aes是目前几乎最好的加密算法long createTokenTime = Long.parseLong(decryptStr.substring(32,45));// token的过期时间int expiresIn = getExpiresIn();long second = 1000L;if (System.currentTimeMillis() - createTokenTime > expiresIn * second) {return ServerResponseEntity.fail(ResponseEnum.TOKEN_ERROR);}}catch (Exception e) {logger.error(e.getMessage());return ServerResponseEntity.fail(ResponseEnum.TOKEN_ERROR);}// 防止解密后的token是脚本,从而对redis进行攻击,uuid只能是数字和小写字母if (!PrincipalUtil.isSimpleChar(decryptToken)) {return ServerResponseEntity.fail(ResponseEnum.TOKEN_ERROR);}return ServerResponseEntity.success(decryptToken);}private static int getExpiresIn() {// 3600秒int expiresIn = 3600;expiresIn = expiresIn * 24;return expiresIn;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OWASP top10--SQL注入(二)

目录 06&#xff1a;SQL注入提交方式 6.1、get提交 6.2、post提交 6.3、cookie提交 6.4、HTTP Header头提交 07&#xff1a;注入攻击支持类型 7.1、union注入&#xff1a; 7.1.1、union操作符一般与order by语句配合使用 7.1.2、information_schema注入 7.2、基于函数…

在gitlab CICD中 小试 hooks:pre_get_sources_script 功能

参考链接&#xff1a; hooks:pre_get_sources_script 功能简介 hooks:pre_get_sources_script 是gitlab CICD中的一个功能&#xff0c;该功能可以指定在克隆 Git 仓库和任何子模块之前要在执行器上执行的某些命令。例如&#xff1a; 调整 Git 配置导出跟踪变量 下来简单给…

(已开源-ICRA2023) High Resolution Point Clouds from mmWave Radar

本文提出了一种用于生成高分辨率毫米波雷达点云的方法&#xff1a;RadarHD&#xff0c;端到端的神经网络&#xff0c;用于从低分辨率雷达构建类似激光雷达的点云。本文通过在大量原始雷达数据上训练 RadarHD 模型&#xff0c;同时这些雷达数据有对应配对的激光雷达点云数据。本…

<Python实际应用>用yolov9实现垃圾检测

公司一个项目需要在无人机巡检的画面中识别垃圾和汽车&#xff0c;正好听闻yolov9最新出炉&#xff0c;于是试了一下采用yolov9来搭建该项目 1.下载和部署 下载yolov9:GitHub地址&#xff1a;GitHub代码下载地址 配置环境可以参考之前关于yolov5的文章 Yolov5自学笔记之一-…

vcpkg环境配置

vcpkg 使用linux相关库&#xff0c;设置环境变量VCPKG_ROOT&#xff0c;设置cmake工具链$VCPKG_ROOT/scripts\buildsystems\vcpkg.cmake set VCPKG_DEFAULT_TRIPLETx64-windows .\vcpkg.exe install fftw3 freetype gettext glibmm gtkmm libjpeg-turbo libpng libxmlpp libs…

驱动开发之新字符设备驱动开发

1.前言 register_chrdev 和 unregister_chrdev 这两个函数是老版本驱动使用的函数&#xff0c;现在新的 字符设备驱动已经不再使用这两个函数&#xff0c;而是使用 Linux 内核推荐的新字符设备驱动 API 函数。 旧版本的接口使用&#xff0c;感兴趣可以看下面这个博客&#…

免费图片文字转换成文本,ocr文字识别软件免费版,真的太实用了!

截屏短视频上一段扎心文字&#xff0c;想把它发到朋友圈怎么办&#xff1f;这时候就需要一个OCR识别软件。 它就像一个聪明的小助手&#xff0c;它可以帮助电脑“看懂”书本上或者图片里的字。就像我们用眼睛看字一样&#xff0c;OCR软件用它的“眼睛”扫描图片&#xff0c;识…

百亿级流量红包系统,如何做架构?(字节面试真题)

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的架构类/设计类的场景题&#xff1a; 1.如何设计高并发红包系统 &#xff0…

【移动云】云端赋能——数字化时代游戏与工作的新境界

前言 在当今这个信息化、数字化的时代&#xff0c;云计算、大数据和人工智能等前沿技术已经深入到我们生活的方方面面。作为我国通信行业的领军企业&#xff0c;中国移动凭借其在5G技术领域的领先优势&#xff0c;推出了基于移动云计算技术的云业务品牌——移动云。移动云以云操…

猫抓(cat-catch)插件的常规用法

目录 1.1、前言1.2、抓取图片资源1.3、抓取音频资源1.4、抓取视频资源 1.1、前言 本文将介绍利用猫抓&#xff08;cat-catch&#xff09;插件如下抓取网页上的图片、音频、视频等资源&#xff0c;猫抓&#xff08;cat-catch&#xff09;插件的安装及设置请参考推荐一款媒体影音…

一文扫尽Nas常用Docker软件

NAS&#xff08;Network Attached Storage&#xff0c;网络附加存储&#xff09;设备上的Docker软件选择取决于您的具体需求和用途。以下是一些NAS上常用的Docker软件推荐&#xff1a; Docker管理工具&#xff1a; Watchtower&#xff1a;它可以自动更新Docker容器中的镜像&…

HILL密码

一&#xff1a;简介 Hill密码又称希尔密码是运用基本矩阵论原理的替换密码&#xff0c;属于多表代换密码的一种&#xff0c;由L e s t e r S . H i l l Lester S. HillLesterS.Hill在1929年发明。 二&#xff1a;原理 1.对于每一个字母&#xff0c;我们将其转化为对应的数字&am…

UneMeta与日本顶级IP熊本熊合作,首个NFT玩法揭秘

UneMeta 生态是一个备受加密市场以及动漫 IP 市场关注的老牌 Web3 数字资产平台&#xff0c;旨在架起现实艺术 IP 和 NFT 艺术社区之间的桥梁&#xff0c;以促进 Web3 社区的包容性和多样性。并期望基于生态一流的产品体验和平台属性&#xff0c;打造一个包容交汇的元宇宙社区。…

MDK安装

MDK安装 1 MDK的差异2 切换MDK3 安装芯片支持包注意点 1 MDK的差异 不同版本MDK有略微的差别&#xff0c;比如&#xff1a;MDK536.EXE&#xff0c;支持版本5的交叉编译链。如下图所示&#xff1a; 而MDK539.EXE不支持版本5的交叉编译链&#xff0c;所以工作的时候&#xff0c…

anaconda的安装和使用

anaconda的安装和使用 Anaconda 是一个用于科学计算和数据分析的开源发行版&#xff0c;包含了Python和R的众多包和管理工具。以下是Anaconda的安装和使用指南&#xff1a; 1. 安装Anaconda 1.1 下载Anaconda 访问 Anaconda官网 下载适用于你操作系统的Anaconda安装包。 1.2 安…

【C语言】自定义类型:联合体和枚举

1. 联合体 1.1 联合体的特点 像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。 但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间所以联合体也叫&#xff1a;共⽤体。 union Un {char…

K8s的CRI机制是什么?

1. 概述 进入 K8s 的世界&#xff0c;会发现有很多方便扩展的 Interface&#xff0c;包括 CRI, CSI, CNI 等&#xff0c;将这些接口抽象出来&#xff0c;是为了更好的提供开放、扩展、规范等能力。 K8s CRI(Container Runtime Interface) 是 K8s 定义的一组与容器运行时进行交…

八种单例模式

文章目录 1.单例模式基本介绍1.介绍2.单例模式八种方式 2.饿汉式&#xff08;静态常量&#xff0c;推荐&#xff09;1.基本步骤1.构造器私有化&#xff08;防止new&#xff09;2.类的内部创建对象3.向外暴露一个静态的公共方法 2.代码实现3.优缺点分析 3.饿汉式&#xff08;静态…

C#基础语言

​​​​ 目录 一个c# 程序主要包括以下部分&#xff1a;​​​​​​​ 标识符 C# 关键字 C# 数据类型 值类型&#xff08;Value types&#xff09; 引用类型&#xff08;Reference types&#xff09; 对象&#xff08;Object&#xff09;类型 动态&#xff08;Dynam…

Python应用实战,用动画生成冒泡排序的过程

写在前言 hello&#xff0c;大家好&#xff0c;我是一点&#xff0c;专注于Python编程&#xff0c;如果你也对感Python感兴趣&#xff0c;欢迎关注交流。 希望可以持续更新一些有意思的文章&#xff0c;如果觉得还不错&#xff0c;欢迎点赞关注&#xff0c;有啥想说的&#x…