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;}
}
相关文章:

java 拦截器-用户无操作超时退出利用Redis
1、授权过滤,只要实现AuthConfigAdapter接口 2、利用Redis token超时时间,用户访问后台续时 效果 Component public class AuthFilter implements Filter {private static Logger logger LoggerFactory.getLogger(AuthFilter.class);Autowiredprivat…...

民国漫画杂志《时代漫画》第16期.PDF
时代漫画16.PDF: https://url03.ctfile.com/f/1779803-1248612470-6a05f0?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了,截止1937年6月战争来临被迫停刊共发行了39期。 ps:资源来源网络!...
线程池以及日志类的实现
目录 线程池: 日志类: 可变参数以及相关函数 1.va_list 2. va_start 3. va_end 日志Log类 线程池 线程池: 是一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行…...

基于长短期记忆网络 LSTM 的送餐时间预测
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对…...

K-means聚类算法详细介绍
目录 🍉简介 🍈K-means聚类模型详解 🍈K-means聚类的基本原理 🍈K-means聚类的算法步骤 🍈K-means聚类的优缺点 🍍优点 🍍缺点 🍈K-means聚类的应用场景 🍈K-mea…...

SAP FS00如何导出会计总账科目表
输入T-code : S_ALR_87012333 根据‘FS00’中找到的总账科目,进行筛选执行 点击左上角的列表菜单,选择‘电子表格’导出即可...

ROS参数服务器
一、介绍 参数服务器是用于存储和检索参数的分布式多机器人配置系统,它允许节点动态地获取参数值。 在ROS中,参数服务器是一种用于存储和检索参数的分布式多机器人配置系统。它允许节点动态地获取参数值,并提供了一种方便的方式来管理和共享配…...
QCC---DFU升级变更设备名和地址
QCC---DFU升级变更设备名和地址 这个很多人碰到这个疑问,升级了改不了设备名和地址 /******************************************************************************* Copyright (c) 2018 Qualcomm Technologies International, Ltd. FILE NAME sink_dfu_ps.c DESCRIPT…...
[力扣题解] 695. 岛屿的最大面积
题目:695. 岛屿的最大面积 思路 代码 深度优先搜索 // 深度搜索 class Solution { private:int area_max 0;int dir[4][2] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};void dfs(vector<vector<int>>& grid, vector<vector<bool>>& …...
AI模型发展路径探析:开源与闭源,何者更胜一筹?
AI模型发展路径探析:开源与闭源,何者更胜一筹? 在当今快速发展的人工智能领域,AI模型成为推动技术创新和应用落地的关键。而评价一个AI模型“好不好”“有没有发展”,往往会引向一个重要话题:开源与闭源这…...

concurrency 并行编程
Goroutine go语言的魅力所在,高并发。 线程是操作系统调度的一种执行路径,用于在处理器执行我们在函数中编写的代码。一个进程从一个线程开始,即主线程,当该线程终止时,进程终止。这是因为主线程是应用程序的原点。然后…...
JavaScript如何让一个按钮的点击事件在完成之前禁用
在JavaScript中,要禁用一个按钮的点击事件直到某个操作完成,你可以将其点击事件用匿名函数的方式书写。 你可以将其在点击函数内设置为null来禁用按钮。 <button id"butto_n">点击抽奖</button><script>butto_n.onclick bu…...

透视App投放效果,Xinstall助力精准分析,让每一分投入都物超所值!
在移动互联网时代,App的推广与投放成为了每一个开发者和广告主必须面对的问题。然而,如何精准地掌握投放效果,让每一分投入都物超所值,却是一个令人头疼的难题。今天,我们就来谈谈如何通过Xinstall这个专业的App全渠道…...

【Linux杂货铺】进程通信
目录 🌈 前言🌈 📁 通信概念 📁 通信发展阶段 📁 通信方式 📁 管道(匿名管道) 📂 接口 编辑📂 使用fork来共享通道 📂 管道读写规则 &…...

常用API(正则表达式、爬取、捕获分组和非捕获分组 )
1、正则表达式 练习——先爽一下正则表达式 正则表达式可以校验字符串是否满足一定的规则,并用来校验数据格式的合法性。 需求:假如现在要求校验一个qq号码是否正确。 规则:6位及20位之内,0不能在开头,必须全部是数字…...

JVM学习-Class文件结构②
访问标识(access_flag) 在常量池后,紧跟着访问标记,标记使用两个字节表示,用于识别一些类或接口层次的访问信息,包括这个Class是类还是接口,是否定义为public类型,是否定义为abstract类型,如果…...
数据库连接项目
MySQL...

MySQL--InnoDB体系结构
目录 一、物理存储结构 二、表空间 1.数据表空间介绍 2.数据表空间迁移 3.共享表空间 4.临时表空间 5.undo表空间 三、InnoDB内存结构 1.innodb_buffer_pool 2.innodb_log_buffer 四、InnoDB 8.0结构图例 五、InnoDB重要参数 1.redo log刷新磁盘策略 2.刷盘方式&…...
ffplay 使用文档介绍
ffplay ffplay 是一个简单的媒体播放器,它是 FFmpeg 项目的一部分。FFmpeg 是一个广泛使用的多媒体框架,能够解码、编码、转码、复用、解复用、流化、过滤和播放几乎所有类型的媒体文件。 ffplay 主要用于测试和调试,因为它提供了一个命令行界面,可以方便地查看媒体文件的…...

四种网络IO模型
📝个人主页:五敷有你 🔥系列专栏:面经 ⛺️稳中求进,晒太阳 IO的定义 IO是计算机内存与外部设备之间拷贝数据的过程。CPU访问内存的速度远高于外部设备。因此CPU是先把外部设备的数据读取到内存,在…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

Linux入门(十五)安装java安装tomcat安装dotnet安装mysql
安装java yum install java-17-openjdk-devel查找安装地址 update-alternatives --config java设置环境变量 vi /etc/profile #在文档后面追加 JAVA_HOME"通过查找安装地址命令显示的路径" #注意一定要加$PATH不然路径就只剩下新加的路径了,系统很多命…...