史上最强大的权限系统设计方案——极简主义

权限模型设计——资源-组-标签模型/Resources-Group-Tag(RGT)

1、前言

RBAC模型可以说是权限模型的事实标准了,也有大量基于其的变种或增强设计,如RBAC0、RBAC1、RBAC2、RBAC3等等,但其设计或实现都太过繁琐和复杂了,这里借用一位博友做的RBAC3模型作比较(各有所长,无比较高低之意,仅借为基础作展开讲解),表设计图如下:

图1

仅仅一个权限就有15个表之多,而且大多数表相互之间都有多对多关联,复杂度之高~~~就这,还没有实现最全的权限系统,如SaaS所需要的数据分离、数据合并等数据权限功能基于这个设计就很难实现(其设计中仅有基于组织的数据隔离,并且组织和权限在同一个维度);另外由于其设计是针对一个具体的系统进行的,太具象了,不够通用,较难移植。

RGT模型:先上一张最终的表设计图,核心的思想就是把对象进行统一抽象(多个类似对象抽象为一个)、简化(用一个表来表达一对多关系),应用到具体应用中时只需要拓展资源表的字段即可。

图2

与图1相比,把用户、权限统一抽象为资源,并使用URI管理上下级关系(类似文件系统的机制,优势:可使用索引);把组织、身份、用户组、角色统一抽象为组,组本身是树结构,资源和组之间是多对多关系,这就完成了图1所支持的功能。另外新添加了另一个维度——标签,用于从另一个维度做数据权限功能。

2、权限模型对比

RGT核心思想也是源自于RBAC模型,但对RBAC模型有进一步抽象。

RBAC基础模型:

RGT基础模型:

把RBAC中的用户和权限统一抽象成了资源、把角色抽象成了组,在这个基础上增加了标签,用于实现数据隔离、数据合并等数据权限功能。

RBAC常用结构:

其中用户为线性表,权限可级联,角色可拓展为树,如下:

对于其它层次的拓展也是基于用户-角色,如图1的组织架构、用户组等。

RGT常用结构:

其中资源、组、Tag本身都可以是树结构。

这里Tag只是一个维度的统一叫法,可以用来表示任何概念,如国家、公司、域、网段、租户等等。

3、复杂度对比

时间复杂度:

由于RBAC可能存在多级多对多级联,而RGT最多只存在一次多对多级联,故在时间复杂度上RGT更优。基于缓存的情况下这个优势会非常明显。

逻辑复杂度:

由于RGT比较抽象,在理解和实际操作中需要对整个设计都非常明确;而且RBAC每个表的意义都很确定,操作简单;故逻辑复杂度RBAC更优。

开发复杂度:

RBAC有大量的表和表关系,开发复杂度很高,特别是多级缓存会很难设计;RGT一般就3张表,最多4张表,开发和拓展都比较简单。

PS:空间复杂度相差不大,不作比较。

4、实施的具体步骤

经过前面的对比,自行选择适合的方案,后续章节仅针对RGT展开。

4.1、定义资源、组、Tag

确认模型后的第一步需要根据实际项目情况定义资源、组、Tag分别代表什么。以图1为案例(后续也使用该业务为案例),在其基础上拓展一层公司,公司与公司间的权限完全隔离,公司内部的权限采用层级管理;那么资源代表用户和权限,组代表组织、身份、用户组、角色,Tag代表公司。

4.2、套入模型

模型只是定义了权限相关的设计,并没有包含业务,需要把模型套入实际的项目中并且根据实际业务情况拓展用户、公司等基础信息的字段,并且在需要做数据权限的相关业务表上添加Tag字段(复杂数据权限可以使用多对多)。

4.3、基础数据初始化

要让权限系统正常工作,需要预先把基础的用户、权限、组织、身份、用户组、角色、公司等信息添加到系统中。

4.4、鉴权

当某个用户请求某个资源时,首先判定该用户是否具有访问该资源的功能权限(查询资源-组映射表),然后判定该用户是否具有访问该资源的数据权限(查询Tag)。

4.5、优化

至此,核心业务功能已经完成了,对性能没要求的业务就结束了。

由于鉴权是无处不在的,如果每一个动作都按如上操作进行鉴权,那性能是无法忍受的(一次鉴权至少需要3次查询,平均开销50ms+),那就开始优化吧。第一步:直接缓存4个表的数据,平均开销能压到5ms左右。第二步:重构4个表的数据,采用K-V结构缓存,平均开销能压到2ms左右。第三步:集中缓存+本地缓存,平均开销能压到0.1ms左右。

注:实际步骤之间没有顺序关系,为了表达性能提升的递进关系才按顺序写,缓存是以空间换时间,请根据实际需要进行选择。

发布了2 篇原创文章 · 获赞 2 · 访问量 64

猜你喜欢

转载自blog.csdn.net/tablelai/article/details/105296236