权限系统设计
我们比较常见的就是基于角色的访问控制,用户通过角色与权限进行关联。简单地说,一个用户拥有多个角色,一个角色拥有多个权限。这样,就构造成“ 用户-角色-权限 ”的授权模型。在这种模型中,用户与角色之间、角色与权限之间,通常都是多对多的关系。如下图:
基于这个,得先了解角色到底是什么?我们可以理解它为一定数量的权限的集合,是一个权限的载体。
例如:一个论坛的“管理员”、“版主”,它们都是角色。但是所能做的事情是不完全一样的,版主只能管理版内的贴子,用户等,而这些都是属于权限,如果想要给某个用户授予这些权限,不用直接将权限授予用户,只需将“版主”这个角色赋予该用户即可。
但是通过上面我们也发现问题了, 如果用户的数量非常大的时候,就需要给系统的每一个用户逐一授权 (分配角色),这是件非常繁琐的事情,这时就可以增加一个用户组,每个用户组内有多个用户,除了给单个用户授权外,还可以给用户组授权,这样一来,通过一次授权,就可以同时给多个用户授予相同的权限,而这时用户的所有权限就是用户个人拥有的权限与该用户所在组所拥有的权限之和。用户组、用户与角色三者的关联关系如下图:
通常在应用系统里面的权限我们把它表现为菜单的访问(页面级)、功能模块的操作(功能级)、文件上传的删改,甚至页面上某个按钮、图片是否可见等等都属于权限的范畴。有些权限设计,会把功能操作作为一类,而把文件、菜单、页面元素等作为另一类,这样构成“用户-角色-权限-资源”的授权模型。而 在做数据表建模时,可把功能操作和资源统一管理,也就是都直接与权限表进行关联,这样可能更具便捷性和易扩展性。 如下图:
这样设计的好处有两个:
一、 不需要区分哪些是权限操作,哪些是资源 ,(实际上,有时候也不好区分,如菜单,把它理解为资源呢还是功能模块权限呢?);
二、 方便扩展 ,当系统要对新的东西进行权限控制时,我只需要建立一个新的关联表“权限XX关联表”,并确定这类权限的权限类型字符串即可。
需要注意的是,权限表与权限菜单关联表、权限菜单关联表与菜单表都是一对一的关系。(文件、页面权限点、功能操作等同理)。也就是每添加一个菜单,就得同时往这三个表中各插入一条记录。
这样,可以不需要权限菜单关联表,让权限表与菜单表直接关联,此时,须在权限表中新增一列用来保存菜单的ID,权限表通过“权限类型”和这个ID来区分是种类型下的哪条记录。最后扩展出来的模型完整设计如下图:
随着系统的日益庞大,为了方便管理,如果有需要可引入角色组对角色进行分类管理,跟用户组不同,角色组不参与授权。
例如:当遇到有多个子公司,每个子公司下有多个部门,这是我们就可以把部门理解为角色,子公司理解为角色组,角色组不参于权限分配。另外,为方便上面各主表自身的管理与查找,可采用树型结构,如菜单树、功能树等,当然这些可不需要参于权限分配。
1.用户表:
2.角色表:
3.用户与角色关联表
4.用户组表
5.用户组与用户信息关联表
6.用户组与角色关联表
7.菜单表
8.页面元素表
9.文件表
10.权限表
11.权限与菜单关联表
12.权限与页面元素关联表
13.权限与文件关联表
14.功能操作表
15.权限与功能操作关联表
16.角色与权限关联表
17.操作日志表
几乎所有的管理后台都会涉及到权限的设计,权限控制是管理后台的重要功能,可以有效的提高系统的安全性,减少误操作、数据泄漏等风险的发生。但是,很多产品经理会对权限功能有一点害怕的心理,一方面是由于能参考的实例较少,权限管理算是一个“系统级”的基础功能,一般系统中只有管理员可以操作,不像其他功能可以通过去其他系统中试用体验,另一方面,对于权限功能普通用户无法操作使用,所以存在感较低,做好了也不会出彩,可没做好就会导致整个流程不通、产品崩溃。
一 RBAC模型
目前,接受度较高的功能权限模型是RBAC(Role-Based Access Control)模型。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。
1.角色的作用
如果没有角色的概念,直接用户对应权限,虽然会更加灵活,但是后台的数据表设计会变得复杂,操作成本也会很高,同时容错能力也会变得很差。
而引入“角色”概念后,用户与角色可为多对一或多对多的关系,当一个用户的角色为多对多时,当前用户的权限是多个角色的并集。此时只需要为角色赋予权限,能够大大减轻管理负担,同时将用户与权限解耦,提供更大的灵活性,同时整个设计的容错能力也提高了很多。
2.引入用户组
一些大型的平台上,如果用户数量较大,新增角色时,需要为大量用户分配新的角色,工作量巨大,此时可以引入用户组的概念,将这些用户拉到同一个用户组中,然后对整个用户组进行角色的指定,这就大大减少了角色分配的工作量。
同理如果权限较多时也会存在一样的问题,对角色进行权限设置时也需要大量的操作,此时可以考虑引入权限组的概念,将关联性较强的权限大包成组赋予角色,从而减少赋值时的工作量,现实中权限组的使用相对较少,因为系统中的权限一般来讲是有限的。需要注意的是即使有用户组或权限组的存在,也可以允许用户或权限与角色直接关联,这个可以视具体业务情况而定。
下图所示为mac系统中运行添加用户组,并以用户组为单位配置权限。
3. 角色继承的RBAC模型
在一个业务场景中,如果角色需区分:设计主管、设计组长、设计成员,并且管理方式为向下兼容时,则需使用角色继承的RBAC模型。上层角色继承下层角色的全部权限,且可额外赋予权限。
此时除了对角色进行定义,还需要管理角色间的关系,通过关系来体现角色的层级关系,从而达到继承权限的效果。角色的继承关系主要有两种:树形图和有向无环图。
继承关系常常来源于公司团队的组织结构,此时常将角色与组织结构进行关联达到继承角色模型的效果。如下图所示的赵同学,其角色是“三级团队负责人”,与其并列的小组中有多个“三级团队负责人”的角色,但依附于左侧的组织结构树,各级负责人仅有查看和操作自己下属子节点的权限。
4. 限制的RBAC模型
在一个产品或系统中,部分角色可能是需要隔离的、不允许被同时赋予一个人的。跟大家熟知的“不能既是‘运动员’又是‘裁判员’ ”一个道理。
因此,对于众多角色中的一组,只能是单选的关系,但多组角色之间可以共同存在。如下图中,一个用户可以既为设计师又为管理员,但在设计师角色组中仅能被赋予一个角色,在管理员角色组中也仅能被赋予一个角色。
此外,限制还有可能是数量上的,比如一个产品组中必须有且只有一个管理员,不允许删除或再分配管理员角色,仅允许将负责人角色变更。
限制的模型不仅仅对分配过程产生影响,有时即使拥有了多种角色,因为不同的角色对同一个功能的使用方式或数据会产生冲突,所以使用时也需要进行限制。如下图所示为同一时间仅允许以一个身份登录。
根据不同的业务需求,限制的形式很多。需要注意的是不能仅依赖后端限制,而是要在前端展示清晰的规则和恰当的限制,避免用户出错和沮丧。
三、权限的拆分与设计
通过RBAC模型已经能够很好的搭建起用户、角色与权限之间的关系了。但具体是什么样的关系,以及“权限”这个抽象的概念具体如何规划?
这些都需要分析清楚才能进一步设计出完善的权限系统。
首先需要知道,一般产品的权限由页面、操作和数据构成。页面与操作相互关联,必须拥有页面权限,才能分配该页面下对应的操作权限。数据可被增删改查。
整体关系如下图所示:
因此,在设计之初我们就需要考虑到未来可能区分角色的地方,尽量解耦、模块化。对于技术来说,每一个页面模块、每一个操作都最好使用独立的接口。对于设计来说,需要保障所有角色因为权限而屏蔽掉部分操作和数据后,页面和流程仍能体验流畅。
保证初期设计支持后,配置权限时,还需要注意以下几点:
(1)确定是否支持前端配置
如果角色和权限相对固定,则一般将角色与权限的关系可以写在后台,改动时需要后端变更且重新上线。这种情况适用于公司内部系统等只有一个使用主体的系统。
如果需要自定义角色或者每个角色在不同使用者的场景下有不同的权限,则需要将角色的定义、角色与权限之间的配置体现在“前端用户配置页面”。这种情况适用于有频繁变动的自定义角色权限,和有租户体系的系统。
(2)以基本单元拆分,以业务逻辑配置
一般可将每个对象的“增、删、改、查”各自作为一个基本的权限单元。打个比方,在“人员管理”中,查看人员列表、添加人员、删除人员、编辑人员信息最好拆分为4个权限单元。在技术和设计上,我们希望能尽量做到解耦和模块化。
但是在业务层面有些操作却是一体的。这些不能拆开的权限在“前端用户配置页面”中建议打包成一个整体提供配置。例如:如果我们确定在系统的现有和未来业务中,仅分为普通成员有“人员管理”的查看权限,管理员有操作权限,则可将“增、删、改”三个基本权限单位合并为“操作”权限进行配置。
(3)页面权限优先于操作和数据权限
必须配置了页面模块权限后,才能配置当前页面模块下具体的操作权限,以及页面模块的数据展示权限。
(4)查看权限优先于增删改权限
正常情况下,一定要先能查看某个模块或操作,其它的增删改操作才有意义。因此在设计时,应在获取查看权限前限制其它权限的配置,或者配置其它权限时默认赋予查看权限。
(5)角色与权限的多种关系
角色与权限的关系不仅是单纯“是/否关系”,还包括以某种限制进行操作,和以某种程度访问数据。
例如在“人员管理”中:
数据范围:用户拥有查看人员列表的权限,但仅能查看自己所在的团队;数据边界限制(上限等):添加人员时不能超过20个等。数据字段:HR能查看人员列表中包括职级、薪资等字段,其它角色仅能查看姓名邮箱等字段;
(6)角色与权限的设计表达
在传达一个系统的权限设计规则时,设计师常常习惯用主观最直接的方式表达想法,如用“当……时,就……”的句式来表达。但一个平台中涉及的权限规则是非常多的,当通篇以这样的形式描述时,表达对象将很难理解。
正确的描述方式:更清晰的是基于开发的语言,和技术模型的结果进行表达。将各角色与权限单元绘制成网格,每个交叉点网格中描述该角色与权限的数据关系和限制。
如下图所示:
四、需要注意的Tips
1. 隐形的admin
在可自定义角色和权限的系统中,一般需要预留一个admin角色来进行系统的初始配置,用于添加首批的业务人员和配置基本的角色。
有的系统中允许存在上帝视角的admin角色,则其可以作为“超级管理员”显示在角色配置的列表中。有的系统中不允许这种角色存在,则可将这种角色设置为隐形的状态,仅赋予维护系统的工作人员。
2. 初始权限的赋予
对于允许用户自行加入的系统,需要设定一至多个默认的角色,有时可以是仅有最基础权限的“游客”角色。
初始权限还可以与用户既有的某些数据字段进行关联,如添加用户时获取到用户的岗位为“设计师”,则直接赋予“设计师”角色的权限。
3. 人员管理中对自己的处理
在人员管理中,管理员角色处理自己时需要额外注意。因为如果修改或删除了自己角色后,可能导致系统没有管理角色,从而无法添加其他成员和正常运行。设计时可添加判断,当自己为唯一管理角色时,禁止编辑和删除。
4. 无页面权限的提示
虽然可以通过页面权限限制直接隐藏当前用户没有权限的页面,但不能排除用户获取到权限外的url地址。当用户意外访问到没有权限的页面时务必提供“无权限”的提示,避免用户认为系统bug。
总结一下,整个权限系统设计就是定义各个节点和节点间关系的过程。
节点包括:
用户;用户组;角色;角色组;权限(页面、操作、数据);权限组(页面、操作、数据);
权限管理是所有后台系统的都会涉及的一个重要组成部分,主要目的是对不同的人访问资源进行权限的控制,避免因权限控制缺失或操作不当引发的风险问题,如操作错误,隐私数据泄露等问题。
迄今为止最为普及的权限设计模型是RBAC模型,基于角色的访问控制(Role-Based Access Control)
RBAC-0模型是权限最基础也是最核心的模型,它包括用户/角色/权限,其中用户和角色是多对多的关系,角色和权限也是多对多的关系。
用户 是发起操作的主体,按类型分可分为2B和2C用户,可以是后台管理系统的用户,可以是OA系统的内部员工,也可以是面向C端的用户,比如阿里云的用户。
角色 起到了桥梁的作用,连接了用户和权限的关系,每个角色可以关联多个权限,同时一个用户关联多个角色,那么这个用户就有了多个角色的多个权限。
有人会问了为什么用户不直接关联权限呢?在用户基数小的系统,比如20个人的小系统,管理员可以直接把用户和权限关联,工作量并不大,选择一个用户勾选下需要的权限就完事了。
但是在实际企业系统中,用户基数比较大,其中很多人的权限都是一样的,就是个普通访问权限,如果管理员给100人甚至更多授权,工作量巨大。
这就引入了 "角色(Role)" 概念,一个角色可以与多个用户关联,管理员只需要把该角色赋予用户,那么用户就有了该角色下的所有权限,这样设计既提升了效率,也有很大的拓展性。
权限 是用户可以访问的资源,包括页面权限,操作权限,数据权限:
以上是RBAC的核心设计及模型分析,此模型也叫做RBAC-0,而基于核心概念之上,RBAC还提供了扩展模式。包括RBAC-1,RBAC-2,RBAC-3模型。下面介绍这三种类型
此模型引入了角色继承(Hierarchical Role)概念,即角色具有上下级的关系,角色间的继承关系可分为一般继承关系和受限继承关系。
一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。
而受限继承关系则进一步要求角色继承关系是一个树结构,实现角色间的单继承。这种设计可以给角色分组和分层,一定程度简化了权限管理工作。
基于核心模型的基础上,进行了角色的约束控制,RBAC2模型中添加了责任分离关系。
其规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时所应遵循的强制性规则。
责任分离包括静态责任分离和动态责任分离。主要包括以下约束:
即最全面的权限管理,它是基于RBAC-0,将RBAC-1和RBAC-2进行了整合。
当平台用户基数增大,角色类型增多时,而且有一部分人具有相同的属性,比如财务部的所有员工,如果直接给用户分配角色,管理员的工作量就会很大。
如果把相同属性的用户归类到某用户组,那么管理员直接给用户组分配角色,用户组里的每个用户即可拥有该角色,以后其他用户加入用户组后,即可自动获取用户组的所有角色,退出用户组,同时也撤销了用户组下的角色,无须管理员手动管理角色。
根据用户组是否有上下级关系,可以分为有上下级的用户组和普通用户组:
每个公司都会涉及到到组织和职位,下面就重点介绍这两个。
我们可以把组织与角色进行关联,用户加入组织后,就会自动获得该组织的全部角色,无须管理员手动授予,大大减少工作量,同时用户在调岗时,只需调整组织,角色即可批量调整。
组织的另外一个作用是控制数据权限,把角色关联到组织,那么该角色只能看到该组织下的数据权限。
每个组织部门下都会有多个职位,比如财务部有总监,会计,出纳等职位,虽然都在同一部门,但是每个职位的权限是不同的,职位高的拥有更多的权限。
总监拥有所有权限,会计和出纳拥有部分权限。特殊情况下,一个人可能身兼多职。
根据以上场景,新的权限模型就可以设计出来了,如下图:
根据系统的复杂度不同,其中的多对多关系和一对一关系可能会有变化
授权即给用户授予角色,按流程可分为手动授权和审批授权。权限中心可同时配置这两种,可提高授权的灵活性。
有了上述的权限模型,设计表结构就不难了,下面是多系统下的表结构,简单设计下,主要提供思路:
在项目中可以采用其中一种框架,它们的优缺点以及如何使用会在后面的文章中详细介绍。
权限系统可以说是整个系统中最基础,同时也可以很复杂的,在实际项目中,会遇到多个系统,多个用户类型,多个使用场景,这就需要具体问题具体分析,但最核心的RBAC模型是不变的,我们可以在其基础上进行扩展来满足需求。
权限管控可以通俗的理解为权力限制,即不同的人由于拥有不同权力,他所看到的、能使用的可能不一样。对应到一个应用系统,其实就是一个用户可能拥有不同的数据权限(看到的)和操作权限(使用的)。
Access Control List,ACL是最早的、最基本的一种访问控制机制,是基于客体进行控制的模型,在其他模型中也有ACL的身影。为了解决相同权限的用户挨个配置的问题,后来也采用了用户组的方式。
原理:每一个客体都有一个列表,列表中记录的是哪些主体可以对这个客体做哪些行为,非常简单。
例如:当用户A要对一篇文章进行编辑时,ACL会先检查一下文章编辑功能的控制列表中有没有用户A,有就可以编辑,无则不能编辑。再例如:不同等级的会员在产品中可使用的功能范围不同。
缺点:当主体的数量较多时,配置和维护工作就会成本大、易出错。
Discretionary Access Control,DAC是ACL的一种拓展。
原理:在ACL模型的基础上,允许主体可以将自己拥有的权限自主地授予其他主体,所以权限可以任意传递。
例如:常见于文件系统,LINUX,UNIX、WindowsNT版本的操作系统都提供DAC的支持。
缺点:对权限控制比较分散,例如无法简单地将一组文件设置统一的权限开放给指定的一群用户。主体的权限太大,无意间就可能泄露信息。
Mandatory Access Control,MAC模型中主要的是双向验证机制。常见于机密机构或者其他等级观念强烈的行业,如军用和市政安全领域的软件。
原理:主体有一个权限标识,客体也有一个权限标识,而主体能否对该客体进行操作取决于双方的权限标识的关系。
例如:将军分为上将>中将>少将,军事文件保密等级分为绝密>机密>秘密,规定不同军衔仅能访问不同保密等级的文件,如少将只能访问秘密文件;当某一账号访问某一文件时,系统会验证账号的军衔,也验证文件的保密等级,当军衔和保密等级相对应时才可以访问。
缺点:控制太严格,实现工作量大,缺乏灵活性。
(Attribute-Based Access Control),能很好地解决RBAC的缺点,在新增资源时容易维护。
原理:通过动态计算一个或一组属性是否满足某种机制来授权,是一种很灵活的权限模型,可以按需实现不同颗粒度的权限控制。
属性通常有四类:
例如:早上9:00 11:00期间A、B两个部门一起以考生的身份考试,下午14:00 17:00期间A、B两个部门相互阅卷。
缺点:规则复杂,不易看出主体与客体之间的关系,实现非常难,现在应用的很少。
RBAC的核心在于用户只和角色关联,而角色代表对了权限,是一系列权限的集合。
RBAC三要素:
在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。角色与角色的关系同样也存在继承关系防止越权。
RBAC模型可以分为:RBAC 0、RBAC 1、RBAC 2、RBAC 3 四个阶段,一般公司使用RBAC0的模型就可以。另外,RBAC 0相当于底层逻辑,后三者都是在RBAC 0模型上的拔高。
我先简单介绍下这四个RBAC模型:
RBAC 0模型: 用户和角色、角色和权限多对多关系。
简单来说就是一个用户拥有多个角色,一个角色可以被多个用户拥有,这是用户和角色的多对多关系;同样的,角色和权限也是如此。
RBAC 0模型如下图:没有画太多线,但是已经能够看出多对多关系。
RBAC 1模型: 相对于RBAC 0模型,增加了角色分级的逻辑,类似于树形结构,下一节点继承上一节点的所有权限,如role1根节点下有role1.1和role1.2两个子节点。
角色分级的逻辑可以有效的规范角色创建(主要得益于权限继承逻辑),我之前做过BD工具(类CRM),BD之间就有分级(经理、主管、专员),如果采用RBAC 0模型做权限系统,我可能需要为经理、主管、专员分别创建一个角色(角色之间权限无继承性),极有可能出现一个问题,由于权限配置错误,主管拥有经理都没有权限。
而RBAC 1模型就很好解决了这个问题,创建完经理角色并配置好权限后,主管角色的权限继承经理角色的权限,并且支持针对性删减主管权限。
RBAC 1模型如下图:多对多关系仍旧没有改变,只增加角色分级逻辑。
[图片上传中...(-95cc0-1640060170347-0)]
RBAC 2模型: 基于RBAC 0模型,对角色增加了更多约束条件。
如角色互斥,比较经典的案例是财务系统中出纳不得兼管稽核,那么在赋予财务系统操作人员角色时,同一个操作员不能同时拥有出纳和稽核两个角色。
如角色数量限制,例如:一个角色专门为公司CEO创建的,最后发现公司有10个人拥有CEO角色,一个公司有10个CEO?
这就是对角色数量的限制,它指的是有多少用户能拥有这个角色。
RBAC 2 模型主要是为了增加角色赋予的限制条件,这也符合权限系统的目标:权责明确,系统使用安全、保密。
RBAC 3模型: 同样是基于RBAC0模型,但是综合了RBAC 1和RBAC 2的所有特点。这里就不在多描述,读者返回去看RBAC 1和RBAC 2模型的描述即可。
RBAC 权限模型由三大部分构成,即用户管理、角色管理、权限管理。用户管理按照企业架构或业务线架构来划分,这些结构本身比较清晰,扩展性和可读性都非常好。角色管理一定要在深入理解业务逻辑后再来设计,一般使用各部门真实的角色作为基础,再根据业务逻辑进行扩展。权限管理是前两种管理的再加固,做太细容易太碎片,做太粗又不够安全,这里我们需要根据经验和实际情况来设计。
用户管理中的用户,是企业里每一位员工,他们本身就有自己的组织架构,我们可以直接使用企业部门架构或者业务线架构来作为线索,构建用户管理系统。
需要特殊注意:
实际业务中的组织架构可能与企业部门架构、业务线架构不同,需要考虑数据共享机制,一般的做法为授权某个人、某个角色组共享某个组织层级的某个对象组数据。
在设计系统角色时,我们应该深入理解公司架构、业务架构后,再根据需求设计角色及角色内的等级。一般角色相对于用户来说是固定不变的,每个角色都有自己明确的权限和限制,这些权限在系统设计之处就确定了,之后也轻易不会再变动。
(1)自动获得基础角色
当员工入职到某部门时,该名员工的账号应该自动被加入该部门对应的基础角色中,并拥有对应的基础权限。这种操作是为了保证系统安全的前提下,减少了管理员大量手动操作。使新入职员工能快速使用系统,提高工作效率。
(2)临时角色与失效时间
公司业务有时需要外援来支持,他们并不属于公司员工,也只是在某个时段在公司做支持。此时我们需要设置临时角色,来应对这种可能跨多部门协作的临时员工。
如果公司安全级别较高,此类账号默认有固定失效时间,到达失效时间需再次审核才能重新开启。避免临时账号因为流程不完善,遗忘在系统中,引起安全隐患。
(3)虚拟角色
部门角色中的等级,可以授权同等级的员工拥有相同的权限,但某些员工因工作原因,需要调用角色等级之外的权限,相同等级不同员工需要使用的权限还不相同。这种超出角色等级又合理的权限授予,我们可以设置虚拟角色。这一虚拟角色可集成这一工作所需的所有权限,然后将它赋予具体的员工即可。这样即不用调整组织架构和对应的角色,也可以满足工作中特殊情况的权限需求。
(4)黑白名单
白名单:某些用户自身不拥有某部门的顶级角色,但处于业务需求,需要给他角色外的高级权限,那么我们可以设计限制范围的白名单,将需要的用户添加进去即可。在安全流程中,我们仅需要对白名单设计安全流程,即可审核在白名单中的特殊用户,做到监控拥有特殊权限的用户,减少安全隐患。
黑名单:比较常见的黑名单场景是某些犯了错误的员工,虽然在职,但已经不能给他们任何公司权限了。这种既不能取消角色关联,也不能完全停用账号的情况,可以设置黑名单,让此类用户可以登录账号,查看基本信息,但大多数关键权限已经被黑名单限制。
权限管理一般从三个方面来做限制。页面/菜单权限,操作权限,数据权限。
(1)页面/菜单权限
对于没有权限操作的用户,直接隐藏对应的页面入口或菜单选项。这种方法简单快捷直接,对于一些安全不太敏感的权限,使用这种方式非常高效。
(2)操作权限
操作权限通常是指对同一组数据,不同的用户是否可以增删改查。对某些用户来说是只读浏览数据,对某些用户来说是可编辑的数据。
(3)数据权限
对于安全需求高的权限管理,仅从前端限制隐藏菜单,隐藏编辑按钮是不够的,还需要在数接口上做限制。如果用户试图通过非法手段编辑不属于自己权限下的数据,服务器端会识别、记录并限制访问。
数据权限如何管控
数据权限可以分为行权限和列权限。行权限控制:看多少条数据。列权限控制:看一条数据的多少个字段
简单系统中可以通过组织架构来管控行权限,按照角色来配置列权限,但是遇到复杂情况,组织架构是承载不了复杂行权限管控,角色也更不能承载列的特殊化展示。
目前行业的做法是提供行列级数据权规则配置,把规则当成类似权限点配置赋予某个角色或者某个用户。
网易有数做法:
https://youdata.163.com/index/manual/o/6System_management/data_role.html
1.超级管理员
超级管理员是用来启动系统,配置系统的账号。这个账号应该在配置好系统,创建管理员之后被隐藏起来。超级管理员账号拥有系统中全部权限,可穿梭查看各部门数据,如果使用不恰当,是系统管理的安全隐患。
2.互斥角色如何处理
当用户已经有用的角色和即将添加的角色互相互斥时,应该在添加新角色时,提示管理员因角色互斥的原因,无法进行新角色添加。如需添加,要先撤销掉前一个角色,再添加新角色。
3.用户管理权限系统设计一定要简单清晰
在设计权限系统之处,一定要理清思路,一切从简,能不增加的多余角色和权限逻辑,就一定不要增加。因为随着公司业务的扩大,权限和角色也会随之增多,如果初期设计思路不严谨,那么权限系统会随着业务的扩大而无限混乱下去,此时再来整理权限,已经太晚了。所以初期设计就一定要条理清晰,简单明了,能避免后续非常多不必要的麻烦。
4.无权提示页
有时员工 A 会直接给员工 B 分享他当下正在操作的页面,但有可能员工 B 无权查看。此时我们应该在这里考虑添加「无权提示页」,避免粗暴的 404 页面让员工 B 以为是系统出错了。
当前使用最普遍的是RBAC模型,即用户-角色-权限。该模型可以满足大部分的业务场景,较为细化复杂的权限,也可结合ABAC模型来实现。
系统会有若干个功能,但是不同模块功能会对应企业中不同的管理者,那么权限不尽相同。为了灵活分配给不同用户不同权限,衍生出了用户-角色-权限模型,一个角色封装多个权限操作,可直接将该角色分配给用户:
若大量用户使用同一个角色,则每次分配,仍会有很多重复劳动,所以衍生出了「用户组」的概念,将用户绑定到一个组上,可为这个组赋予一个角色,组下的用户均有这个角色:
同理,角色之间有很多相同的权限,每个维护角色时都要勾选大量的权限,因此可以增加「权限组」的概念,将通用的权限打包成组,分配给角色。
在设计系统时,可具体问题具体分析,较简单的系统,无需设计的太过复杂,越复杂越灵活,同时越灵活也越复杂;要考虑实际业务场景、培训成本等各个因素。在设计表结构的时候,可以预留出组的概念,产品设计层面0到1,无需设计过于复杂。
用户,即账号的概念,登录系统要有账号,账号关联着角色,决定可以看到什么、操作什么;每个账号可看到的数据范围也各有不同,因此可以根据不用行业的字段属性,去为账号配置数据范围,也就是基于属性的权限验证(ABAC: Attribute-Based Access Control)。
权限可以再细分为字段权限和菜单功能权限,不同账号进入系统时,看到的菜单、菜单中的功能都有所不同,进入同一个页面时,页面中的字段是否展示,也各不相同。
因此,我们在设计权限体系时,可以参考该思考方式去设计。
5步搭建权限管理:创建账号、创建角色、字段权限设计、菜单功能权限设计、数据范围设计。本文将以人事系统为例,进行权限搭建说明。
孤立的系统,可单独设计注册逻辑、后台添加账号逻辑进行账号的创建;人事系统作为员工入离职的核心,因此可在入职成功时,系统自动为其创建一个单点登录账号;离职时,自动失效账号。
如果需要引用用户组的概念,则可根据一些特定的规则,例如部门、岗位等,自动加入某用户组。也可设计页面为其手动维护到用户组中。
创建角色时,可设置该角色属于哪个角色组,没有角色组概念则可忽略;是否可向下赋权,即该角色是否可设置子角色并分配权限,一般非集团企业,可不进行此设计。
一般情况下,创建角色只要维护角色名称和描述即可。较为复杂的,可引入角色组或向下赋权的概念,例如集团企业。
在角色下,可为不同系统模块分配字段权限;例如,在员工管理模块,可编辑基本信息、工作信息、学历信息,在个人档案模块仅可只读基础信息(具体如何设计系统表结构、字段等,本文不做详细说明,后面有机会会在别的文章进行说明)。
账号是否有菜单功能权限,即是否配置了相关的接口权限;在产品设计时,需要梳理好各个页面功能的颗粒度,这样研发同学在拆分接口的时候,才能更好的规划。
一般权限配置都是由系统管理员来完成,所以保证逻辑通畅、页面较清晰即可;商业化的产品,一般会将菜单功能梳理出来列举好,让用户学会自己勾选配置,通常层级为:目录模块-菜单-功能。如果是内部系统定制化开发,则可不必拘泥于形式,能配置即可,例如下图,先在后台把菜单与功能的接口配置好,再在角色中勾选这些接口,组合成角色-权限。
当多个人拥有相同的菜单和功能,但管理的数据范围有所不同时;例如:A和B同样是HRBP,管理着团队的入离职等情况,但A负责的是产品部,B负责的是企业内所有组长等。此时就需要为不同人划分不同的数据范围,由于人事系统主要的划分属性来源于员工属性,因此在设计员工表的时候,可根据业务划分成不同对象(或者说是表),对象下拥有不同的字段(或者说是员工属性),再根据字段的不同类型,将逻辑判断区分出来;例如,日期格式字段,逻辑判断可为>/≥/</≤/介于/≠/=等;字典值字段,逻辑判断可为属于/不属于/为空/不为空等。
如果是其他行业,则可根据具体场景划分出不同属性;这个就是基于属性的权限验证(ABAC: Attribute-Based Access Control)。
当每个人都有数据范围时,在做数据共享类似功能时,例如员工档案数据分享时,可仅分享数据统计的逻辑、数据来源,而能看到哪些字段和数据范围则取决于账号本身的权限。
一般针对中小型企业的商业化产品的权限都不会做的过于复杂,但是万变不离其宗,无论页面如何设置,其本质没有什么变化。以钉钉举例,钉钉在设置管理范围时,仅支持按组织架构划分,由于钉钉人事模块是后发展起来的,一开始并没有过多的内置各种属性字段,因此管理范围也只能做成根据组织架构划分。但是日常基本够用了。
当「智能人事」中权限选择细分时,可以看到在单独这个业务下,钉钉也是划分了不同的人事模块,并且不同模块可单独配置字段权限,虽然现在只有员工档案一个模块。但是可以看到架构基本还是这一套,后面也支持各种扩展。
基本模式,class和action分开
但我们实际业务中,我们多把class和action合在一起
如果是内容类,比如cms这种,我们一般采用拆开的方式,因为这种资源-操作拆分的方式有意义。
如果是审批类,比如oa系统这种,我们一般采用合并的方式。
当业务越来越多,都需要权限管理系统的时候,通用权限管理系统就显得迫在眉睫。
而通用权限管理系统中,粒度划分尤为重要。
1.粒度划分
权限的最小粒度,一般以 一个接口为一条权限 。
比如 /bbs/create (代表论坛发帖) 这种接口为最小粒度,好处是便于管理。
而如果是 /bbs/create?cid=123&pid=456 这种,我们还是按照 /bbs/create 这种粒度划分,而里面的参数,一般的做法是在create这个接口里面再单独做权限判断。保证最小粒度的权限足够简单,权限管理部分职责单一,而与业务强耦合的功能放在业务里做。
也就是可以分成 平台权限 和 业务权限。
2.结构图
如图所示,通用权限管理系统中,用户可能会是域账号登陆,外部的域账号只与用户关联与系统无关。
为了适应不同场景,用户、应用、角色三者会关联成一张表。
这个表的作用是告诉系统, 哪个用户在哪个应用下对应哪一个角色 。
角色跟资源的关系还是跟普通的权限系统保持一致。
如 用户A 在 OA 下是 管理员,用户A 在 ACL 下是 用户。
通过这个对应关系,基本可以满足各种不同的应用场景。
而数据资源作为可选项,在某些场景下也可能存在。
如用户A 在 DZZ 游戏下是管理员,用户A 在DQY 游戏下是GM。
这里需要关注的一点是,这个表基本都是一个用户对应一个游戏为一条数据,而不会一个用户对应多个游戏为一条数据。这是因为首先权限系统比较复杂,我们这么做为了使权限管理更加简单不使问题复杂化。另一个原因是真实使用场景中,这种一对多的关系比较少,复用率很低,而且变化的时候不灵活。
对于B端产品,可能会有多个系统部署在用户机器上,比如一个机器上有OA和ERP系统,两套系统都需要账户体系和权限管理系统,这个时候就可以用通用权限管理系统互相打通。但是通用权限系统貌似减少了开发成本,但是也有可能维护成本极高,要使用不同的系统之间的差异。
因此,设计通用权限管理系统的时候,往往通用权限系统只做一部分最简单的,最基础的权限控制,而跟业务耦合的权限管理则在各自系统本身的业务逻辑里面。
所以,才有了文章开头的粒度问题。
我们的粒度一般分到URI级别,每一个请求没有个URI都是一个资源,一个资源对应一条权限。
比如用户发帖这种问题,发帖接口可能是一个接口,但是里面还会涉及到用户是否可以发图片的这种权限。
这种情况下,比较推荐的做法是用户发帖还是一个权限,由通用权限系统处理,而发图片权限,则再由业务逻辑判断。class+action这一层最好职责单一,不掺杂业务判断,这样比较好管理,同时保持通用权限管理系统的纯粹性。
在实际场景中,每个项目都有菜单,当业务场景比较单一的情况下,菜单也可以做到通用权限管理系统中统一处理。
一个菜单对应一个资源,也可以对应多个资源
一般流程为:应用获取菜单总数据,查询这个用户信息,再通过权限系统查询这个用户uid对应每个资源是否有权限,然后洗掉没权限的菜单,留下这个用户在这个应用下的菜单。
如图所示,菜单可以只跟用户关联,所有的操作都是从用户这个纬度进行查询,这也也保持了基础权限管理系统的完整性。
当然,菜单可以不做在通用权限管理系统里做在业务层里,具体问题具体分析。
现实应用场景中,对于应用来说,简单的做法是用户的相关权限操作都去请求通用权限管理系统,能操作就返回true,不能操作返回false。但如果需要的权限请求非常多,也可以一次性全部取全,再业务层自己处理。
实际开发中,权限管理原则大部分是视图不做强限制,数据强限制。
用户如果足够多,且权限差不多是,会分成用户组进行管理。
用户权限的继承基本在实际场景下不会考虑,因为一旦后期用户权限发生改变,牵连过大。
而用户权限的互斥一般只在业务在使用,保证通用权限管理系统的可维护性和通用性,特殊需求业务自己要求就好了。
实现业务系统中的用户权限管理 设计篇
B/S系统中的权限比C/S中的更显的重要 C/S系统因为具有特殊的客户端 所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现 而B/S中 浏览器是每一台计算机都已具备的 如果不建立一个完整的权限检测 那么一个 非法用户 很可能就能通过浏览器轻易访问到B/S系统中的所有功能 因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测 让经过授权的用户可以正常合法的使用已授权功能 而对那些未经授权的 非法用户 将会将他们彻底的 拒之门外 下面就让我们一起了解一下如何设计可以满足大部分B/S系统中对用户功能权限控制的权限系统
需求陈述不同职责的人员 对于系统操作的权限应该是不同的 优秀的业务系统 这是最基本的功能
可以对 组 进行权限分配 对于一个大企业的业务系统来说 如果要求管理员为其下员工逐一分配系统操作权限的话 是件耗时且不够方便的事情 所以 系统中就提出了对 组 进行操作的概念 将权限一致的人员编入同一组 然后对该组进行权限分配 权限管理系统应该是可扩展的 它应该可以加入到任何带有权限管理功能的系统中 就像是组件一样的可以被不断的重用 而不是每开发一套管理系统 就要针对权限管理部分进行重新开发 满足业务系统中的功能权限 传统业务系统中 存在着两种权限管理 其一是功能权限的管理 而另外一种则是资源权限的管理 在不同系统之间 功能权限是可以重用的 而资源权限则不能关于设计
借助NoahWeb的动作编程理念 在设计阶段 系统设计人员无须考虑程序结构的设计 而是从程序流程以及数据库结构开始入手 为了实现需求 数据库的设计可谓及其重要 无论是 组 操作的概念 还是整套权限管理系统的重用性 都在于数据库的设计
我们先来分析一下数据库结构
首先 action表(以下简称为 权限表 ) gorupmanager表(以下简称为 管理组表 ) 以及master表(以下简称为 人员表 ) 是三张实体表 它们依次记录著 权限 的信息 管理组 的信息和 人员 的信息 如下图
这三个表之间的关系是多对多的 一个权限可能同时属于多个管理组 一个管理组中也可能同时包含多个权限 同样的道理 一个人员可能同时属于多个管理组 而一个管理组中也可能同时包含多个人员 如下图
由于这三张表之间存在着多对多的关系 那么它们之间的交互 最好使用另外两张表来完成 而这两张表起著映射的作用 分别是 actiongroup 表(以下简称 权限映射表 )和 mastergroup 表(以下简称 人员映射表 ) 前者映射了权限表与管理组表之间的交互 后者映射了人员表与管理组表之间的交互 如下图
另外 还需要一张表来控制系统运行时左侧菜单中的权限分栏
也就是 权限分栏表 如下图
根据上面的分析 我们进行数据库结构设计 如下图
点击这里查看权限管理系统数据表字段设计
为了能够进行良好的分析 我们将数据库结构图拆分开来 三张实体表的作用已经很清晰 现在我们来看一下两张映射表的作用
一 权限映射表 如下图
首先 我们来了解一下权限映射表与管理组表以及权限表之间的字段关联
看图中的红圈 先看gorupid字段相关联 这种关联方式在实际数据库中的表现如下图
如图中所示 管理组表中 超级管理员 的groupid为 那么权限映射表中groupid为 的权限也就是 超级管理员 所拥有的权限
使用groupid字段关联 是为了查到一个管理组能够执行的权限有哪些 但这些权限的详细信息却是action字段关联所查询到的
action字段相关联在数据库中的表现如下图
通过这种关联 才查询到权限映射表之中那些权限的详细信息 综合起来 我们就知道了一个管理组可以执行的权限有哪些 以及这些权限的详细信息是什么
或许你会问 为什么不使用actionid字段相关联呢因为
权限表中的id字段在经过多次的数据库操作之后可能会发生更改 权限映射表中仅仅记录著一个管理组可以执行的权限 一旦权限表中的id更改 那么权限映射表中的记录也就更改了 一个管理组可以执行的权限势必将出错 这是非常不希望的考虑到上面的情况 所以应该使用action字段相关联 因为
在权限表中 id可能发生变化 而action字段却是在任何情况下也不可能发生变化的
权限映射表中记录的action字段也就不会变 一个管理组可以执行的权限就不会出错了
二 人员映射表 如下图
我们来了解一下人员映射表与管理组表以及人员表之间的字段关联 如下图
lishixinzhi/Article/program/net/201311/13938
1、首先在oracle数据库创建教学管理系统需,要用到的数据表如下。
2、上述中数据表的其他信息创建。(departments表、class表、students表、course表)。
3、步骤一中数据表的其他信息创建。(teacher表、teach表、score表)。
4、然后对创建的数据表按要求输入数据值。
5、最后按照上述要求继续用插入语句添加数据值。
6、查询学生信息表中学生的学号、姓名、性别、出生日期、班级编码,并以汉字标题显示字段名。就完成了。
所谓权限管理,一般是根据系统设置的安全规则或者安全策略,使用户在整个系统资源下只能访问自己被授权的资源,这样可以在保证数据安全的同时提高系统的使用效率。
常用权限--数据
企业一些重要的资料,比如财务数据,并不需要让员工知晓,这个时候就需要使用“数据权限”给员工授权,授权之后,相关数据就可以只给特定的员工查看。
常用权限--功能
和数据权限同样的道理,不同岗位的员工需要不同的功能权限,比如给张三赋予一个“销售经理”的角色,这个角色具有查询、添加、修改、删除销售部门员工的权利。那么张三就能够进入系统,进行此类的操作,若没有赋予这个角色,则没有这些权限。
权限示例
一般来说,权限系统会提供以下功能:
1.角色管理界面,由用户定义角色,给角色赋予权限;
2.用户角色管理界面,由用户给系统用户赋予角色。
一个很简单的例子,比如你开过个人淘宝店,系统上就有众多权限管理功能,比如给客服开通商品的上传、删除权限。
权限应尽可能详细,除了为主体授权,还应可以为部门、岗位、角色等授权。
例如,在角色管理界面我们能看到系统上相关角色的记录,管理员可以对角色进行增删改查,并为特定的角色赋权。
在“更多”这里,会出现各种需要授权的模块,访问过滤则为IP和时段控制。
当选择功能授权,进入下图界面,勾选需要授权的功能模块即可。
到这里,角色功能的授权就完成了。
当然,权限的使用通常要配合流程和表单等基础功能,这里不再演示,完整功能可搜索“learun”进行在线体验。