当前位置: 首页 > article >正文

SpringBoot+Shirp的权限管理

目录

怎么实现动态菜单

1.html页面

2.获取动态菜单

Shiro权限刷新

1. 配置Shiro

2. 创建权限刷新服务

3. 调用权限刷新服务

注意事项

如何更新ShiroFilter初始权限


怎么实现动态菜单

1.html页面

 <ul class="nav side-menu">
                    <!--第一重循环,循环32次,有6条满足-->
                    <li th:if="${right1.rightType=='Folder'}" th:each="right1:${session.loginUser.role.rights}">
                        <a>
                            <i class="fa fa-home"></i>  <span th:text="${right1.rightText}">一级菜单</span>
                            <span class="fa fa-chevron-down"></span>
                        </a>
                        <ul class="nav child_menu">
                            <li th:if="${right2.rightType=='Document' && right2.rightParentCode==right1.rightCode}" th:each="right2:${session.loginUser.role.rights}">
                                <a th:href="@{${right2.rightUrl}}" href="javascript:;" th:text="${right2.rightText}">二级菜单</a>
                            </li>
                        </ul>
                    </li>
                </ul>

2.获取动态菜单

 // 获得权限信息
        User user = (User) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 动态授权:从数据库中获取角色和权限
        Role role = user.getRole();
        if (role != null) {
            info.addRole(role.getRoleName()); // 动态设置角色
            Set<Right> rights = role.getRights();
            if (rights != null && !rights.isEmpty()) {
                for (Right right : rights) {
                    info.addStringPermission(right.getRightCode()); // 动态设置权限
                }
            }
        }

Shiro权限刷新

在Spring Boot项目中,使用Apache Shiro进行权限管理时,实现权限刷新通常涉及以下几个步骤:

  1. 理解权限刷新需求
    • 权限刷新通常意味着用户的权限在运行时发生了变化,需要更新Shiro中的安全上下文,以确保后续访问控制能够反映最新的权限状态。
  2. 更新权限数据
    • 首先,确保你的权限数据(如角色、权限等)在数据库中或某个持久化存储中是可以动态更新的。
  3. 重新加载权限
    • 当权限数据发生变化时,你需要一种机制来重新加载用户的权限信息。这通常涉及从数据库或其他数据源重新获取权限数据,并更新Shiro的Subject对象。
  4. 实现权限刷新逻辑
    • 你可以通过编写一个服务类来处理权限刷新逻辑。这个服务类将负责从数据源获取最新的权限信息,并调用Shiro的API来更新当前用户的权限。

以下是一个简单的示例,展示了如何在Spring Boot Shiro项目中实现权限刷新:

1. 配置Shiro

确保你已经正确配置了Shiro,包括Realm、CacheManager等。

2. 创建权限刷新服务

import org.apache.shiro.SecurityUtils;  
import org.apache.shiro.mgt.SecurityManager;  
import org.apache.shiro.subject.Subject;  
import org.apache.shiro.subject.PrincipalCollection;  
import org.apache.shiro.realm.AuthorizingRealm;  
import org.apache.shiro.authz.AuthorizationInfo;  
import org.apache.shiro.authz.SimpleAuthorizationInfo;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Service;  
  
import java.util.Set;  
  
@Service  
public class PermissionRefreshService {  
  
    @Autowired  
    private UserService userService; // 假设你有一个UserService来管理用户信息  
  
    @Autowired  
    private AuthorizingRealm realm; // 你的Shiro Realm实现  
  
    public void refreshPermissions(Long userId) {  
        // 获取当前Subject  
        Subject currentUser = SecurityUtils.getSubject();  
  
        // 假设你的Realm使用用户名作为Principal  
        String username = getCurrentUsername(currentUser);  
  
        // 从数据库或其他数据源获取最新的权限信息  
        Set<String> roles = userService.getRolesByUserId(userId);  
        Set<String> permissions = userService.getPermissionsByUserId(userId);  
  
        // 创建AuthorizationInfo对象并设置权限和角色  
        AuthorizationInfo authInfo = new SimpleAuthorizationInfo();  
        authInfo.setRoles(roles);  
        authInfo.setStringPermissions(permissions);  
  
        // 更新Realm中的权限信息  
        realm.doClearCache(PrincipalCollection.fromRealmNames(username));  
        realm.init(); // 这一步可能不是必需的,取决于你的Realm实现  
  
        // 触发Shiro重新加载权限(这一步通常通过清除缓存和访问控制检查自动完成)  
        // 你也可以手动调用某些Shiro API来确保权限被重新加载,但这通常不是必需的  
  
        // 注意:在某些情况下,你可能需要让用户重新登录或重新认证以刷新权限  
        // 这可以通过注销当前用户并立即重新登录来实现  
        // currentUser.logout(); // 注销用户  
        // 然后重定向到登录页面或自动登录(取决于你的需求)  
    }  
  
    private String getCurrentUsername(Subject subject) {  
        // 根据你的Principal类型获取用户名  
        // 这里假设Principal是一个String类型的用户名  
        return (String) subject.getPrincipal();  
    }  
}

3. 调用权限刷新服务

在你的业务逻辑中,当用户的权限发生变化时,调用PermissionRefreshServicerefreshPermissions方法来刷新权限。

注意事项

  • 缓存:Shiro使用缓存来存储权限信息以提高性能。因此,在权限发生变化时,你需要确保Shiro的缓存被正确清除。
  • 线程安全:在多线程环境中,确保对共享资源的访问是线程安全的。
  • 重新认证:在某些情况下,你可能需要让用户重新登录以刷新其会话和权限信息。这取决于你的具体需求和实现。
  • 性能:频繁地刷新权限可能会影响性能。因此,请确保只在必要时刷新权限,并优化你的数据源访问和缓存策略。

通过以上步骤,你可以在Spring Boot Shiro项目中实现权限刷新功能。

如何更新ShiroFilter初始权限

在Shiro框架中,ShiroFilter是用于执行URL级别的访问控制的组件。一旦ShiroFilter被初始化,并且根据配置(如shiroFilterFactoryBean)设置了初始的权限规则,这些规则在运行时是静态的,即它们不会自动更新以反映用户权限的变化。

然而,有几种方法可以在运行时更新ShiroFilter的权限规则:

  1. 重新初始化ShiroFilter
    这种方法涉及到销毁当前的ShiroFilter实例,并根据新的权限规则重新创建一个。这通常不是推荐的做法,因为它涉及到复杂的上下文管理和可能的会话丢失。

  2. 使用动态代理或AOP
    可以通过动态代理或AOP(面向切面编程)来拦截对ShiroFilter的访问控制检查,并在检查之前动态地应用新的权限规则。这种方法需要深入理解Shiro的内部机制和Java的动态代理技术。

  3. 清除缓存并重新加载权限
    当用户的权限发生变化时,可以清除Shiro的缓存(特别是授权缓存),并触发Shiro重新加载用户的权限信息。这通常是通过调用Realm的doClearCache方法来实现的。然后,当Shiro需要再次检查权限时,它会从Realm中重新加载这些信息。

  4. 自定义Filter或Advice
    可以创建一个自定义的Shiro Filter或Spring AOP Advice,在每次访问控制检查之前检查权限是否已过期或需要刷新。如果需要,可以在此时从数据源重新加载权限并更新Shiro的上下文。

  5. 使用Shiro的WebSubject.checkPermission
    在控制器或服务层中,而不是依赖ShiroFilter的URL映射,可以显式地调用WebSubject.checkPermission来检查权限。这种方法更加灵活,因为它允许你在业务逻辑的任何地方进行权限检查,并可以根据需要动态地应用新的权限规则。

  6. 重新登录
    虽然这不是更新ShiroFilter权限的直接方法,但在某些情况下,让用户重新登录可能是最简单的解决方案。重新登录会触发一个新的会话创建,并根据最新的用户信息加载权限。

在实际应用中,最常用和推荐的方法是清除缓存并重新加载权限(方法3),以及使用自定义的权限检查逻辑(方法5)。这些方法既灵活又相对简单,能够很好地适应大多数权限动态变化的场景。

请注意,无论选择哪种方法,都需要确保在权限更新过程中系统的安全性和一致性。例如,在清除缓存之前,可能需要确保没有其他并发操作正在使用旧的权限信息。


http://www.kler.cn/a/380259.html

相关文章:

  • Python 条件语句
  • Java之包,抽象类,接口
  • 【算法】【优选算法】双指针(下)
  • 【折腾一上午】Java POI 导出 Excel 自适应列宽行高
  • 云轴科技ZStack在CID大会上分享VF网卡热迁移技术
  • Echarts环形图引线设置
  • 云专线优势有哪些?对接入网络有什么要求?
  • Vue3 keep-alive核心源码的解析
  • C++ | Leetcode C++题解之第537题复数乘法
  • 麦麦Docker笔记(一)
  • masm汇编字符输入输出演示
  • 数字身份发展趋势前瞻:去中心化身份
  • OpenCV图像预处理1
  • RuleAlign 规则对齐框架:将医生的诊断规则形式化并注入模型,无需额外人工标注的自动对齐方法
  • Vue Composition API 有哪些常用的 API?
  • CentOS 磁盘扩容
  • 浅谈串口服务器的作用
  • 非线性数据结构之图
  • ICT网络赛道安全考点知识总结5
  • 低代码架构浅析
  • 第七篇: BigQuery中的复杂SQL查询
  • fpga 常量无法改变
  • mybatis源码解析-sql执行流程
  • @Excel若依导出异常/解决BusinessBaseEntity里面的字段不支持导出
  • 数据结构与算法——Java实现 52.力扣98题——验证二叉搜索树
  • MySQL45讲 第十四讲 count(*)这么慢,我该怎么办?