您的位置:首页 > 健康 > 美食 > 数据权限的设计与实现系列4——数据权限控制整体设计

数据权限的设计与实现系列4——数据权限控制整体设计

2024/12/26 10:39:42 来源:https://blog.csdn.net/seawaving/article/details/141373653  浏览:    关键词:数据权限的设计与实现系列4——数据权限控制整体设计

背景

在前面介绍的若依开发平台和基于MybatisPlus数据权限插件实现的的数据权限控制方案中,都预置了5种数据权限范围。

  • 全部数据权限:所有数据,即不做数据权限控制
  • 部门数据权限:用户自己本部门的数据
  • 部门及以下数据权限:用户自己本部门及子部门的数据
  • 自定数据权限:自定义数据权限,即配置某角色可以访问若干个自选的部门的数据
  • 仅本人数据权限:自己的数据

先前分析过这种设计思路存在的一些问题,即对于数据权限的控制维度和实现思路基于部门维度,控制点放在角色上,会造成角色爆炸问题和权限扩大。

设计思路梳理

我们平台实现模式变了,控制点并不是放在角色上,因此需要进行一些调整。
首先,全部数据权限这种模式不适用了,不配置默认就是全部数据权限。
其次,自定数据权限,通过角色和部门对应关系来进行数据权限过滤的方式,因为控制点不再基于角色,也不需要了。
再次是考虑部门及以下数据权限的合理性。通常的数据权限控制范围是上级部门可以查看下级部门的数据,反之则不行。这条规则恰恰是反向的,上级部门创建的数据,下级部门可以访问,因此这种需求场景理论上会非常少。
深入思考了下,有更好的做法。
这实际上是个权限规划问题,更常见的做法是先规划好明确的数据权限范围,如公司、部门、个人,然后具体的业务数据,按照规划的数据范围来控制。公司和个人都是相对明确和固定的,关键在于部门的处理。实际上,对于中大型公司,公司与个人之间往往隔着多级部门,除了公司直属的一级部门外,部门下还会有二级部门或三级部门(不同公司称呼不同,有的叫部门,有的叫模块,有的叫小组等)。
系统初始化时就确定好数据权限控制维度中部门对应到哪一级,如果数据权限管理粒度粗一些,则对应到一级部门,即在用户登录时,认证通过后,读取其一级部门的组织机构标识,作为该用户的部门标识(注:库表中保存的用户的组织架构标识是其直接挂靠的组织机构标识,可能是二级或三级部门)。
如果要细化,可以新增一个维度,就叫二级部门(或模块、小组等),与公司、一级部门并列,处理逻辑同上。

基于上述考虑,新的通用数据权限调整为以下3种:

  • 仅限自己访问:业务实体对象的创建人=当前用户
  • 本部门访问:业务实体对象的归属部门=当前用户的所在部门
  • 本公司访问:业务实体对象的归属公司=当前用户的所在公司

其中,本公司可访问是可选项,本质上还是取决于需求,业务系统使用方的体量和组织结构。如果就是一个公司,这条跟不做数据权限过滤是一样的;如果是一个集团,下属有多个公司,公司间需进行数据隔离,则加上这条就非常重要了。

目标确立

上面3种维度只是通用,要应对业务系统中复杂的个性化数据权限控制需求是不够的,结合具体销售单的应用场景来完善。
1.销售员本人可查看自己的,不能查看他人的
2.销售部经理可以查看所有的
3.公司总经理只查看销售金额大于100万的

要满足上述需求,还需要结合角色以及业务实体自身的属性来进行条件组合。
对销售单配置数据权限访问规则:
{创建人}={当前用户}
or
{当前用户拥有的角色} 包含 {销售部经理}
or
{当前用户拥有的角色} 包含 {公司总经理} and {销售金额}>100万

综上,我们规划和设计的数据权限,控制点放在了具体的业务实体上,由4种维度组合控制:部门、用户、角色(平台中称为用户组)、业务实体的属性。

功能梳理

完成上述需要做以下几方面工作:

  1. 业务表中必须增加字段,用来标识数据归属,主要包括创建人、归属部门、归属公司(可选)
  2. 前端实现数据权限规则的可视化配置功能,由系统管理员进行维护
  3. 配置规则中,当前用户、当前用户归属部门、当前用户拥有的角色等内容,使用约定的特殊标记标识,如{@CurrentUser@},后端解析规则时,根据运行时动态获取替换为真实数据。
  4. 后端需要识别到要进行数据权限过滤的查询、修改和删除操作,读取数据权限规则配置,解析处理为数据权限过滤sql片段,拼接到原业务SQL语句中。

技术难点

有以下几个技术难点需要解决:

  1. 数据权限规则的配置对象是谁?
  2. 数据权限规则保存在哪?
  3. 后端如何找到对应的数据权限规则?

下面来逐个思考和解决。

数据权限规则的配置对象是谁?

数据权限规则的配置对象是业务实体还是具体的删改查操作?
方案1:业务实体,查询、修改和删除同一个规则
方案2:业务实体具体方法,查询、修改和删除可以分别配置不同的规则

方案1只需要配置一次就好了,简便;
方案2的控制粒度比方案1更小,更灵活,可以为删改查分别配置。
考虑到数据权限规则通常是一致的,并不需要为查询、修改和删除分别控制,几乎没有这样的实际业务场景,因此暂时按方案1的方式实现,后续如有方案2这种细颗粒度控制需求,再做平台的优化改造。

2.数据权限规则保存在哪?

方案1:系统管理模块下的系统权限项
方案2:实体配置模块下的实体数据模型

方案1更直观,与系统功能菜单可以对应起来,但是菜单项是独立配置的,与业务实体没有明确的关联关系,因此如采用该方式,需要增加业务实体的标识或库表名。
方案2更符合逻辑,业务实体对应的数据权限规则,在实体配置环节处理,自然,并且唯一。

实际有两个挑战:
1.权限项(功能菜单)可能会根据实际需要配置多个对应着同一个业务实体,这种情况下,如果数据权限规则也配置多个出来会存在冲突。
2.是否有些业务功能并没有通过实体配置功能来实现,数据权限规则配置没有地方安放?

综合考虑了下,数据权限其中一个重要维度就是业务实体属性,这部分数据必须基于实体配置模块产生,因此挑战2的问题可以忽略。
最终选择方案2,在数据模型的基础上维护数据权限规则。

新建库表,来维护实体模型与数据权限规则的对应关系,存放表名、数据权限规则,后续如需要分别控制改删查的数据权限,可以增加一列区分具体操作,并重写拦截器,来获取不同的规则。

3.后端如何找到对应的数据权限规则?

Mybatisplus的数据权限插件,会拦截sql语句,将当前操作的表名传给数据权限处理器的getSqlSegment方法,依据表名,去数据权限配置表中获取的sql片段,如不为空,则需要进行数据权限过滤。

开源平台资料

平台名称:一二三开发平台
简介: 企业级通用开发平台
设计资料:[csdn专栏]
开源地址:[Gitee]
开源协议:MIT
如果您在阅读本文时获得了帮助或受到了启发,希望您能够喜欢并收藏这篇文章,为它点赞~
请在评论区与我分享您的想法和心得,一起交流学习,不断进步,遇见更加优秀的自己!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com