权限管理——多系统下的数据权限通用控制

大家好:

常见的,在项目实际开发中我们不光要控制一个用户能访问哪些资源,还需要控制用户只能访问资源中的某部分数据。这就是所谓的数据权限。典型的如列表数据权限,主要通过数据权限控制行数据,让不同的人有不同的查看数据规则。

行业背景

在互联网系统中,权限一般分为功能权限和数据权限,功能权限比较常见,因为通用性和复用性,业内有很多的通用框架和设计。但对应数据权限来说,由于数据权限强依赖客户组织架构和具体业务的关系,往往实现起来会比较复杂,很少有一个设计架构能完全覆盖住,所以大部分的系统都一致性的遵循此策略:如非必要的尽量不使用数据权限,必须要的则单独控制。

目前常见数据权限方案基本为硬编码,具体分为如下两种:一是拆分功能页面,即根据不同数据权限用户,通过复制拷贝的方式,增加多个类似的菜单,再通过功能权限配置来给不同用户设置不同的菜单,从而实现数据权限的控制;二是在功能对应的后端接口里做判断,对不同数据权限的用户,过滤不同的数据列表透出给用户。硬编码的方式显而易见的优点是技术难度低,实现简单。

但以上硬编码的方式,无论选择用哪一种,都无法解决系统灵活性的问题,每当系统有老的需求要变更或者新的需求要新增,对应的开发人员就不得不去调整编码,修改菜单和页面,由此可见,硬编码对开发的成本和运维的成本都比较高。与此同时,行业内常见的通用数据权限控制,大都是给单一业务使用,和业务耦合度较高,可能在当前业务客户端是通用可扩展的,但是在另一个业务客户端就无法做到无缝接入了。

因此,如何提高数据权限设置的灵活性,降低耦合性,是本领域技术人员需要解决的问题。

建设价值

首先来说一下,为什么我们要做这样一个多系统的数据权限控制装置?

大背景是我司当前有多个业务系统需要通过数据权限控制业务数据,它们的用户体系或相同或不同,控制维度各有定制。

于是产生诸如以下需求:

  • 权限可配置化
  • 支持业务快速接入
  • 模型统一

为了支持以上需求,于是理所当然的出现了如下一套多系统的通用数据权限控制系统。

系统介绍

本系统底层使用统一的一套模型,支持权限配置化,业务方可自定义权限维度,用户体系解耦,满足不同系统快速接入数据权限的业务场景。

数据权限

RBAC是经典的功能权限模型,它是 Role-BasedAccess Control 的英文缩写,意思是基于角色的访问控制。

运营事先会在系统中定义出各种不同的角色,不同的角色拥有不同的权限,一个角色实际上就是一组权限的集合。而系统的所有用户都会被分配到不同的角色中,一个用户可能拥有多个角色。使用这种模型可以极大地简化权限的管理。

但是,在该模型下,系统只会验证用户甲是否属于角色A,而不会判断用户甲是否能访问只属于用户乙的数据 Data。这种问题我们称之为"水平权限管理问题"。

所以,为了解决这个问题,我们基于 RBAC 模型下,又扩展了功能和维度的概念,使系统能基于角色控制用户的数据权限。如下:

同时,为了做到多系统通用,我们又对系统、功能、权限做了如下抽象:

模型把每个系统抽象成由一个个业务组成,业务下分解成多个功能,功能对应多个维度:

  • 数据权限的颗粒度为到功能,一个功能可包含多个 Rest 接口。
  • 功能下分多个维度,所谓的数据权限实际就是控制每个维度,维度最终对应的是每个功能业务数据的筛选字段。
  • 最终当所有都配置完成后,每个角色对应每个功能下就挂着多个数据规则。当用户访问具体功能时,根据用户角色的数据规则,返回对应数据。
  • 当固定值不满足业务需求时,提供开放端口给业务方,业务方可实现对应维度的选择项端口,来达到自定义维度对应值的目的。

数据规则

根据以上描述,显而易见的,要实现数据权限,最重要的是需要抽象出数据规则。

比如我们营销系统的订单列表,需要从下面几个维度来控制数据访问权限。

销售人员只能看自己的数据;

a 部门的人只能看自己部门的数据;

a 部门的上级部门 A 的人能看自己部门的数据和下级 b 部门的人;

上面的这些维度就是数据规则。

这样数据规则的几个重点要素我们也明晰了,就是规则字段,规则表达式,规则值,上面三个场景对应的规则分别如下:

规则字段:创建人,规则表达式: = ,规则值:当前登录人

规则字段:所属部门,规则表达式: = ,规则值:a

规则字段:所属部门,规则表达式: in ,规则值:A,a

即数据规则由【维度+条件表达式+维度对应值】组成,业务数据的数据权限就是由多个数据规则组成的范围控制。具体模型如下:

接入流程

那么,本套多系统权限控制系统,到底该如何接入呢?大致流程如下:

按照此通用方案,数据控制整体接入过程如下:

1.业务确定需要数据权限接入的功能。

2.产品、开发、业务确认功能的维度。

3.运营在开发的支持下在运营管理端配置数据权限,包括支持的维度、表达式、固定值等等。如需自定义维度对应值,实现对应端口。

4.各系统管理员登录各自的数据权限配置端,设置每个角色的数据规则。

5.客户访问系统的具体功能,根据客户的角色,获得数据规则,根据数据规则组装业务数据返回。

接入案例-订单列表

订单是很常见的系统功能,当前,需要对不同员工查看订单的数据范围做控制,根据员工所属的部门不同,查看对应部门的订单列表。

步骤一:确定系统、功能、维度

系统:xxx系统 功能:订单列表 维度:部门

步骤二:管理端配置数据权限

步骤三:业务方接入 Sdk,实现自定义维度(部门)选择项配置端口

示意代码

arduino 复制代码
/**
 * 获取维度选择项 
 */
List<DimensionOption> getDimensionOptionList(List<String> dimensionCodes);

步骤四: 对应api查询数据接口接入 Sdk,完成数据过滤

步骤五: 系统管理员配置角色数据权限

只要完成以上5步,就实现了接入数据权限的功能。整个流程只有接入 Sdk 的成本,1天内即可完成,快速、高效,极大的降低了成本。同时公司内所有系统都拥有了一套完整统一的权限控制系统。

Sdk 如何进行数据权限控制

那么,底层究竟是如何实现数据权限控制的?

以下是一个请求的控制链路:

权限 Sdk 是真正实现权限控制的核心组件。

Sdk 中的基石是一个个对外开放的端口,其中最底层的是上下文端口。接入方需实现这个端口接口,根据当前缓存用户封装数据权限上下文。如有自定义维度,需实现自定义维度选择项端口,返回业务自定义的维度选择项。

数据权限生效实现过程如下:

1.请求 Path 被 Sdk 拦截,通过正则匹配配置的权限 Api,匹配到说明需要被控制。

2.在功能接口中,Sdk 根据上下文端口获取当前请求上下文,根据上下文获取对应用户所有角色的数据权限。

3.根据数据权限设置的配置,组装权限控制的条件。

4.业务方查询时加上权限控制条件,得到的数据,就是控制了数据权限后的数据。

ps:本sdk只针对java语言的后端

如果业务方使用的是 MyBatis 的 Xml 原生语句, Sdk 会把所有的数据权限组装成对应的 Sql 片段,自动对XML查询注入该 Sql 片段;如果使用的是 MyBatis-plus 的 QueryWrapper 方式,Sdk 会把所有的数据权限自动注入到生成的 QueryWrapper 条件中。

业务方也可以自主使用权限控制配置查询数据,关闭 Sdk 的自动注入。

问题
  • 当前只能直接对数据库存在的字段进行控制,如果是间接条件,无法控制数据权限
  • 自动注入当前只支持 MyBatis 的 Xml 原生语句和 MyBatis-plus 的 QueryWrapper 方式,其他如 Jpa 等不支持
思考

还有更多的类似问题,都是多系统数据权限控制需要解决的。虽然具体到每个小点,单从技术的角度来说,可能未必很难,但要支持更多系统,具备更好的通用化,还有很长的一段路可走。这是一个会随着业务的发展,需要持续改进的工作。

推荐阅读

SpringBoot自动装配

Java线程和CPU调度

数字人+AI换脸简单实现虚拟制片

Redis内存淘汰和过期删除策略原理分析

浅析MySQL之MVCC机制

招贤纳士

政采云技术团队(Zero),Base 杭州,一个富有激情和技术匠心精神的成长型团队。规模 500 人左右,在日常业务开发之外,还分别在云原生、区块链、人工智能、低代码平台、中间件、大数据、物料体系、工程平台、性能体验、可视化等领域进行技术探索和实践,推动并落地了一系列的内部技术产品,持续探索技术的新边界。此外,团队还纷纷投身社区建设,目前已经是 google flutter、scikit-learn、Apache Dubbo、Apache Rocketmq、Apache Pulsar、CNCF Dapr、Apache DolphinScheduler、alibaba Seata 等众多优秀开源社区的贡献者。

如果你想改变一直被事折腾,希望开始折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊......如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的技术团队的成长过程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 [email protected]

微信公众号

文章同步发布,政采云技术团队公众号,欢迎关注

相关推荐
专注VB编程开发20年4 分钟前
asp.net mvc如何简化控制器逻辑
后端·asp.net·mvc
用户67570498850235 分钟前
告别数据库瓶颈!用这个技巧让你的程序跑得飞快!
后端
千|寻1 小时前
【画江湖】langchain4j - Java1.8下spring boot集成ollama调用本地大模型之问道系列(第一问)
java·spring boot·后端·langchain
程序员岳焱1 小时前
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
后端·sql·mysql
龚思凯1 小时前
Node.js 模块导入语法变革全解析
后端·node.js
天行健的回响1 小时前
枚举在实际开发中的使用小Tips
后端
wuhunyu1 小时前
基于 langchain4j 的简易 RAG
后端
techzhi1 小时前
SeaweedFS S3 Spring Boot Starter
java·spring boot·后端
写bug写bug2 小时前
手把手教你使用JConsole
java·后端·程序员