概要
在不同的系统中,其实关于权限设计是没有标准方案的。一般地,依据项目需求进行系统的功能规划设计、组织结构设计以及对应的权限设计等即可。权限管理是所有后台系统的都会涉及的一个重要组成部分,主要目的是对不同的人访问资源进行权限的控制,避免因权限控制缺失或操作不当引发的系统风险问题。从而有效的保证人、角色、资源的有效控制,避免数据不当的操作、隐私数据的泄露等问题。
RBAC模型
概念
其实,关于权限设计最常见的就是基于RBAC模型。而RBAC模型又有RBAC0、RBAC1、RBAC2、RBAC3等几种常见的模式。RBAC(Role-Based Access Control) 基于角色的访问控制的设计思想。作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。
RBAC中有4个比较关键的元素:用户 – 角色 – 权限 – 资源。
RBAC支持的安全原则
RBAC支持三个著名的安全原则:最小权限原则、责任分离原则和数据抽象原则。
最小权限原则:RBAC可以将角色配置成其完成任务所需的最小权限集合。
责任分离原则:可以通过调用相互独立互斥的角色来共同完成敏感的任务,例如要求一个计账员和财务管理员共同参与统一过账操作。
数据抽象原则:可以通过权限的抽象来体现,例如财务操作用借款、存款等抽象权限,而不是使用典型的读、写、执行权限。
RBAC优缺点
(1)优点:
简化了用户和权限的关系。
易扩展、易维护。
(2)缺点:
RBAC模型没有提供操作顺序的控制机制,这一缺陷使得RBAC模型很难适应哪些对操作次序有严格要求的系统。
这里补充一下术语解释:
(1)、资源
被安全管理的对象(Resources页面、菜单、按钮、订单等)。
(2)、 权限
问和操作资源的许可(Permit删除、编辑、审批等)。
(3)、角色
用户通过业务需求确定一个角色(Role),并按照实际的业务场景,赋予角色对应的权限的过程,角色也可以理解是权限的集合,是众多权限颗粒组成。
(4)、 用户
系统实际的操作员(User)
(5)、操作权限
页面权限:即用户登录系统可以看到的页面,由菜单来控制,菜单包括一级菜单或多级菜单。当系统赋予用户对应菜单的权限,那么用户就可以访问对应的菜单页面。
操作权限:即页面的功能按钮,包括:查看、新增、修改、删除、审核等。当用户点击按钮时,系统将会校验用户的是否包含次操作权限,如果有,就可以进行下一步操作。
数据权限 :数据权限就是用户在同一页面看到的数据是不同的。比如项目管理员,就能看到当前团队正在进行中的项目,以及项目的进度情况。而团队成员,就只能看到本人具体参与的项目,已经项目信息。相对于复杂一项的权限也可以基于组织结构来拓展。
总的来说,一般我们会这样来用一句话更好的理解它:【用户(user:谁)】被赋予【角色(role:具有1-n个权限)】,通过角色关联的【权限(permit:许可)】去访问/操作【资源(resource)】。如下图:
RBAC0模式
这是权限最基础也是最核心的模型,基本上绝大多数就是基于它来建设,包括用户、角色、权限。其中用户和角色可以是多对多的关系;角色和权限也是多对多的关系。
用户是发起操作的主体,可以是业务性的访问者、可以是后台管理系统的用户。角色起到了桥梁的作用,连接了用户和权限的关系。由于角色和权限的关系是多对多,而用户与角色也是多对多的关系,所以一个用户就有一个或多个角色一个或多个系统权限(这里关于针对比较简单的系统,例如用户量很小,项目级别也很小的系统,可以采用用户直接和权限关联。也就是添加一个用户,就直接针对用户去添加对应的权限,可以没有角色的概念。针对这种情况,在此不展开讨论)。
一般的系统中,引入角色(Role)就是为了提升了系统操作的效率和拓展性。权限是用户可以访问的资源,包括:页面权限、作权限、数据权限等(具体解释看上面的术语部分)。下面用具体的图例来展示:
RBAC1模式
RBAC1模式是RBAC0的拓展。主要是在角色上引入了角色继承(Hierarchical Role)的概念。即角色具有上下级的关系,角色间的继承关系可分为一般继承(General)和受限继承(Limited)关系。一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。而受限继承关系则进一步要求角色继承关系是一个树结构,实现角色间的单继承,受限继承则增强了职责关系的分离。这种设计可以给角色分组和分层,一定程度简化了权限管理工作。
这里举一个场景例子,比如销售团队,销售主管或经理一般会需要了解并汇总下面销售专员的数据。而销售专员能够管理各自的销售数据。此时,销售主管就需要向下继承销售专员的角色,进而也就拥有了他们的基本权限。
RBAC2模式
RBAC2同样建立在RBAC0基础之上,仅是对用户、角色和权限三者之间增加了一些限制,实现了责任分离。RBAC2中的一个基本限制是互斥角色的限制,互斥角色是指各自权限可以互相制约的两个角色。对于这类角色一个用户在某一次活动中只能被分配其中的一个角色,不能同时获得两个角色的使用权。该模型有以下几种约束:
(1)互斥角色
同一用户只能分配到一组互斥角色集合中至多一个角色,支持责任分离的原则。互斥角色是指各自权限互相制约的两个角色。对于这类角色一个用户在某一次活动中只能被分配其中的一个角色,不能同时获得两个角色的使用权。常举的例子:在审计活动中,一个角色不能同时被指派给会计角色和审计员角色。
(2)基数约束
一个角色被分配的用户数量受限;
一个用户可拥有的角色数目受限;
同样一个角色对应的访问权限数目也应受限,以控制高级权限在系统中的分配。例如公司的*有限的。
(3)先决条件角色
可以分配角色给用户仅当该用户已经是另一角色的成员;对应的可以分配访问权限给角色,仅当该角色已经拥有另一种访问权限。指要想获得较高的权限,要首先拥有低一级的权限。
(4)运行时互斥
允许一个用户同时拥有多个角色,但在系统运行中或部分特殊场景不可同时使用这两个角色,只能使用其中一种角色。
这些限制可以分成两类,即静态职责分离SSD(Static Separation of Duty)和动态职责分离DSD(Dynamic Separation of Duty)。
(1)静态职责分离(SSD)
当角色授权给用户时,需要判断当前用户是否被赋予了一个与新角色冲突的角色,冲突的角色位一个二元关系,任何一个用户在此场景下只能拥有其中一个角色。
(2)动态职责分离(DSD)
在角色分配时可以将冲突的角色赋予给同一个用户,但是在用户使用系统时,一次会话中不能同时激活两个角色。
RBAC3模型
即最全面的权限管理,它是基于RBAC0,将RBAC1和RBAC2进行了整合。这种模式即要维护好角色间的继承关系处理好分层,又要处理角色间的责任分离。模型公式:RBAC3 = RBAC1 + RBAC2 。
场景实战
需求场景
我们目前在做一款toB的产品,采用SaaS的模式对外B端客户提供服务。目标就是如何规划好平台的管理、租户的管理、租户应用的管理以及租户业务流程等内容的管理。我们将SaaS平台基本角色分为平台管理员、平台运维、平台开发、租户管理员、租户子管理员、租户其他角色组成。在这里,我将我们SaaS服务的权限部分设计分享出来。
设计说明
我们这套设计,涉及两部分,即完整的企业组织结构和角色组。所以这里针对部分概念进行说明。
组织(部门)
针对toB的产品,往往要考虑如何支撑起企业的组织结构,比如企业的部门层级。同时组织结构也可以与角色进行关联,用户加入组织后,就会自动获得该组织的默认角色。同时用户在调岗时,只需调整组织、角色即可批量调整。组织的另外一个作用是控制数据权限,把角色关联到组织,那么该角色只能看到该组织下的数据权限。
用户组(角色组)
在系统中,存在相同属性或操作功能的用户存在。随着使用的用户基数增大、角色类型增多时,分配的工作就会越发的繁琐。这里可以增加用户组的概念来统一规划这一部分用户的权限管理。在上面的设计中,角色组中的岗位、职位就充当了这部分的作用。以后其他用户加入对应的用户组(角色组)后,即可自动获取用户组的所有角色。退出用户组,同时也撤销了用户组下的角色,无须管理员手动管理角色。
职位 / 岗位
每个组织部门下都会有多个职位或岗位,比如IT技术部会有技术总监、技术经理、研发组长、开发等职位。虽然都在同一部门,但是每个职位的权限是不同的,职位高的拥有更多的权限。研发总监拥有所有权限,研发组长和开发拥有部分权限。有些特殊情况下,一个人可能身兼多职。
角色
角色是权限控制的最小单位(不是权限的最小单位),通过角色来进行权限资源的分配。在上面的设计中,就是遵循RBAC模式进行的设计。例如管理角色组,就涉及到了RBAC1,主管理员同时拥有子管理员的权限;同时也涉及到了RBAC2,一个组织只能有一个主管理员(基数约束 ),但是可以有多个子管理员。
含有组织、职位、用户组、角色模型
通过根据以上场景,平台的权限模型设计如下图:
以上基本就是关于我们一个项目的权限设计部分。
回归讨论点
关于沟通的问题,总的来说有以下几点:
1、对权限专业知识的学习和理解。
我记得在《致2019年的自己》总结中,也重点提到就是建立相应专业知识体系。为什么这个比较重要呢。在这里插入一个笑话。有次一小伙和我讨论关于SaaS。刚开始我给他介绍了我的一些SaaS的理解。而后让我比较头疼的是,对方聊的并非SaaS,而是“sass”。这区别可大了去。前者是服务设计模式或方法,后者是前端的一种CSS的技术。
回归正题,我们应该要建立起相对专业的知识体系,这个可能直接影响到我们对知识的认知、业务架构的设计等方面。同时在沟通过程中是否能在同一个点开展讨论,而不造成尴尬的局面。在沟通过程中,采用相对专业的术语,大家一听就懂并很快能领会。如果采用自己的语言可能造成对方无法理解。
2、需求设计者应了解相关的知识,而并非标榜“我是做需求的”。
其实,关于系统的设计、技术的选型是由需求来驱动的。毕竟项目管理最后要落眼到成本、进度上。我见过一些需求设计,需求点可能是不错的,但是缺乏相应的知识了解,导致在传达上或原型设计上出现的偏差甚至是错误。就以权限为例,我们在这个项目上其实走了一些弯路,核心的问题就在于需求,由于对于权限一些知识不了解,造成设计稿只能按照意思设计出来,研发却实现出现问题。
这里就体现的专业知识的重要性。需求设计者不一定要深层次的研究技术,而是要了解并理解它们的一些基本原理和设计思想。尤其是在和技术研发沟通过程中,如果采用的是专业性的知识沟通,那么既能节约沟通成本,也能缩小理解上的误差,更重要的是系统架构结构设计趋向更加稳定。
3、灵活的运用对应知识
一个技术的学习和理解,并不代表照抄照搬。比如,我在同朋友针对权限这块的交流中,真正的价值是对于权限的设计思路和方法,而并非某个项目上的具体实现。毕竟项目的“独特性”不能忽略。因为每个项目的业务不同,面对的用户群体不同,所以权限的具体细节自然不同。所以我们应该更加侧重于权限体系的知识,可以拓展对于不同场景,应该如何来设计。所以,我们应该先对一个知识有一定的学习和理解,接着就是灵活的应用和整合。
文章来源:DevOps;
编辑:云朵匠 | 数商云(微信ID:shushangyun_com)