写在开始前---权限管理设计

权限分为功能权限,数据权限。所谓功能权限,用户可以看见并操作哪些功能,比如某菜单项,某下载按钮等。数据权限,则更复杂,包括可以看见或操作哪些范围内的数据。

 

功能权限

现下解决方案很多,比如常用的rbac。根据系统规模和用户数量,可以自由裁剪灵活使用。用户,角色/身份,权限,自由配置。我们后台系统用户较少,我就使用了用户,权限,用户权限,基本不怎么变动。

权限包括菜单啊,页面上的按钮啊啥的,可以把每一项产生url请求的都认为是操作权限,将url路由配置在数据库里,按照模块或页面归类,并分配到具体的用户或角色。使用的时候,再校验。

 

数据权限

首先需要归类,有哪些用户,有哪些功能页面,有哪些资源,针对资源有哪些规则。这个规则很复杂。设计复杂,使用复杂,随着时间及系统的使用会越来越复杂。

某用户已被赋予某种角色或身份,登录系统后,能看到哪些功能,是固定的。在某项功能下面,还需要规定能看到哪些数据。不是自己能看的,就不能看到。这是数据范围。

用户在前端选择自定义的搜索条件,后系统内部,还要加上数据范围的条件,合在一起,查出有效范围符合条件的数据。

这里的难点,怎么把搜索条件和数据范围条件融合合并一起!

 


 

 

 

简单的翻了翻spring(Shiro)和tp6一些项目的菜单权限配置及权限验证相关模块。

 

菜单按钮

基本步骤是根据系统结构设置目录,根据模块功能设置相应下属菜单及菜单页对应的按钮。把这些分类加入数据库保存,有id,pid,name,url,权限标记等。

给角色分配权限就是将系统内已配置好的目录菜单按钮按照树型结构显示出来,根据实际选中相关项,将按钮作为叶节点,和上层菜单目录id一起存入角色权限表。查看编辑的时候再原路返回显示。

 

 

权限控制

要么在基类控制器那里统一鉴权,要么在每个控制器或action里鉴权。前者省事整齐划一,后者灵活繁琐。

统一鉴权一般使用的是将controller和action结合,然后再与数据库的权限标记比对,这里也可以不设置标记,统一设置url,控制器获取request的url再直接与配置的url比对。

在每个控制器或action分别鉴权,则是每个action有配置的权限标记,request到来时判断角色权限里是否分配有这个标记。

 

数据权限

数据权限按说是最复杂的,每个社会或行业自有国情在。公司结构复杂,跨子公司,跨部门,跨业务。

1、 '全部数据权限'
2、'本部门及以下数据权限',
3、 '本部门数据权限',
4、 '自定数据权限',
5、 '仅本人数据权限'

每个权限对应不同范围数据,除了这种按照部门划分数据权限,其实还有地域性,行业性等其他属性,比如A能看这个省市的,B能看另一省市的。

按照部门划分,则企业内部人员必然以总体-部门-人员的结构建档再分划归档,衍生出部门,部门人员,头衔职位职称等表。根据所在部门及头衔职位职称来判断数据的权限。

粒度的大小粗细根据实际情况。

总体是在常规的查询后面拼接特定范围的sql,做范围数据过滤。

复制代码
未过滤之前sql:
select u.user_id, u.dept_id, u.login_name, u.user_name, u.email , u.phonenumber, u.password, u.sex, u.avatar, u.salt , u.status, u.del_flag, u.login_ip, u.login_date, u.create_by , u.create_time, u.remark, d.dept_name from sys_user u left join sys_dept d on u.dept_id = d.dept_id where u.del_flag = '0'
复制代码
复制代码
过滤之后的sql:
select u.user_id, u.dept_id, u.login_name, u.user_name, u.email
    , u.phonenumber, u.password, u.sex, u.avatar, u.salt
    , u.status, u.del_flag, u.login_ip, u.login_date, u.create_by
    , u.create_time, u.remark, d.dept_name
from sys_user u
    left join sys_dept d on u.dept_id = d.dept_id
where u.del_flag = '0'
    and u.dept_id in (
        select dept_id
        from sys_role_dept
        where role_id = 2
    )
复制代码

(以上sql来自ruoyi)

posted @ 2022-06-24 13:21  love/coder  阅读(58)  评论(0编辑  收藏  举报