一、权限系统介绍
权限系统简单定义:“who 对 what 进行 how 的操作”的表达式是否为真。
系统涉及到的概念:
- Who:用户(user),使权限的拥有者或主体。
- What:权限针对的对象或资源(resource)。
- How:具体的操作权限或方法行为(operator或method)。
引申之后,可以增加:
- 用户组:group用户的集合,方便对一批相同的用户进行管理。
- 角色:role权限的集合,方便对一批权限进行管理。
这里考虑用户组和角色,不考虑继承,即所有的用户组都是平级的关系,不可以继承包含,所有的角色也都是平级的关系,不可以包含和继承。
再次引申一下,资源不仅有平级的关系,还有级联的关系,拥有父级别的资源权限就有了所有子级别对应的权限了。
最后关系图如下:
二、Linux权限系统介绍
以linux的文件目录的权限管理为例,linux有用户,组,权限的概念。
一个linux用户可以属于多个linux用户组;同理一个linux用户组可以有多个用户。
Linux的文件或目录有4种权限:读,写,可执行,无权限。
一个linux文件或目录只能属于一个用户和一个组。
drwxr-xr-x user_00 users 16384 Sep 23 11:14 lamp
第1位表示文件类型。d是目录文件,l是链接文件,-是普通文件,p是管道
第2-4位表示这个文件的所有者是user_00,这个用户有r读,w写,x执行的权限。
第5-7位表示这个文件的组users包含的用户,他们具有的权限是r读,x执行。
第8-10位表示既不是文件所有者user_00,也不再users这个用户组里的用户具有的权限是x执行权限。
在这里,user_00, users对应who,文件和目录对应what,,rwx对应how操作。
三、Mysql权限系统介绍
Mysql的权限涉及到user,db,host,table_priv,columns_priv,proc_priv这几张表,它是分级别的,
它的存取控制分为两个阶段,
1:服务器检查你是否有连接权限;2:你发出的每个请求都要去验证权限。
权限涉及到全局层级,数据库层级,表层级,列层级,子程序层级。
Who对应用户。
What对应db,table,view,column,process,function等。
How对应connect,select,update,insert,delete,create,drop,alter,grant,process,file,execute操作。
角色role就是一组权限的集合,通过角色,管理员可以方便的把一组权限授予某个用户。
四、通用权限系统的设计
- 系统注册
- 审批流程注册
- 资源、操作、审批流注册。l
- 权限申请,撤销,修改,删除,续期
- 权限审批,驳回
- 权限批量开通
- 用户组管理
- 角色管理
- 移动审批
- 权限校验
- 权限查看,权限回收
- 通知服务,到期提醒,审批催办
- 权限Api服务(申请,注册,鉴权)
- 操作日志
五、腾讯罗盘权限系统DB设计
1.t_priv_system 系统注册表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
create table if not exists t_priv_system(
sys_id bigint primary key not null comment '主键,系统id',
sys_name varchar(255) comment '系统名称',
sys_owner varchar(2000) comment '系统负责人,逗号分隔多人',
sys_mark varchar(2000) comment '系统备注,系统用途,主页url',
vip_users longtext comment 'vip用户列表',
sys_status int comment '系统状态',
creator varchar(255) comment '创建者',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '系统注册表';
|
2.t_priv_process 权限审批流程,最多有9步审批,必须完成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
create table if not exists t_priv_process(
proc_id bigint primary key comment '主键,流程id',
sys_id bigint comment '流程所属系统id',
proc_name varchar(255) comment '流程名称',
creator varchar(255) comment '流程创建者',
stepnum int comment '流程总数<10',
stepobj1 varchar(255) comment '步骤1审批对象',
stepobj2 varchar(255) comment '步骤2审批对象',
stepobj3 varchar(255) comment '步骤3审批对象',
stepobj4 varchar(255) comment '步骤4审批对象',
stepobj5 varchar(255) comment '步骤5审批对象',
stepobj6 varchar(255) comment '步骤6审批对象',
stepobj7 varchar(255) comment '步骤7审批对象',
stepobj8 varchar(255) comment '步骤8审批对象',
stepobj9 varchar(255) comment '步骤9审批对象',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '权限审批流程,最多有9步审批,必须完成';
|
3. t_priv_approvalobj 流程审批对象定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
create table if not exists t_priv_approvalobj(
apvobj_id bigint primary key comment '主键,审批对象id',
stepobj_en varchar(255) comment '审批步骤对象英文名,唯一索引',
stepobj_cn varchar(255) comment '审批步骤对象中文名',
is_apicall int comment '是否api调用',
apiurl varchar(255) comment 'apiURL地址',
apiparam varchar(255) comment 'api参数',
apvobj_status int comment '审批对象状态',
created datetime comment '创建时间',
updated datetime comment '更新时间',
unique key uk_obj_en(stepobj_en)
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '流程审批对象定义';
|
4.t_priv_resources 系统资源信息表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
create table if not exists t_priv_resources(
prid bigint primary key auto_increment comment '主键,权限资源表',
sys_id bigint comment '资源所属系统',
resource_id varchar(255) comment '资源id',
resource_cn varchar(255) comment '资源名称',
creator varchar(255) comment '资源创建者',
resource_owner text comment '资源负责人,分号分割',
is_has_subresource int comment '是否有级联子资源权限',
subresource_type int comment '子资源类型 api或本地',
subresource_level int comment '字资源层数',
subresource_apiurl varchar(255) comment '资源涞源 api url',
is_canapply int comment '是否可以申请',
proc_id bigint comment '资源申请流程id',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '系统资源信息表';
|
5.t_priv_resource_operation 系统资源操作信息表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
create table if not exists t_priv_resource_operation(
proid bigint primary key comment '主键,操作id',
sys_id bigint comment '系统id',
resource_id varchar(255) comment '资源id',
operate_en varchar(255) comment '操作英文名read,write,admin',
operate_cn varchar(255) comment '操作中文名',
creator varchar(255) comment '创建者',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '系统资源操作信息表';
|
6.t_priv_user_apply 用户权限申请表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
create table if not exists t_priv_user_apply(
apply_id bigint primary key comment '申请单id,主键',
apply_user varchar(255) comment '权限申请人',
apply_group_id bigint comment '申请组id',
sys_id bigint comment '系统id',
sys_name text comment '系统名称',
permission_owner varchar(255) comment '权限获得者',
resource_id text comment '资源id 和子资源合并的',
resource_cn longtext comment '资源名称 和子资源合并的',
operate_en varchar(255) comment '资源操作id',
operate_cn varchar(255) comment '资源操作名称',
apply_reason text comment '申请原因',
apply_daylimit bigint comment '申请时长',
apply_status int comment '申请单状态',
last_remind_time datetime comment '上次催办时间',
process_id bigint comment '审批流程id',
stepnum int comment '审批总步数',
currstep int comment '当前审批步',
stepopers1 text comment '步骤1所有审批人 分号分割',
stepapprover1 varchar(255) comment '步骤1实际审批人',
stepresult1 int comment '步骤1审批结果0驳回,1通过',
stepmark1 varchar(255) comment '步骤1审批意见',
stepopers2 text comment '步骤2所有审批人 分号分割',
stepapprover2 varchar(255) comment '步骤2实际审批人',
stepresult2 int comment '步骤2审批结果0驳回,1通过',
stepmark2 varchar(255) comment '步骤2审批意见',
stepopers3 text comment '步骤3所有审批人 分号分割',
stepapprover3 varchar(255) comment '步骤3实际审批人',
stepresult3 int comment '步骤3审批结果0驳回,1通过',
stepmark3 varchar(255) comment '步骤3审批意见',
stepopers4 text comment '步骤4所有审批人 分号分割',
stepapprover4 varchar(255) comment '步骤4实际审批人',
stepresult4 int comment '步骤4审批结果0驳回,1通过',
stepmark4 varchar(255) comment '步骤4审批意见',
stepopers5 text comment '步骤5所有审批人 分号分割',
stepapprover5 varchar(255) comment '步骤5实际审批人',
stepresult5 int comment '步骤5审批结果0驳回,1通过',
stepmark5 varchar(255) comment '步骤5审批意见',
stepopers6 text comment '步骤6所有审批人 分号分割',
stepapprover6 varchar(255) comment '步骤6实际审批人',
stepresult6 int comment '步骤6审批结果0驳回,1通过',
stepmark6 varchar(255) comment '步骤6审批意见',
stepopers7 text comment '步骤7所有审批人 分号分割',
stepapprover7 varchar(255) comment '步骤7实际审批人',
stepresult7 int comment '步骤7审批结果0驳回,1通过',
stepmark7 varchar(255) comment '步骤7审批意见',
stepopers8 text comment '步骤8所有审批人 分号分割',
stepapprover8 varchar(255) comment '步骤8实际审批人',
stepresult8 int comment '步骤8审批结果0驳回,1通过',
stepmark8 varchar(255) comment '步骤8审批意见',
stepopers9 text comment '步骤9所有审批人 分号分割',
stepapprover9 varchar(255) comment '步骤9实际审批人',
stepresult9 int comment '步骤9审批结果0驳回,1通过',
stepmark9 varchar(255) comment '步骤9审批意见',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '用户权限申请表';
|
7. t_priv_permission 用户,组,角色权限表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
create table if not exists t_priv_permission(
permission_id bigint primary key comment '主键,权限id',
permission_owner_type varchar(255) comment '所有者类型User,group,Role',
permission_owner varchar(255) comment '权限所有者',
sys_id bigint comment '系统id',
resource_id text comment '资源id',
resource_cn longtext comment '资源名称',
operate_en varchar(255) comment '操作名称',
valid_from bigint comment '权限有效开始日期',
valid_to bigint comment '权限有效结束日期',
permission_status int comment '权限状态',
apply_id bigint comment '相关的申请单id',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '用户,组,角色权限表';
|
8. t_priv_log 操作日志表
二期工程,可以考虑扩展用户组和角色的定义及实现。
9. t_priv_group 用户组表
1
2
3
4
5
6
7
8
9
10
11
12
13
|
create table if not exists t_priv_group(
group_id bigint primary key comment '组id',
sys_id varchar(255) comment '关系类型,用户为主,组为主',
group_cn varchar(255) comment '组名',
creator varchar(255) comment '创建者',
group_mark text comment '组描述信息',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '用户组表';
|
10. t_priv_role 角色表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
create table if not exists t_priv_role(
role_id bigint primary key comment '主键,角色id',
sys_id bigint comment '系统id',
role_cn varchar(255) comment '角色名称',
creator varchar(255) comment '创建者',
role_mark text comment '角色描述',
valid_from bigint comment '角色有效开始日期',
valid_to bigint comment '角色有效结束日期',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '角色表';
|
11. t_priv_ugr_relation 用户,组,角色关系表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
create table if not exists t_priv_ugr_relation(
ugr_id bigint comment '主键',
ugr_type varchar(255) comment '关系类型,用户为主,组为主',
user_en varchar(255) comment '用户名',
group_en varchar(255) comment '用户所属组名',
role_en varchar(255) comment '用户所有角色名,组拥有角色名',
creator varchar(255) comment '创建者',
created datetime comment '创建时间',
updated datetime comment '更新时间'
)
ENGINE = InnoDB
default CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '用户,组,角色关系表';
|
六、腾讯罗盘功能模块设计
- 系统管理模块
(1) 新建编辑系统
(2) 系统查询
- 审批对象定义模块
(1)新建编辑审批对象
- 审批流程定义模块
(1)新建编辑审批流程
(2)查询审批流程
(3)查询审批流程相关的资源,申请单,权限单,权限用户
- 资源管理模块
(1)新建编辑资源信息
(2)新建编辑资源子信息
(3)新建编辑资源操作信息
(4)查询资源信息
(5)查询此资源相关的申请单,权限单,用户列表,组列表,角色列表
(6)权限用户资源操作权限清理功能
- 权限申请模块
(1)用户申请资源(子资源)相关操作的权限(批量)功能
(2)申请单状态处理
(3)申请单查询
(4)申请单审批进度查询
(5)申请单催办功能(邮件,短信,微信)
(6)批量开通权限功能
- 审批单管理模块
(1)审批单查询
(2)审批单(批量)处理
- 用户组管理模块
(1)新建编辑用户组
(2)用户组权限申请,添加,编辑
(3)用户组成员管理
(4)用户组角色管理
- 角色管理模块
(1)角色新建
(2)角色权限新建编辑
(3)角色查询
(4)角色相关用户,用户组查询
- 个人中心模块
(1)资源列表
(2)申请单列列表
(3)所属用户组列表
(4)所有角色列表
(5)所有权限列表
(6)权限续期
(7)资源权限列表
- Api模块
(1) 系统注册接口
(2) 资源注册接口
(3) 权限查询接口
(4) 鉴权服务接口
(5) 权限审批接口
- 移动端模块
七、腾讯罗盘权限系统用户界面设计
八、腾讯罗盘权限系统业务逻辑架构
-
权限申请模块
提供一个权限后台Server, 每当有用户提交申请单,则保存之后,给后台server发送请求,后台server接受到请求后就直接返回,并开启一个任务处理此申请单的相关信息,
主要有如下信息:
(1)获取申请单对应的审批流程
(2)获取每个流程步骤的审批人
(3)更新申请单的审批人信息和审批步骤信息
(4)通知相关人进行审批
申请单处理主要分为两步,
第一步就是用户提交申请单,系统会根据用户选择的目录对象情况,进行合并,生成对应的拼接好的resource_id,这个时候保存数据仅仅保存Apply_id、
Apply_user、Sys_id、Sys_name、Permission_owner、Resource_id、Resource_cn、Operate_en、
Apply_reason、Apply_daylimit、Apply_status、Updated这几个信息;同时启动后台服务,进行第二步处理。
第二步首先获取申请单对应的系统和资源id,从而获取到对应的审批流程,然后获取审批流对应的每个步骤审批角色的实际审批人,最后更新申请单的审批信息。
整体流程如下:
-
权限审批模块
这一步主要是资源的负责人对审批单进行审批操作,因为涉及到移动端审批,所以我们抽象出了审批公共操作。
主要流程如下:
采用先审批先处理的模式,以先操作的为主
-
权限鉴权验证模块
用户需要传递系统id,资源id及子资源id,操作id,鉴权用户
系统会先获取用户的角色,
用户所属组的角色
合并所有角色,获取角色的所有权限,
获取用户的权限,
获取用户所属组的权限
合并所有的权限
判断用户是否有对应的操作权限.
通用权限系统提供了鉴权api,供外部系统调用,判断用户是否有对相关资源操作的权限。
请求url:http://ca.oa.com/checkauth
请求参数:
{
User_en:"",//用户名
Obj_id:[],//资源id,存放样式如下[1001,1211,1213,54368]
Obj_operation: "",//资源操作
Sys_id:"" //系统id
}
整个鉴权的流程如下:
在处理鉴权参数的过程中,会把用户请求参数中的obj_id进行拼装,因为这个参数是一个数组 ,用户可以只传递一个资源id,也可以传递子资源id,例如:可以是这样[1001],也可以是这样[1001,1211],还可以是这样[1001,1211,1213],如果参数obj_id的参数有n个,那最终会形成n个条件,如对[1001,1211,1213]则会形成1001,1001|1211,1001|1211|1213,他们之间是或的关系,最后判断这些条件是否在数据库权限表t_auth_permission中是否找到对应的记录,如果可以找到,那么判断这次鉴权是成功的,否则就鉴权失败。为了加快鉴权的速度,这里还对resource_id增加了索引,同时增加了缓存处理。
整个方案的设计就可以实现,用户获得了一个父对象的权限(如手机Qzone),那么就获得了手
机Qzone级联的所有子对象的权限,实现了资源的级联管理,同时也实现了资源和操作的分离,
便于管理一个资源的不同操作权限。
- 罗盘权限验证介绍
罗盘采用了cakephp框架开发,cakephp框架的执行入口是controller控制器,控制页面具体的模块。
控制器执行过程:
流程整理如下:
- Controller构造函数__construct
- 所有组件Components构造函数__construct
- 所有组件Components的initialize函数
- Controller的beforeFilter函数
- 所有组件Components的startup函数
- Controller的beforeRender函数
- Controller中View类的render函数
- 所有组件的shutdown函数
- Controller的afterFilter函数
- Controller页面输出
九、罗盘验证流程
-
OaAuthComponent->startup函数
(1) isOaDomain
(2) checkSkipAuth($_GET[SKIP_AUTH_KEY],$_GET[‘__nocheck’])
(3) 是否是vipController (TofService,InfoSearch)
(4) Controller是否有skipLogin函数,有的话Controller->skipLogin
(5) 敏感权限检查会话获取用户名
(6) tof获取员工信息
(7) controller->isAuthorized() 函数调用
-
ReportsController中 isAuthorized 时候要checkProductAuth
ReportsController中isAuthorized 验证流程
(1) checkSkipAuth
(2) 管理员跳过权限验证
(3) 报表开发负责人和产品负责人验证
(4) 报表白名单访问验证
(5) 报表合作者访问验证
(6) 报表所属产品的负责人验证
(7) checkProductAuth($productId); //用户的产品权限验证
-
AppController中 getUserDepProdInfo时候要checkProductAuth
-
WxController中getUserDepProdInfo时候要checkProductAuth
-
CustomReportController中 config时候要checkProductAuth
十、腾讯罗盘权限系统接口Api设计
- 系统注册api
- 资源查询api
- 用户角色查询api
- 角色权限查询api
- 用户组查询api
- 组角色查询api
- 组权限查询api
- 用户权限查询api
- 鉴权api
- 操作查询api
十一、权限系统容灾设计
权限系统是一个开放的通用的部门级别的系统,可以为各种系统提供权限管理功能。
层级定义.