最完整RuoYi+Shiro安全实战:从登录到权限控制全解析
你是否还在为Java权限系统集成Shiro框架而头疼?配置复杂、认证流程混乱、权限颗粒度难以控制?本文将带你零门槛掌握RuoYi框架与Shiro安全认证的深度集成方案,从核心原理到实战配置,让你1小时内搭建企业级安全防护体系。
读完本文你将获得:
- 3分钟理解Shiro在RuoYi中的架构设计
- 5步完成自定义Realm认证流程开发
- 10个核心配置项优化系统安全性
- 完整的权限控制实战案例(含代码模板)
Shiro安全框架在RuoYi中的架构设计
RuoYi作为基于SpringBoot的权限管理系统,其安全核心采用Shiro框架实现身份认证与授权控制。系统通过分层设计实现安全逻辑解耦,主要包含三大核心组件:
graph TD
A[认证层] -->|UsernamePasswordToken| B[UserRealm]
B --> C{授权层}
C --> D[角色权限管理]
C --> E[菜单权限过滤]
B --> F[会话管理层]
F --> G[OnlineSessionDAO]
F --> H[KickoutSessionFilter]
核心实现模块分布在以下路径:
- 认证核心:UserRealm.java
- 配置中心:ShiroConfig.java
- 登录服务:SysLoginService.java
- 会话管理:OnlineWebSessionManager.java
登录认证流程深度解析
RuoYi的认证流程采用"控制器-服务层-Realm"三级架构,确保安全逻辑与业务逻辑分离。以下是用户登录时的核心执行链路:
1. 前端请求处理
用户提交登录表单后,请求首先到达SysLoginController.java,控制器调用login方法处理认证请求:
@PostMapping("/login")
public AjaxResult login(String username, String password, String code, Boolean rememberMe) {
// 验证码校验
validateCaptcha(username, code);
// 调用Shiro登录
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
subject.login(token);
return success();
}
2. 认证逻辑处理
Shiro框架将认证请求转发至自定义Realm的doGetAuthenticationInfo方法:
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
String password = new String(upToken.getPassword());
SysUser user = loginService.login(username, password);
return new SimpleAuthenticationInfo(user, password, getName());
}
3. 安全校验流程
在SysLoginService.java中实现了7层安全校验:
| 校验类型 | 实现代码 | 安全作用 |
|---|---|---|
| 验证码校验 | if (ShiroConstants.CAPTCHA_ERROR.equals(...)) |
防止机器人攻击 |
| 用户名格式校验 | username.length() < UserConstants.USERNAME_MIN_LENGTH |
过滤非法输入 |
| 密码强度校验 | password.length() < UserConstants.PASSWORD_MIN_LENGTH |
强制密码复杂度 |
| IP黑名单校验 | IpUtils.isMatchedIp(blackStr, ShiroUtils.getIp()) |
拦截恶意IP |
| 用户状态校验 | UserStatus.DELETED.getCode().equals(user.getDelFlag()) |
防止已删除用户登录 |
| 密码加密校验 | passwordService.validate(user, password) |
验证密码哈希值 |
| 会话并发控制 | KickoutSessionFilter |
限制多设备登录 |
权限控制核心实现
RuoYi采用"基于角色的访问控制"(RBAC)模型,通过Shiro的授权机制实现细粒度权限管理。核心实现包含两大维度:
1. 基于注解的权限控制
系统通过@RequiresPermissions注解实现方法级权限控制,例如用户管理控制器:
@RequiresPermissions("system:user:list")
@GetMapping("/list")
public TableDataInfo list(SysUser user) {
startPage();
List<SysUser> list = userService.selectUserList(user);
return getDataTable(list);
}
2. 基于URL的权限过滤
在ShiroConfig.java中配置URL拦截规则:
filterChainDefinitionMap.put("/login", "anon,captchaValidate");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/system/user/**", "perms[system:user:***]");
filterChainDefinitionMap.put("/**", "user,kickout,onlineSession,syncOnlineSession");
权限字符串采用"模块:功能:操作"三级结构,如system:user:add表示用户管理模块的添加权限。
会话管理与安全防护
RuoYi扩展了Shiro的会话管理功能,实现企业级安全特性,主要包括:
1. 会话并发控制
通过KickoutSessionFilter实现同账号多设备登录限制,核心配置:
@Bean
public KickoutSessionFilter kickoutSessionFilter() {
KickoutSessionFilter filter = new KickoutSessionFilter();
filter.setMaxSession(2); // 最多允许2台设备同时登录
filter.setKickoutAfter(false); // 后登录用户踢出先登录用户
filter.setKickoutUrl("/login?kickout=1");
return filter;
}
2. 会话状态监控
系统通过OnlineSessionDAO实现会话的持久化与监控,管理员可在后台查看在线用户列表并强制下线:
public void deleteOnlineById(String sessionId) {
SysUserOnline online = selectOnlineById(sessionId);
if (online == null) {
return;
}
online.setStatus(OnlineStatus.off_line);
onlineSessionDAO.delete(online.getSessionId());
}
3. 安全配置优化
以下关键配置项可显著提升系统安全性,配置文件路径:application.yml
| 配置项 | 建议值 | 安全作用 |
|---|---|---|
| shiro.session.expireTime | 30 | 会话超时时间(分钟) |
| shiro.user.captchaEnabled | true | 启用登录验证码 |
| shiro.cookie.httpOnly | true | 防止JS获取Cookie |
| shiro.cookie.secure | true | 仅HTTPS传输Cookie |
| csrf.enabled | true | 启用CSRF防护 |
实战:自定义权限认证开发
以下是扩展RuoYi权限功能的完整步骤,以实现数据权限隔离为例:
1. 创建自定义Realm方法
在UserRealm.java中添加数据权限过滤:
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SysUser user = ShiroUtils.getSysUser();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 添加数据权限
info.addStringPermission("dataScope:" + user.getDeptId());
return info;
}
2. 配置权限注解
在Service方法上添加数据权限注解:
@DataScope(deptAlias = "d")
public List<SysUser> selectUserList(SysUser user) {
return userMapper.selectUserList(user);
}
3. 实现权限拦截器
创建数据权限拦截器DataScopeInterceptor.java,拦截SQL执行并添加权限条件。
总结与最佳实践
RuoYi框架通过Shiro的深度定制,构建了完整的安全体系。在实际项目中,建议:
- 权限设计:采用"粗粒度角色+细粒度权限"的混合模型
- 安全审计:启用SysOperLog记录关键操作
- 定期更新:关注官方文档的安全更新建议
- 性能优化:通过Ehcache缓存权限数据,配置文件:ehcache-shiro.xml
通过本文介绍的方法,你可以快速掌握RuoYi与Shiro的集成技术,构建安全可靠的企业级应用。更多高级特性请参考RuoYi官方文档及源代码实现。
立即行动:
- Star收藏项目仓库:https://gitcode.com/yangzongzhuan/RuoYi
- 关注作者获取更多实战教程
- 留言分享你的权限系统设计经验
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0152- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
LongCat-Video-Avatar-1.5最新开源LongCat-Video-Avatar 1.5 版本,这是一款经过升级的开源框架,专注于音频驱动人物视频生成的极致实证优化与生产级就绪能力。该版本在 LongCat-Video 基础模型之上构建,可生成高度稳定的商用级虚拟人视频,支持音频-文本转视频(AT2V)、音频-文本-图像转视频(ATI2V)以及视频续播等原生任务,并能无缝兼容单流与多流音频输入。00
auto-devAutoDev 是一个 AI 驱动的辅助编程插件。AutoDev 支持一键生成测试、代码、提交信息等,还能够与您的需求管理系统(例如Jira、Trello、Github Issue 等)直接对接。 在IDE 中,您只需简单点击,AutoDev 会根据您的需求自动为您生成代码。Kotlin03
Intern-S2-PreviewIntern-S2-Preview,这是一款高效的350亿参数科学多模态基础模型。除了常规的参数与数据规模扩展外,Intern-S2-Preview探索了任务扩展:通过提升科学任务的难度、多样性与覆盖范围,进一步释放模型能力。Python00
skillhubopenJiuwen 生态的 Skill 托管与分发开源方案,支持自建与可选 ClawHub 兼容。Python0112