权限系统设计

B端产品如何设计权限系统

Posted by Li Yucang on July 18, 2023

权限系统设计

前言

现代经济学理论认为,企业本质上是“一种资源配置的机制”,其能够实现整个社会经济资源的优化配置,降低整个社会的“交易成本”。

权限管理系统的本质是企业内部或企业之间的资源在B端产品上以特定机制配置的映射;所以权限管理系统的贴身情况也是衡量产品商业模式好坏、用户价值高低的一杆标尺。

权限管理系统的设计中常遇到的问题有:

  • 配置不规范,系统基础不稳,拓展性差;

  • 配置不灵活,用户需求难满足,体验差;

  • 配置太灵活,逻辑会复杂,实施成本高;

那么,如何设计一款贴身并能随着产品一起生长的权限管理系统呢?

常见的权限模型

基本要素

权限是主体对客体遵循特定机制做出的行为。所以,权限的4个基本要素就是主体、客体、行为、机制。

主体

指行为的行使者,是操作的发起者。主体的类型有很多种,常见的有:

  • 用户及用户组。更准确地术语应是“系统使用者”,其与系统的账号体系相对应,一个用户对应一个唯一账号;多个用户组成一个用户组;

  • 角色及角色组。角色是权限分配的单位与载体,通常与组织架构体系相对应。

  • 用户标签及用户标签组;

  • 设备及设备组。HarmonyOS系统首期给Mate40系列开放使用;

  • IP地址。限制对IP地址的访问;

  • 地理位置。如O2O生活平台在不同位置展示的店铺不同;

  • 局域网。如公司电脑在内网和外网所访问的资源不同。

客体

指行为的承受者,是操作所针对的对象。主要有三大类:

1、资源

  • 基本属性的数据

  • 行数据

  • 个别的列数据(俗称“某些字段”)

2、资源的容器

  • 页面

  • 目录或菜单

  • Tab

  • 按钮

3、操作资源所必须的条件

  • 任务流,也称工作流。某一资源在任务流中的状态不同,不同状态的资源可以分配给不同角色操作;

  • 所属权。所属权包括个人、个人及下属、部门、部门及下属、全部,通常与组织架构体系的组织范围相对应。

行为

指主体对客体的活动,包括主体在产品中对客体的一些操作,而我们常说的“权限”一词则指代了这一操作,例如“查看朋友圈的权限”。常见的行为有:

  • 登入、登出

  • 改,包括读写

  • 查,包括不可见、只读

  • 上传、下载

  • 共享

机制

系统机制包括对主体、客体和主客体关系的认证,对主体行为及行为运行方式的授权。常见的机制有:

  • 继承。父级可以拥有子级的权限,依托于组织架构或角色层级结构;例如销售部门负责人有所有下属的权限;

  • 互斥。是对主体之间责任的强制性规定,防止同一主体拥有足够权限进行欺骗行为,防止即当运动员又当裁判的行为。责任分离有静态和动态之分:

  • 静态互斥。一个用户不能同时拥有两个互斥的角色。例如银行内部的贷款申请者和贷款审批者不能让同一个人承担;

  • 动态互斥。一个用户可以拥有两个角色,但在运行时只能激活一个角色,也成为运行互斥机制。例如银行内部为了灵活放贷,职员张三可以同时有贷款申请者角色和贷款审批者角色,但对于同一笔贷款,不能即申请又审批。

  • 先决条件。A想成为C,就必须先成为B,C只能从B中产生;

  • 基数限制。是主体与主体、主体与客体、主体与行为间数量关系的限制。例如一个用户可拥有的角色数目受限;一个角色被分配的用户数量受限;一个角色的权限数目受限;

  • 授予机制。是主体将自己的权限授予给其他主体的权限;

  • 双向验证。系统即验证主体,也验证客体,双方都通过验证时才能允许主体对客体的行为;

  • 共享机制。

访问范围限定机制。一般有三类依托:

  • 组织架构

  • 角色层级结构

  • 组织范围/抽象关系

环境限制。分为三类:

  • 空间限制。例如针对地理位置、IP地址、局域网的限制;

  • 时间限制。例如考试时间到了之后,操作权限有所限制;

  • 频度限制。例如对输入密码的频率的限制;

ACL模型:访问控制列表

Access Control List,ACL是最早的、最基本的一种访问控制机制,是基于客体进行控制的模型,在其他模型中也有ACL的身影。为了解决相同权限的用户挨个配置的问题,后来也采用了用户组的方式。

原理:每一个客体都有一个列表,列表中记录的是哪些主体可以对这个客体做哪些行为,非常简单。

例如:当用户A要对一篇文章进行编辑时,ACL会先检查一下文章编辑功能的控制列表中有没有用户A,有就可以编辑,无则不能编辑。再例如:不同等级的会员在产品中可使用的功能范围不同。

缺点:当主体的数量较多时,配置和维护工作就会成本大、易出错。

DAC模型:自主访问控制

Discretionary Access Control,DAC是ACL的一种拓展。

原理:在ACL模型的基础上,允许主体可以将自己拥有的权限自主地授予其他主体,所以权限可以任意传递。

例如:常见于文件系统,LINUX,UNIX、WindowsNT版本的操作系统都提供DAC的支持。

缺点:对权限控制比较分散,例如无法简单地将一组文件设置统一的权限开放给指定的一群用户。主体的权限太大,无意间就可能泄露信息。

MAC模型:强制访问控制

Mandatory Access Control,MAC模型中主要的是双向验证机制。常见于机密机构或者其他等级观念强烈的行业,如军用和市政安全领域的软件。

原理:主体有一个权限标识,客体也有一个权限标识,而主体能否对该客体进行操作取决于双方的权限标识的关系。

例如:将军分为上将>中将>少将,军事文件保密等级分为绝密>机密>秘密,规定不同军衔仅能访问不同保密等级的文件,如少将只能访问秘密文件;当某一账号访问某一文件时,系统会验证账号的军衔,也验证文件的保密等级,当军衔和保密等级相对应时才可以访问。

缺点:控制太严格,实现工作量大,缺乏灵活性。

RBAC模型:基于角色的访问控制

Role-Based Access Control,RBAC模型在目前使用的最广泛、最普遍。

原理:在主体和权限之间引入了“角色(Role)”的概念,角色解耦了主体和权限之间的关系。有四个不同的层次:

  • RBAC0:基本模型,相当于ACL+角色。权限被赋予角色,而不是用户,当一个角色被制定给一个用户时,该用户就拥有了该角色所包含的权限。所有的角色都是平级的,没有制定角色层级关系;所有对象都没有附加约束,没有制定限制;

  • RBAC1:角色分级模型,相当于RBAC0+继承机制;

  • RBAC2:角色限制模型,相当于RBAC0+互斥机制+先决条件机制+基数限制机制;

  • RBAC3:统一模型,相当于RBAC1+RBAC2。

缺点:需要将某个权限单独设置给用户时,如果用户已有的角色中不包含该权限,就需要重新设置角色的权限或者重新创建一个新的角色,在业务和需求变更时需要维护大量的角色。

ABAC模型:基于属性的访问控制

Attribute-Based Access Control,能很好地解决RBAC的缺点,在新增资源时容易维护。

原理:通过动态计算一个或一组属性是否满足某种机制来授权,是一种很灵活的权限模型,可以按需实现不同颗粒度的权限控制。

属性通常有四类:

  • 一是主体属性,如用户年龄、性别等;

  • 二是客体属性,如一篇文章等;

  • 三是环境属性,即空间限制、时间限制、频度限制;

  • 四是操作属性,即行为类型,如读写、只读等。

例如:早上9:00 ~ 11:00期间A、B两个部门一起以考生的身份考试,下午14:00 ~ 17:00期间A、B两个部门相互阅卷。

缺点:规则复杂,不易看出主体与客体之间的关系,实现非常难,现在应用的很少。

RBAC模型

权限设计

从业务分类上来讲权限可以分为数据查看权限,数据修改权限等,对应到系统设计中有页面权限、菜单权限、按钮权限等。菜单也分一级菜单、二级菜单甚至三级菜单。菜单对应的页面里又有很多按钮,我们在设计的时候最好把权限设计成树形结构,这样在申请权限的时候就可以一目了然的看到菜单的结构,需要哪些权限就非常的明了了。

如下图所示:

按照这个架构,按钮的父级是二级菜单,二级菜单的父级是一级菜单,这样用户申请权限的时候非常清晰的看到自己需要哪些权限。

为什么需要角色

权限结构梳理清晰之后,需要思考怎么把权限分配给用户,用户少的情况下,可以直接分配,一个用户可以有多个权限,统一一个权限可以被多个用户拥有,用户-权限的模型结构如下所示:

这种模型能够满足权限的基本分配能力,但是随着用户数量的增长,这种模型的弊端就凸显出来了,每一个用户都需要去分配权限,非常的浪费管理员的时间和精力,并且用户和权限杂乱的对应关系会给后期带来巨大的维护成本。用户-权限对应关系图:

这种对应关系在用户多的情况下基本无法维护了。其实很多用户负责同一个业务模块所需要的权限是一样的,这样的话我们是不是可以借助第三个媒介,把需要相同的权限都分配给这个媒介,然后用户和媒介关联起来,用户就拥有了媒介的权限了。这就是经典的RBAC模型,其中媒介就是我们通常所说的角色。

权限模型的演进

RBAC模型

有了角色之后可以把权限分配给角色,需要相同权限的用户和角色对应起来就可以了,一个权限可以分配给多个角色,一个角色可以拥有多个权限,同样一个用户可以分配多个角色,一个角色也可以对应多个用户,对应模型如下所示:

这就是经典的RBAC模型了(role-based-access-control),在这里面角色起到了桥梁左右,连接了用户和权限的关系,每个角色可以拥有多个权限,每个用户可以分配多个角色,这样用户就拥有了多个角色的多个权限。

同时因为有角色作为媒介,大大降低了错综复杂的交互关系,比如一家有上万人的公司,角色可能只需要几百个就搞定了,因为很多用户需要的权限是一样的,分配一样的角色就可以了。这种模型的对应关系图如下所示:

用户和角色,角色和权限都是多对多的关系,这种模型是最通用的权限管理模型,节省了很大的权限维护成本, 但是实际的业务千变万化,权限管理的模型也需要根据不同的业务模型适当的调整,比如一个公司内部的组织架构是分层级的,层级越高权限越大,因为层级高的人不仅要拥有自己下属拥有的权限,二期还要有一些额外的权限。

RBAC模型可以给不同层级的人分配不同的角色,层级高的对应角色的权限就多,这样的处理方式可以解决问题,但是有没有更好的解决办法呢,答案肯定是有的,这就引出角色继承的RBAC模型

角色继承的RBAC模型

角色继承的RBAC模型又称RBAC1模型。每个公司都有自己的组织架构,比如公司里管理财务的人员有财务总监、财务主管、出纳员等,财务主管需要拥有但不限于出纳员的权限,财务总监需要拥有但不限于财务主管的权限,像这种管理关系向下兼容的模式就需要用到角色继承的RBAC模型。角色继承的RBAC模型的思路是上层角色继承下层角色的所有权限,并且可以额外拥有其他权限

模型如下所示:

从模型图中可以看出下级角色拥有的权限,上级角色都拥有,并且上级角色可以拥有其他的权限。角色的层级关系可以分为两种,一种是下级角色只能拥有一个上级角色,但是上级角色可以拥有多个下级角色,这种结构用图形表示是一个树形结构,如下图所示:

还有一种关系是下级角色可以拥有多个上级角色,上级角色也可以拥有多个下级角色,这种结构用图形表示是一个有向无环图,如下图所示:

树形图是我们比较常用的,因为一个用户一般情况下不会同时有多个直属上级,比如财务部只能有一个财务总监,但是可以有多个财务主管和收纳员。

带约束的RBAC模型

带约束的RBAC模型又成RBAC2模型。在实际工作中,为了安全的考虑会有很多约束条件,比如财务部里同一个人不能即是会计又是审核员,跟一个人同一时间不能即是运动员又是裁判员是一个道理的,又比如财务部的审核员不能超过2个,不能1个也没有。因为角色和权限是关联的,所以我们做好角色的约束就可以了。

常见的约束条件有:角色互斥、基数约束、先决条件约束等。

角色互斥: 如果角色A和角色B是互斥关系的话,那么一个用户同一时间不能即拥有角色A,又拥有角色B,只能拥有其中的一个角色。

比如我们给一个用户赋予了会计的角色就不能同时再赋予审核员的角色,如果想拥有审核员的角色就必须先去掉会计的角色。假设提交角色和审核角色是互质的,我们可以用图形表示:

基数约束: 同一个角色被分配的用户数量可以被限制,比如规定拥有超级管理员角色的用户有且只有1个;用户被分配的角色数量也需要被限制,角色被分配的权限数量也可以被限制。

先决条件约束:用户想被赋予上级角色,首先需要拥有下级角色,比如技术负责人的角色和普通技术员工角色是上下级关系,那么用户想要用户技术负责人的角色就要先拥有普通技术员工的角色。

用户划分

用户组

我们创建角色是为了解决用户数量大的情况下,用户分配权限繁琐以及用户-权限关系维护成本高的问题。抽象出一个角色,把需要一起操作的权限分配给这个角色,把角色赋予用户,用户就拥有了角色上的权限,这样避免了一个个的给用户分配权限,节省了大量的资源。

同样的如果有一批用户需要相同的角色,我们也需要一个个的给用户分配角色,比如一个公司的客服部门有500多个人,有一天研发部研发了一套查询后台数据的产品,客服的小伙伴都需要使用,但是客服由于之前并没有统一的一个角色给到所有的客服小伙伴,这时候需要新加一个角色,把权限分配给该角色,然后再把角色一个个分配给客服人员,这时候会发现给500个用户一个个添加角色非常的麻烦。但是客服人员又有共同的属性,所以我们可以创建一个用户组,所有的客服人员都属于客服用户组,把角色分配给客服用户组,这个用户组下面的所有用户就拥有了需要的权限。

RBAC模型添加用户组之后的模型图如下所示:

很多朋友会问,用户组和角色有什么区别呢?简单的来说,用户组是一群用户的组合,而角色是用户和权限之间的桥梁。 用户组把相同属性的用户组合起来,比如同一个项目的开发、产品、测试可以是一个用户组,同一个部门的相同职位的员工可以是一个用户组, 一个用户组可以是一个职级,可以是一个部门,可以是一起做事情的来自不同岗位的人。

用户可以分组,权限也可以分组,权限特别多的情况下,可以把一个模块的权限组合起来成为一个权限组,权限组也是解决权限和角色对应关系复杂的问题。

比如我们定义权限的时候一级菜单、二级菜单、按钮都可以是权限,一个一级菜单下面有几十个二级菜单,每个二级菜单下面又有几十个按钮,这时候我们把权限一个个分配给角色也是非常麻烦的,可以采用分组的方法把权限分组,然后把分好的组赋予角色就可以了。

给权限分组也是个技术活,需要理清楚权限之间的关系,比如支付的运营后台我们需要查各种信息,账务的数据、订单的数据、商户的数据等等,这些查询的数据并不在一个页面,每个页面也有很多按钮,我们可以把这几个页面以及按钮对应的权限组合成一个权限组赋予角色。加入权限组之后的RBAC模型如下所示:

实际工作中我们很少给权限分组,给用户分组的场景会多一些,有的时候用户组也可以直接和权限关联,这个看实际的业务场景是否需要,权限模型没有统一的,业务越复杂业务模型会约多样化。

组织

每个公司都有自己的组织架构,很多时候权限的分配可以根据组织架构来划分。因为同一个组织内的小伙伴使用的大部分权限是一样的。如下所示一个公司的组织架构图:

按照这个组织架构,每一个组织里的成员使用的基础权限很可能是一样的,比如人力资源都需要看到人才招聘的相关信息,市场推广都需要看到行业分析的相关信息,按照组织来分配角色会有很多优势:

实现权限分配的自动化: 和组织关系打通之后,按照组织来分配角色,如果有新入职的用户,被划分在某个组织下面之后,会自动获取该组织下所有的权限,无需人工分配。又比如有用户调岗,只需要把组织关系调整就可以了,权限会跟着组织关系自动调整,也无需人工干预。这么做首先需要把权限和组织关系打通。

控制数据权限: 把角色关联到组织,组织里的成员只能看到本组织下的数据,比如市场推广和大客定制,市场推广针对的是零散的客户,大可定制针对的是有一定体量的客户,相互的数据虽然在一个平台,但是只能看自己组织下的数据。

加入组织之后的RBAC模型如下所示:

用户可以在多个组织中,因为组织也有层级结构,一个组织里只可以有多个用户,所以用户和组织的关系是多对多的关系,组织和角色的关系是一对一的关系。这个在工作中可以根据实际情况来确定对应关系。

职位

一个组织下面会有很多职位,比如财务管理会有财务总监、财务主管、会计、出纳员等职位,每个职位需要的权限是不一样的,可以像组织那样根据职位来分配不同的角色,由于一个人的职位是固定的,所以用户跟职位的对应关系时一对一的关系,职位跟角色的对应关系可以是多对多的关系。加入职位的RBAC模型如下所示:

理想的RBAC模型

RBAC模型根据不同业务场景的需要会有很多种演变,实际工作中业务是非常复杂的,权限分配也是非常复杂的,想要做出通用且高效的模型很困难。我们把RBAC模型的演变汇总起来会是一个支撑大数据量以及复杂业务的理想的模型。把RBAC、RBAC1、RBAC2、用户组、组织、职位汇总起来的模型如下所示:

按照这个模型基本上能够解决所有的权限问题,其中的对应关系可以根据实际的业务情况来确定,一般情况下,组织和职位是一对多的关系,特殊情况下可以有多对多的情况,需要根据实际情况来定。

理想的RBAC模型并不是说我们一开始建权限模型就可以这么做,而是数据体量、业务复杂度达到一定程度之后可以使用这个模型来解决权限的问题,如果数据量特别少,比如刚成立的公司只有十几个人,那完全可以用用户-权限模型,都没有必要使用RBAC模型。

权限系统表设计

标准RBAC模型表设计

标准RBAC模型的表是比较简单了,要表示用户-角色-权限三者之前的关系,首先要创建用户表、角色表、权限表,用户和角色是多对多的关系,角色和权限是多对多的关系,需要再创建两章关系表,分别是用户-角色关系表和角色-权限关系表。这六张表的ER图如下所示:

理想RBAC模型表设计

理想的RBAC模型是标准RBAC模型经过多次扩展得到的,表结构也会比较复杂,因为要维护很多关系,如下图所示是理想的RBAC模型的ER图:

这里面需要强调的是角色互斥表,互斥的关系可以放在角色上,也可以放在权限上,看实际工作的需求。

结语

本文从易到难非常详细的介绍了权限模型的设计,在工作中需要根据实际情况来定义模型,千人以内的公司使用RBAC模型是完全够用的,没有必要吧权限模型设计的过于复杂。模型的选择要根据具体情况,比如公司体量、业务类型、人员数量等。总之最适合自己公司的模型就是最好的模型,权限模式和设计模式是一样的,都是为了更好的解决问题,不要为了使用模型而使用模型。