业务效果
对于同一种业务数据的查询(比如分页),不同的用户看到的查询结果,受限于其本人的权限规则配置。
例子:用户查看员工工资,张三能看见本人所在部门的数据,李四可以查看行政部和市场部的数据。
规则配置
- 数权规则:表示对数据权限实现逻辑(比如:查看本人数据,查看某个部门的数据)
- 数权分配:数权规则和人的关系(有可能存在中间代理,比如岗位),包含授权、回收、查询等功能
- 数权分配操作的方式: UI交互设计,像用户表达操作逻辑
人 + 规则 = 数权配置
鉴权
资源持有方
保存业务数据的服务,比如订单服务。这些服务需要提前做好规划,业务数据表需要有权限关联字段(比如部门ID),根据业务需求,可能不止一个。
权限集合持有方
权限集合来自业务数据,而业务数据又位于各个微服务中, 比如根据部门来做数据权限,那么部门的唯一标识符就组成了权限集合。
权限配置中心
权限配置中心持有数据权限的规则,由于规则跟系统用户存在直接或者间接的联系,因此,它一般由用户中心来做。
鉴权流程
- 用户发起查询请求
- 资源持有方根据本接口的规则编码和用户ID去权限配置中心拉取改用户的数据权限配置
- 资源持有方根据数据权限规则配置,将权限具体化。比如规则是【本人所在部门及子级】,那么就应该去管理部门数据的服务拉取具体的部门ID集合。
- 资源持有方将权限集合应用到数据查询语句上,使得查询结果符合业务预期。
准备工作
明确责任
约定:某个接口需要支持数据权限
那么:接口实现应该具备以下能力
- 获取数据配置的能力:当前用户在此接口上的数权配置(查看全部数据 or 查看本人所在部门数据)
- 获取数权具体范围的能力: 本人所在部门到底是哪些部门?部门数据不在你的微服务模块中
- 数据处理能力:
- 查询:DAO层查询条件处理
- 更新Service层越权检查(Read & Check befor update)
提前规划
- 确定需求范围:哪些接口需要支持数据权限
- 规划数据库表设计,业务表和数据权限规则的关联(比如应该有部门ID字段)
- 规则配置
- 多个维度的规则:本人数据、按部门、按地区。。。
- 规则组合:本人以 或者 本人所在部门
- 规则关联用户 or 角色 or 岗位 ?
统一处理
- 通用逻辑封装
- 获取规则的逻辑
- 将某种规则自动转化为ORM框架查询,或是增强
- 根据ORM框架不同有不同的处理方式
- Mybatis Plus :Mapper扩展 + Sql拦截,需要对MP源码了解
- JPA: 可能会比MP简单,封装一个Specification 工具类即可满足基本要求
- 可插拔
- Mybatis Plus 原生Mapper接口和扩展接口之间切换
- JPA:Specification 工具处理 OR 不处理
要不要统一处理?
个人认为看统一处理能带来多大的便利性,因为这个跟业务是耦合的,需要一定的开发规范和顶层设计做支撑。拿不准的话,各个业务模块按照上面描述的鉴权流程自己编码比较合适。
参考
获取规则的数据结构
1 | { |
serviceCode
表示服务接口的编码,根据业务需求提前规划好,鉴权流程第二步会用到rules
表示鉴权规则,因为可以有多种规则进行组合,因此还有一个composing字段。
以上的配置描述的数据权限就是
用户 10086
在编码为 get_salary
的业务接口上,所具有的数据权限为
- 由ID为 888 的用户提交的数据
- 部门ID为 1 的子部门的数据
- 部门ID为 1,2,3 的部门的数据
- 满足以上三个条件的任意一个
Mybatis-Plus扩展Mapper的例子
参考代码 ScopeSupport