SpringBoot-权限:数据权限

1,750 阅读4分钟

数据权限分为行级权限和列级权限。

行级权限

比如,有20个一线销售人员分别归属于华东、华南和西南三个销售组,每个销售组有 1 个组长,还有 1 个销售经理负责整个销售部门业务。

通过行级权限,可以使 20 个一线销售只看到自己的订单数据、每个销售组长只能看到自己组的销售订单数据,同时销售经理可以看到所有人的销售订单数据。

如此一来,即便大家都在一张业务表中协作,但是数据彼此隔离,既享受到了协作的便捷性,又避免了因数据隐私带来的困扰。

image.png

西南组组长可查看到西南组的所有数据

image.png

销售人员毛佳慧只能看到自己的数据

行级权限:根据访问人员的访问权限,在sql语句后添加 where 查询权限

列级权限

行级权限虽强大,但仍然不够用。随着业务的发展,一张业务表中参与协作的部门越来越多,仅有「行级权限」很快就不够用了。

仍以订单场景为例,订单创建成功后会流转给库房,仓库人员根据订单上记录的货品和地址发货,然后在对应的订单上标记发货状态,上传订单号。

交给仓库的订单,只需要货品名称、数量和收货地址等信息,但是销售人员创建的订单还包含了金额、合同附件等不希望仓库人员看到的信息。如果能针对仓库人员隐藏部分字段就好了。

同时,还需要避免仓库人员改动订单信息,这样如果发货有异常,就可以立即判断是仓库发错货还是销售人员录入订单出错。

列级权限可以限制成员对单列的操作权限,还可以单独设置可以查看、编辑的字段。 这样,就可以实现上面所希望的:

  • 仓库人员不能看到订单中的金额字段;
  • 仓库人员虽然可以看到订单中的货品名称数量和收货地址,但是无法编辑这些信息。

image.png

订单所有字段

image.png

仓库人员可查看字段

如何设置列级权限?

「列级权限」的设置过程和「行级权限」一样简单::

在「角色与权限」中某个自定义的角色组下,打开需要设置列级权限的业务表,选中「自定义字段权限」后,勾选该角色组允许的操作就可以了。

image.png

设计理念

  • 非侵入性 我们希望数据权限的设计应该是非侵入式的,希望开发人员在编码过程中不需要有字段权限的概念,让开发人员更多的关注业务,而不是时刻思考这个功能如何进行字段权限的实现,待系统开发完后,引入组件即可使用;
  • 扩展性 我们希望字段权限的设计是可以后期在线可配置的,而不是编码过程中写死的,即开发过程不需要进行列权限处理,而上线后通过页面进行配置,即可轻松实现,同时不仅仅满足数据列的清除,也能支持脱敏、加密、混淆等多种业务场景,同时支持重写采取自定义处理;
  • 容错性 应用系统的稳定性不应该受到字段权限设计的干扰,即列权限模块出问题了,不应该影响到业务系统,实现优雅降级;
  • 兼容性 列权限的设计不应该只能适用于新系统,对老系统也能够实现插拔式的支持,且不用更改以前任何业务逻辑;
  • 便捷性 设计应该借鉴spring boot starter 思想,进行可插拔式,免配置的使用,满足开箱即用,既有默认实现,又有重写覆盖的功能;
  • 通用性 列权限的设计满足通用性、普适性,适用于多种类型的系统、多种应用。

实现思路

  • 动态SQL拼接 开由于根据权限查询动态列,可能导致某些重要字段被过滤,导致业务层报空指针,且处理脱敏,过滤极为复杂,与列权限强耦合。存在侵入性、低容错性、高复杂性、低扩展性。
  • 数据拦截 在业务逻辑处理完成后,根据列权限配置信息,对数据字段进行反射过滤,达到字段权限控制目的。