jeesite(jeeplus)使用Shiro解决按实例分配资源权限问题

本文运行环境:jeeplus 2.6 等效于jeesite 1.2.7

还是我现在重做的项目管理系统(PM)的项目,遇到这样一个需求,除了传统的RBAC以外,对管理的项目Project还能够对其中的个别模块进行单独授权,比如某个人,没有管理项目的相应角色,但是针对某个项目,可以临时赋予其针对某个项目的角色,该角色拥有的权限只能在该项目生效。

目前公司里大致思路是全部抛开shiro的权限控制,自己写表来记录,写一个权限基类,再继承出子类,最后再在每个Controller里加@ModelAttribute拦截,在需要判断权限的模块的所有请求参数中附带上projectId,再去后台查找,如果没有权限抛出错误,在前台判断则用el表达式取变量值进行判断。在使用过程中,感觉到极其繁琐,于是业余琢磨别的方式。包括路径拦截,AOP等不一一赘述。经过查阅文档,发现shiro原生是可以支持的。 见参考文献中的5、实例级别的权限

在本项目中:匹配字符串为  模块:子模块:操作:实例ID(项目ID) ,其中前3段为原有权限,已定义在menu里

下面是实现过程:

  1. 授予角色的过程:新建一个表,起名为 prj_role_user ,其中包含 project_id ,role_id,user_id。每条记录代表在某个项目中,授予user某个角色。这里,为了节省开发成本,不单独写角色表,统一存放在原有角色表中,为了区分,我把角色的英文名前缀 改为project开头,建立角色时,只授予其单个项目的权限。
  2. 查找权限:通过关联查询,去menu中读取权限,权限字符串定义在里面 
     select project_id,user_id,permission FROM  bd_prj_role_user as a
    
    join sys_role r on  a.role_id =r.id
    
    join sys_role_menu rm on rm.role_id = r.id
    
    join sys_menu m on m.id = rm.menu_id
    
    join sys_user u on u.id = a.user_id
    
    WHERE r.del_flag='0' and m.del_flag='0' and u.del_flag='0' and r.useable='1' and permission!=''
    
    and user_id = ${userId}
  3. 拼接字符串并授权,将上述sql查询结果中的permission跟project_id拼接成字符串list,在SystemAuthorizingRealm中 找到覆盖的 doGetAuthorizationInfo方法,赋给SimpleAuthorizationInfo。
    for (String permission : userProjectPermissionList) {
                 info.addStringPermission(permission);
             }
  4. 调用方法:不能通过注解,因为无法引入projectId这个变量,改用
    SecurityUtils.getSubject().checkPermission("basic:project:view:"+project.getId());

    在前台调用时,可以在shiro标签内加el表达式拼接权限字符串。

参考资料 张开涛:《跟我学Shiro》第三章:授权

http://jinnianshilongnian.iteye.com/blog/2020017

猜你喜欢

转载自my.oschina.net/u/2351812/blog/1789637
今日推荐