几乎每一个软件系统都涉及到权限设计,权限控制又分为功能权限控制和数据范围权限控制。toC的软件权限控制一般都是根据用户画像(特征数据)来控制的,即使有部分可以配置也相对比较简单。toB的系统一般都需要灵活的配置,功能权限配置也有RBAC(Role-Based Access Control)这样的标准,数据范围权限控制就没有这样的标准的解决方案了。
常见的数据范围权限控制方案
常见的一种数据范围权限控制方案是将业务按照归属人员和归属部门来划分,在配置时可有以下选项:
- 我的业务;
- 部门的业务;
- 下级部门的业务。
这样的设计一般也能够满足大部分业务的需求,但是它有以下几个明显的缺点:
- 不是非常灵活,只能根据业务的归属来进行范围划分;
- 数据必须内置归属人员和归属部门字段,有的系统还约定了字段名称。
基于条件表达式的数据范围设置
条件表达式类似与sql语句条件表达式,在数据查询时植入到查询语句中,在修改时对数据对象进行验证。
数据范围权限条件表达式设置
条件表达式的形式是一个逻辑表达式,其中方括号中的是 [表名.字段名],花括号中的是 { 环境变量或属性 ':' 在SQL语句中的变量名},这个SQL语句中的变量名是可选的,它的作用是个前面环境变量和属性重命名,避免命名SQL语句不合法。
配置不同角色的 数据权限范围
接口的权限遵循RBAC规范,将接口和角色关联,系统在关联角色时同时配置数据范围表达式,实现范围的权限控制。
条件表达式数据范围控制的实现方式
访问关系数据库有两种方式,一种通过ORM接口访问数据库中的表,另一种是直接用SQL语句访问数据库。这两种方式有不同的控制方式:
一、ORM接口访问
需要对ORM接口进行扩展或者自己设计一套ORM方案,南大先腾做了MyBatis和Hibernate的对应功能的拓展 https://github.com/ndxt/centit-persistence/tree/before-delete-hibernate-mybatis ,因为后来公司全部研发都转移到自研的ORM,这个扩展也不再更新了,各位有兴趣可以获取。
在ORM接口访问数据库时对上面的表达式进行转换,主要是转换花括号{}中的环境变量。
二、SQL语句访问
SQL语句访问时也要对语句进行拓展,在SQL语句中添加锚点,形式如下:
select * from bussiness_chance a where 1=1 { bussiness_chance a } order by a.create_time
其中 { bussiness_chance a } 为锚点,形式为 { 表名 别名, 表名 别名,……..} 别名是可选的,一个锚点可以有多个表。SQL语句再执行前需要进行预处理,系统根据当前用户的角色查找他用于的角色在当前接口中的所有数据范围权限表达式,如果有多个表达式则用or连接成符合比表达式,并替换到SQL语句的锚点中。比如上面的示例替换的结果为:
select * from bussiness_chance a where 1=1 and a.follow_user = :currUserCode order by a.create_time
同时在参数变量表中添加一个currUserCode的变量,对应的值为 当前用户环境变量中的currentUser.userCode值。
总结
通过条件表达式的方式来控制数据范围权限理论上可以对任何字段进行过滤控制,可以在系统上线后同个配置的方式进行灵活配置。但是也有一些缺点:一、只能用于关系数据库并且需要拓展ORM模块或者自研ORM模块,二、SQL语句需要添加数据范围权限的控制锚点,虽然不麻烦也不复杂但是不能忘掉。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。