Shiro会话管理和加密
一、会话相关API及会话使用
Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如Web容器Tomcat),可以在JavaSE和JavaEE环境中使用。会话相关API主要包括:
Subject.getSession()
: 获取当前用户的会话,如果当前没有创建会话对象,则会创建一个新的会话。这等价于Subject.getSession(true)
。Subject.getSession(boolean create)
: 根据参数决定是否创建一个新的会话。如果create
为true
且当前没有会话,则创建一个新的会话;如果为false
且当前没有会话,则返回null
。session.setAttribute(key, value)
: 设置会话属性。session.getAttribute(key)
: 获取会话属性。session.removeAttribute(key)
: 删除会话属性。
会话使用时,建议在Controller层使用原生的HttpSession
对象,在Service层使用Shiro提供的Session
对象。
二、缓存
问题分析
在每次访问设置了权限的页面时,Shiro都会执行doGetAuthorizationInfo()
方法来获取权限信息。这可能导致性能问题,因为每次请求都需要重新计算权限。
解决办法
对权限授权数据进行缓存处理。可以使用第三方的Shiro-Redis集成Redis来实现缓存。
具体实现
- 在Shiro配置类中配置Redis缓存管理器。
- 在自定义Realm中使用缓存管理器来缓存权限信息。
- 在用户登录或权限变更时,手动清除缓存中的旧权限信息。
示例代码(Spring Boot环境):
// Shiro配置类
@Configuration
public class ShiroConfig { // ... @Bean public RedisCacheManager cacheManager(RedisManager redisManager) { RedisCacheManager cacheManager = new RedisCacheManager(); cacheManager.setRedisManager(redisManager); return cacheManager; } // ...
} // 自定义Realm
public class CustomRealm extends AuthorizingRealm { // ... @Autowired private RedisCacheManager cacheManager; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 从缓存中获取权限信息 String cacheKey = getAuthorizationCacheKey(principals); AuthorizationInfo cachedAuthInfo = (AuthorizationInfo) cacheManager.getCache("authorizationCache").get(cacheKey); if (cachedAuthInfo != null) { return cachedAuthInfo; } // 如果缓存中没有,则查询数据库并缓存结果 AuthorizationInfo authInfo = // 查询数据库获取权限信息 cacheManager.getCache("authorizationCache").put(cacheKey, authInfo); return authInfo; } // ... private String getAuthorizationCacheKey(PrincipalCollection principals) { // 生成缓存键,例如使用用户名 return principals.getPrimaryPrincipal().toString(); } // 清除缓存的方法 public void clearCachedAuthorizationInfo(PrincipalCollection principals) { String cacheKey = getAuthorizationCacheKey(principals); cacheManager.getCache("authorizationCache").remove(cacheKey); }
}
演示测试
在测试环境中,可以通过模拟用户登录和访问受保护资源来验证缓存是否生效。观察日志或调试信息,确认Shiro是否从缓存中获取了权限信息而不是每次都查询数据库。
三、加密
哈希与盐
为了增强密码的安全性,Shiro支持使用哈希算法对密码进行加密,并可以添加盐值以防止彩虹表攻击。
加密与验证
在Shiro中,可以通过配置HashedCredentialsMatcher
来实现密码的哈希加密和验证。HashedCredentialsMatcher
可以设置哈希算法(如MD5、SHA-256等)和哈希迭代次数。
具体实现
- 在Shiro配置类中配置
HashedCredentialsMatcher
。 - 在自定义Realm中使用
HashedCredentialsMatcher
进行密码验证。
示例代码:
// Shiro配置类
@Configuration
public class ShiroConfig { // ... @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5"); // 设置哈希算法 hashedCredentialsMatcher.setHashIterations(1024); // 设置哈希迭代次数 return hashedCredentialsMatcher; } @Bean public SecurityManager securityManager(CustomRealm customRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(customRealm); securityManager.setCredentialsMatcher(hashedCredentialsMatcher()); // 设置密码加密验证器 return securityManager; } // ...
} // 自定义Realm
public class CustomRealm extends AuthorizingRealm { // ... @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername(); // 查询数据库获取用户信息 User user = userService.findUserByName(username); if (user == null) { throw new UnknownAccountException("用户不存在"); } // 返回认证信息,包含用户名、密码(已加密)、盐值和Realm名称 return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName()); } // ...
}
在上面的代码中,User
类应该包含用户名、密码(已加密)、盐值等属性。在注册用户时,应该使用与HashedCredentialsMatcher
相同的哈希算法和迭代次数对密码进行加密,并将加密后的密码和盐值存储在数据库中。
四、登录次数限制
Shiro本身没有直接提供登录次数限制的功能,但可以通过自定义Realm或拦截器来实现。例如,可以在自定义Realm中维护一个登录失败次数的计数器,当登录失败次数超过一定限制时,可以锁定用户账户或增加额外的验证步骤。
实现登录次数限制的示例代码(简化版):
// 自定义Realm
public class CustomRealm extends AuthorizingRealm { // ... private Map<String, Integer> loginFailureCounts = new ConcurrentHashMap<>(); // 登录失败次数计数器 private static final int MAX_FAILURE_COUNT = 5; // 最大失败次数限制 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername(); // 检查登录失败次数是否超过限制 if (loginFailureCounts.getOrDefault(username, 0) >= MAX_FAILURE_COUNT) { throw new LockedAccountException("账户已被锁定,请稍后再试"); } // 查询数据库获取用户信息 User user = userService.findUserByName(username); if (user == null) { // 登录失败,增加失败次数计数器 loginFailureCounts.put(username, loginFailureCounts.getOrDefault(username, 0) + 1); throw new UnknownAccountException("用户不存在"); } // 验证密码(省略具体实现) // ... // 登录成功,清除失败次数计数器 loginFailureCounts.remove(username); // 返回认证信息 return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName()); } // ...
}
相关文章:
Shiro会话管理和加密
一、会话相关API及会话使用 Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如Web容器Tomcat),可以在JavaSE和JavaEE环境中使用。会话相关API主要包括: Subject.getSession(): 获取当前用户的会话࿰…...

GPON、XG-PON和XGS-PON的区别
类别GPON10G PON 细分 GPON XG-PON XGS-PON 下行速率 2.488 Gbps 9.953 Gbps 9.953Gbps 上行速率 1.244 Gbps 2.488 Gbps 9.953Gbps 可用带宽 2200Mbps 8500Mbps 8500Mbps 1000Mbps2000Mbps8500Mbps ITU-T标准 G.984(2003年) G.987 &a…...
Spring 项目返回值枚举类编写技巧
Spring 项目返回值枚举类编写技巧 在 Spring 项目中,使用枚举类来统一管理返回值和状态码是一种非常优雅的实现方式。这不仅能提升代码的可读性和维护性,还能避免在代码中硬编码字符串或数字来表示状态码。本文将以 ReturnCodeEnum 为例,介绍…...

【操作系统】06.进程控制
一、进程创建 1.1 认识fork函数 在linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。 进程调用fork,当控制转移到内核中的fork代码后,内核将 分配新的内存块和内核数据结构…...
16天自制CppServer-day02
day02-设置错误与异常处理机制 上一天我们写了一个客户端与服务器通过socket进行连接,对socket,bind,listen,accept,connect等函数,我们都设想程序完美地、没有任何异常地运行,但显然这不现实,应该设置出现异常的处理机制&#x…...

时空智友企业流程化管控系统uploadStudioFile接口存在任意文件上传漏洞
免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 时空智友…...

Linux 中文件的权限说明
目录 一:文件权限类型二:默认权限管理1. 查看当前用户的umask值2. 修改当前用户的umask值3. 根据umask计算默认权限 三:普通权限管理1. 三种普通权限说明1.1 对于非目录文件来说1.2 对于目录文件来说 2. 查看某个文件的权限信息2.1 使用 ls -…...

MySql数据库中数据类型
本篇将介绍在 MySql 中的所有数据类型,其中主要分为四类:数值类型、文本和二进制类型、时间日期、String 类型。如下(图片来源:MySQL数据库): 目录如下: 目录 数值类型 1. 整数类型 2. …...

Godot中的信号
目录 概念 signal connect方法连接Callable 信号要求参数 查看信号 连接信号 监听信号 Button - text属性 pressed 连接源 「按钮」的信号连接 使用代码,将方法与信号相连接 节点的connect方法 节点直接使用emit_signal方法通过字符串的方式触发信号…...
vba学习系列(8)--指定列单元格时间按时间段计数
系列文章目录 文章目录 系列文章目录前言一、背景二、VBA总结 前言 一、背景 时间格式:00:00:00 时间段格式:00:00:00 - 01:00:00 计数N列单元格时间位于时间段内的行数 二、VBA 代码如下(示例): Sub AssignTimeSeg…...

大型企业软件开发是什么样子的? - Web Dev Cody
引用自大型企业软件开发是什么样子的? - Web Dev Cody_哔哩哔哩_bilibili 一般来说 学技术的时候 我们会关注 开发语言特性 ,各种高级语法糖,底层技术 但是很少有关注到企业里面的开发流程,本着以终为始(以就业为导向…...

【stm32】DMA的介绍与使用
DMA的介绍与使用 1、DMA简介2、存储器映像3、DMA框图4、DMA基本结构5、DMA请求6、数据宽度与对齐7、数据转运DMA(存储器到存储器的数据转运)程序编写: 8、ADC连续扫描模式DMA循环转运DMA配置:程序编写: 1、DMA简介 DM…...

哈希表的魔力
哈希表与字典 普遍存在一种误解,认为“哈希表”和“字典”这两个术语可以互换。这种观念从根本上是不准确的,至少在计算机科学领域是如此。 字典是将键映射到值的数据结构的一般概念。而哈希表是字典的具体实现。 本质上,字典扮演着一个总体…...

《YOLO 目标检测》—— YOLO v3 详细介绍
!!!!!!!!!!!!!还未写完!!!!!!!…...

WNN 多模态整合 | Seurat 单细胞多组学整合流程
测试环境:CentOS7.9, R4.3.2, Seurat 4.4.0, SeuratObject 4.1.4 2024.10.23 # WNN library(ggplot2) library(dplyr) library(patchwork)1. 导入数据 (1). load counts of RNA and protein dyn.load(/home/wangjl/.local/lib/libhdf5_hl.so.100) library(hdf5r)…...

【Linux】磁盘文件系统(inode)、软硬链接
文章目录 1. 认识磁盘1.1 磁盘的物理结构1.2 磁盘的逻辑结构 2. 引入文件系统2.1 EXT系列文件系统的分区结构2.2 inode 3. 软硬链接3.1 软链接3.2 硬链接 在讲过了内存文件系统后,我们可以知道文件分为两种: 打开的文件(内存中)未…...

网安加·百家讲坛 | 徐一丁:金融机构网络安全合规浅析
作者简介:徐一丁,北京小西牛等保软件有限公司解决方案部总监,网络安全高级顾问。2000年开始从事网络安全工作,主要领域为网络安全法规标准研究、金融行业安全咨询与解决方案设计、信息科技风险管理评估等。对国家网络安全法规标准…...

九、pico+Unity交互开发——触碰抓取
一、VR交互的类型 Hover(悬停) 定义:发起交互的对象停留在可交互对象的交互区域。例如,当手触摸到物品表面(可交互区域)时,视为触发了Hover。 Grab(抓取) 概念ÿ…...

老机MicroServer Gen8再玩 OCP万兆光口+IT直通
手上有一台放了很久的GEN8微型服务器,放了很多年,具体什么时候买的我居然已经记不清了 只记得开始装修的时候搬家出去就没用了,结果搬出去有了第1个孩子,孩子小的时候也没时间折腾,等孩子大一点的时候,又有…...

jmeter 从多个固定字符串中随机取一个值的方法
1、先新增用户参数,将固定值设置为不同的变量 2、使用下面的函数,调用这写变量 ${__RandomFromMultipleVars(noticeType1|noticeType2|noticeType3|noticeType4|noticeType5)} 3、每次请求就是随机取的值了...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...