首页
/ 最完整RuoYi+Shiro安全实战:从登录到权限控制全解析

最完整RuoYi+Shiro安全实战:从登录到权限控制全解析

2026-02-04 04:40:34作者:廉彬冶Miranda

你是否还在为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]

核心实现模块分布在以下路径:

登录认证流程深度解析

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的深度定制,构建了完整的安全体系。在实际项目中,建议:

  1. 权限设计:采用"粗粒度角色+细粒度权限"的混合模型
  2. 安全审计:启用SysOperLog记录关键操作
  3. 定期更新:关注官方文档的安全更新建议
  4. 性能优化:通过Ehcache缓存权限数据,配置文件:ehcache-shiro.xml

通过本文介绍的方法,你可以快速掌握RuoYi与Shiro的集成技术,构建安全可靠的企业级应用。更多高级特性请参考RuoYi官方文档及源代码实现。

立即行动

  • Star收藏项目仓库:https://gitcode.com/yangzongzhuan/RuoYi
  • 关注作者获取更多实战教程
  • 留言分享你的权限系统设计经验
登录后查看全文
热门项目推荐
相关项目推荐