1 分钟阅读

简介

常规权限系统设计

材料1

权限设计=功能权限+数据权限

基本主体:用户 角色 资源。为用户赋予角色,角色操作资源,角色将用户与资源隔离。

从资源的角度说,权限管理分为

  1. 功能权限管理:资源的的新增、删除和修改
  2. 数据权限管理

    • 比如资源有地区维度,比如上海地区、北京地区。
    • 比如资源有部门维度,比如行政部、技术部
    • 维度之间有交集,横向关系。比如上海的行政部
    • 维度有包含关系,纵向关系,比如具备上海的权限,则自动具备浦东和宝山的权限

功能权限的控制:

  1. 我自己曾经一个简单实现,uid,资源id,optype(新增、删除等)
  2. 一些材料展示,类似于uid,url

数据权限设计,建议使用规则引擎。规则引擎的核心是Rule,而所谓的Rule 就是 if(Condition) then do(Action)。

具体的技术操作上,功能权限可以在系统上加filter,对某个url 没有权限,则直接滤掉。(在材料3中称为功能操作表)

材料2

管理设计 之 数据库结构设计

通用权限管理设计 之 数据权限

功能权限决定可以对资源采取何种操作,数据权限决定了用户/角色能不能看到这些资源。

经过用户、角色、资源的抽象后。用户本身有一定的属性,比如所在地区。资源本身有一定的属性,比如资源所在的地区、创建资源的人。所谓权限问题,就是用户与资源间属性的匹配问题。

那么从一个用户身份出发,我们可以拿到uid、所在地区,角色id。这些数据作为一个变量,拼接成一个规则字符串(比如json),这些规则字符串是一个条件树。

{
	groups:
		[
			{
				rules[
					{
						field: current role id,
						op: in,
						value:2,6
						typo: int
					}
				]
				op:and
			},
			{
				rules[
					{
						filed: current role id,
						op:equal,
						value:7,
						type:int
					},{
						field: employee id,
						op:equal,
						value: current employ id
						type:number
					}
				]
				op:and
			}
		]
		op:or
}

条件树附加在资源身上,用以识别哪些用户可以访问该资源:

  1. 可以被角色id为2或6的用户看到
  2. 假设资源有创建者id,那么如果当前用户角色id为7,并且创建了该资源,则可以看到

基于资源的权限系统-设计思路

  1. 一个权限系统的两个基本过程:授权和鉴权
  2. 角色可以用来做功能权限,做数据权限的话,会导致角色数量非常多
  3. 授权

材料3

2018.3.27

RBAC用户角色权限设计方案

说明:A-B 表,表示A表、B表、AB关联表。

就是用户通过角色与权限进行关联,此处用户与角色好理解,难点就是 “权限”在系统中如何描述。

  1. 用户-权限
  2. 用户-角色-权限,角色就是一组权限的集合,不直接将权限授予用户
  3. 用户-角色-权限-资源。假设一个权限描述为“删除文件A”,则应包括文件表、权限表、文件权限关联表。

    • 权限表,权限id、权限类型(增删改查)。
    • 文件(文件是资源的一种)表,略
    • 文件权限关联表, id、权限id、文件id

那么最后查一个用户有没有某个文件的权限

  1. 查询用户的角色id
  2. 查询角色id 对应的权限id
  3. 查询文件权限关联表,根据权限id看看有没有的对应的文件id。

也就是,查询用户 有没有操作文件的权限,落脚点在,文件权限关联表上,有没有对应的记录。

类似的,还有一个权限-功能操作表,功能操作表中,每条记录有一个url 前缀。通过关联表 可以查到 用户是否可以访问该url。

材料4

设计实例:如何以“用户”为单位的进行权限设计(一)

设计实例:如何以“权限”为单位的进行权限设计(二)

权限设计的方式有哪些?

  1. 以“用户”为单位的权限设计。适用的业务场景为:使用该系统的人之中,存在很多拥有同一类权限的人。
  2. 以“权限”为单位的权限设计。当使用该系统的人之中,很多人的权限是不一样的
  3. 以“用户”与“权限”结合的权限设计

自身实践

2017.12.29

笔者曾负责一个组件系统,用户可以新增组件,并对组件进行一些操作。具备以下要求:

  1. 管理员具有上帝视角,可以看到任何组件,进行任何操作
  2. 组件具有不同的类型,有的类型只能应用在一个os中(android或ios),有的可以应用在任何os中。因此,按照组件被应用的os、以及文件类型,也会有专门的管理员。比如android 管理员,ios 管理员等
  3. 一般开发只可以操作他本人创建的组件。但因为伙伴开发的需要,两个开发要都能够操作某一个组件。
  4. 操作组件的权限分为新增、修改和删除

最终关于权限这块的实现是

  1. 管理员和开发分开,开发者的权限管理按照功能权限设计,uid、资源id、操作类型(crud)
  2. 管理员的权限管理,只具体到是否可以看到资源,如果能看到资源即拥有对资源进行操作的crud权限
  3. 从管理员的角度出发,定义数据规则。比如“osType=android”即表示该用户具备查看所有适用于android 系统的组件。

该权限系统能这么设计,也是因为权限控制比较简单:

  1. 用户角色单纯的划分为管理员和开发两种,所以直接省了角色表
  2. 管理员和开发是平级的,只是管理员的权限更大一些
  3. 管理员没有功能权限的要求,即只要是管理员就可以crud

代码接口

  1. 方法上加注解,用来描述该方法 谁可以执行

     @PrivilegedOperation("admin=true")
     public void delete(Device device){
         ...
     }
    
  2. 使用filter, 根据请求url + uid 判断是否具有操作权限
  3. 硬编码
  4. 拦截所有的资源访问方法,或者说在所有的资源操作方法执行之前 “塞入” 一个处理逻辑,进行权限判断。比如

     @PrivilegedOperation
     public void delete(@PrivilegedResourceId(resouce="device") id="deviceId" Device device){
         ...
     }
    

    通过 PrivilegedOperation 拦截方法的执行,通过PrivilegedResourceId 描述资源的id

审批流程(未完成)

2018.4.23 新增

权限管理系统伴随的,通常会有一个审批流程系统,相关设计参见审批流程数据库设计

数据库表 设计中,也会有类和实例的关系

  1. flow:id,name
  2. node:id,flow_id,prev,next,handlers
  3. flow_example:id,title,uid(发起者),create_at,status(未发起,正在流转,已结束)
  4. process: id,node_id,uid(操作者),handle_at,flow_example_id

  5. flow + node 将一个流程的作用及先后 步骤 规定好
  6. flow_example 是一个流程的实例
  7. process,描述 在当前 实例下,进行到哪一个步骤

小结

权限系统涉及的主体:用户、角色、资源

权限分为

  1. 功能权限,描述uid可以对资源id进行哪些类型的操作。功能权限的管控有两种粒度:

    1. 比如增删改查,直接跟uid 绑定。
    2. 以develop(查询 + 新增 + 修改)、guest(查询)、master(查询 + 新增 + 修改)、owner(增删改查 + 授权) 等角色来 表示功能权限
  2. 数据权限,描述哪些用户可以看到哪些资源。

    • 数据规则可以附加在用户身上,描述用户可以看到哪些资源。比如isAdmin=true 或者 andoridAdmin=true
    • 也可以附加在资源身上,描述资源可以被哪些用户访问。比如每次新增一个资源,都记录一个id、uid/roleid、资源id

    前者将用户规则加在用户上,只适合简单系统,查询麻烦,更新资源方便。后者更符合“角色将用户与资源隔离的精神”,但每次资源操作都需要更新 用户与资源的关联关系。查询方便,更新资源麻烦。

留下评论