最近在研究权限功能,想要开发一套通用的权限模型。
主要包含了功能权限和数据权限两种。其实功能权限分为模块权限、页面权限、操作权限这三类加上数据权限就一共是四类了。
功能权限和包含的模块权限、页面权限、操作权限采用统一RBAC设计或者再引入一些角色组、用户组、权限组等分类概念就可以完美的实现了。能够应对小型系统或者大型的人员数量很多的系统。
但是数据权限是一个难点(这里只考虑数据行,而不考虑数据列能否查看的问题,这个以后再讨论),数据权限的分类是相对容易的,我认为一般的数据权限层级都可以使用树状图来呈现。但是难点在于查询数据的时候或者操作数据的时候的数据查询或者筛选。
关于部门层级可能会存在下列情况:
数据权限可能存在以下情况:
1、查看本一级及以下等级的所有内容的权限
2、查看单一等级的权限
3、查看跨部门等级的权限
4、查看本人的权限
5、动态增加等级的权限
*一个人隶属于多个部门的情况如何处理?
关于数据查询我个人认为可能有以下几种实现方式。
解决方案:
1、方法重载:
根据权限分类抽象管理员角色
针对不同的角色进行数据方法的重载
根据当前角色调用相应的数据方法获取数据
最终将数据进行合并然后去重
实现方式:service层进行切面,调用接口时分配到不同的方法,然后汇总返回
优点:单表查询或者连表查询,速度较快
缺点:代码随着层级的增加持续增加,无法适应层级的动态增添
2、数据sql拼接查询
数据表的每一张表中均存储等级标识字段
获取当前用户的所有等级
根据获取的所有等级查询数据库表,拼接sql执行查询。例如 in (1,2,3)
实现方式:
每张数据库表存 等级 字段
mybatis interceptor拦截器,将sql进行一轮select * from ( 原始sql ) where auth in ( 等级逗号拼接) 进行查询。
或者
相关查询service层方法上添加注解,使用切面来生成拼接sql,结合mybatis的apply方法进行sql拼接
优点:能够一次执行,获取到数据权限列表下的所有数据
缺点:使用 in 可能会影响效率 ,权限和数据耦合性很高,需要权限控制的表就要设置插入部门或用户组字段。
而却权限需要和部门或者用户组进行耦合。插入数据时需要明确当前操作是哪个部门或用户组的用户,将相应的部门或用户组外键插入到表中。
毕竟部门或者用户组并不是业务数据的相关数据,只有用户才是,增加了这个字段从数据建模上将有问题。
如果建立索引增加in的效率就有可能需要建立联合索引(如果多个索引可能会出现合并索引的情况或者索引失效的情况)这对sql优化可能是灾难。
3、数据筛选
将所有相关的数据查询出来
然后获取当前用户的所有等级情况
然后根据规则进行数据筛选,将相关的数据筛选出来。
优点:可以搭配规则引擎进行数据筛选。单表查询速度快。
缺点:
以空间换时间
大数据量情况下对存储和检索是一种负担,
需要搭配缓存,从缓存中获取数据,对硬件的要求提高。需要数据筛选搭配规则引擎硬编码
或者
不使用缓存和程序数据筛选,数据全量同步到搜索引擎中,改用搭配规则引擎(例如Drools)和搜索引擎(例如es),从搜索引擎中快速检索,
但这增加了多条搜索的可能性,可能会涉及多次搜索。架构复杂。程序员编码和配置的要求也比较高
关于数据权限的实现目前还没有开始,只是想到是否可以使用这三种方式的一种进行实现。我个人感觉还是第二种sql拼接查询的情况会更好,实现难度也低。
关于数据权限的实现,能否有其他更好的方式才是未来探索的方向,还请大佬能为小弟指点迷津,指出现阶段您所知的更好的方法,不吝赐教。谢谢啦