在20世纪90年代期间,大量专家学者和研究单位对RBAC(Role-Based Access Control)的概念进行了深入研究,先后提出了许多类型的RBAC模型,其中以美国George Mason大学信息安全技术实验室(LIST)提出的RBAC96模型最具系统性,并得到普遍的公认。
传统的权限分配的方式是将用户与权限绑定,也就是直接将权限绑定到用户身上,例如之前盛行的ACL模型。这种做法的缺陷在于效率低下,设置权限时没有统一的标准。当用户量过多时,操作复杂麻烦。
在RBAC中需要对系统的所有资源进行权限控制,系统资源可以简单地概括为静态资源(功能操作、数据列)和动态资源(数据),也分别称为对象资源和数据资源。RBAC的目标是对系统中所有对象资源和数据资源进行权限控制。
RBAC是什么
RBAC基于角色的访问控制是用户通过角色与权限进行关联,为什么不直接给用户分配权限呢?简单来说,一个用户拥有多个角色,每个角色拥有若干权限。这样就构成了“用户-角色-权限”的授权模型。在这个模型中,用户与角色、角色与权限之间是多对多的关系。
角色是什么呢?
角色可以理解为一定数量的权限的集合,也就是权限的载体。当用户数量越来越大的时候,就需要为用户分组,每个用户组内拥有不同的用户,除了可以给用户授权外,也可以给用户组授权。如此一来,用户拥有的所有权限就是用户个人拥有的权限与该用户所在用户组拥有的权限之和。
用户组与角色有何区别呢?
用户组是用户的集合,但不是权限的集合。角色同时具有用户集合和权限集合的概念,角色是把两个集合联系在一起的中间媒介。如果用户组的权限和成员仅能被系统安全员修改的话,用户组的机制是非常接近于角色的概念的。角色也可以在用户组的基础上实现,这有利于保持原有系统中的控制关系。在这种情况下,角色相当于一个策略部件,与用户组的授权及责任关系相联系,而用户组则是实现角色的机制。因此,两者之间是策略与实现机制之间的关系。
权限是什么呢?
权限表现在对功能模块的操作,例如对上传文件的删除和修改,对菜单的访问,甚至是对页面上某个按钮或图片可见性的控制,都是属于权限的范畴。在做数据表建模时可将功能操作和资源进行统一管理,直接与权限表进行关联,这样更具便捷性和易扩展性。
可见权限分为
- 页面权限
Web系统由一个一个页面组成,页面构成了模块,用户能够看到这个页面的菜单,是能进入某个页面就成为页面权限。 - 操作权限
用户在系统中交互动作都是操作权限,典型的例如增删改查操作。 - 数据权限
业务管理系统中对数据私密性有要求时,哪些人可以看到哪些数据,看不到哪些数据。
RBAC权限模型的扩展模型的完整设计
RBAC本质
RBAC的本质是单纯地用户和权限进行解耦,将用户与角色、角色与权限关联。
RBAC认为权限的过程可以抽象为:判断谁(Who)是否可以对什么(What)进行怎样(How)的访问操作(Operator),简单来说,就是对这个逻辑表达式的值是否为真(True)的求解过程。进而将权限问题转换为Who、What、How的问题,因此Who、What、How构成了访问权限的三元组。
- Who 权限的拥有者或主体,如User、Role、Group、Actor、Principal...
- What 权限针对的对象或资源,如Operator、Object、Class、Resource...
- How 具体的权限,主要是Privilege,可进行正向授权和反向授权。
RBAC相关概念
- User 用户
用户对应着系统中的具体操作者,用户可以自己拥有权限,也可以归属于零个或多个角色,也可以属于零个或多个组,用户的权限集是自身所具有的权限、所属角色具有的权限,所属组具有的权限的合集,用户与权限、角色、组之间的关系都是多对多的关系。
- Operator 操作
Operator 表明对What的How操作,也就是Privilege+Resource的组合。
- Privilege 权限
权限由操作与资源组成,表示对资源的一个操作。角色与权限的关系是多对多的,这一点是权限的核心。
- Role 角色
Role 表示一定数量权限的集合,权限分配的单位与载体,目的是隔离用户和权限的逻辑关系。角色是为许多拥有相似权限的用户进行的分类管理,角色具有上下级关系,可形成树状结构,父级角色的权限是自身以及子角色权限的总和。角色作为用于与权限的代理层,解耦了权限与用户的关系,所有的授权应该给与角色而不是直接分配给用户或组。
- Group 用户组
Group 是权限分配的单位与载体,权限不考虑分配给特定的用户而给组,组可以包含组以实现权限的继承,也可以包含用户,组内用户继承组的权限。用户与组的关系是多对多的,组可以层次化以满足不同级别权限控制的要求。
为了更好地管理用户,对用户进行分组归类。组也具有上下级关系,可形成树状结构。
- Session会话
Session在RBAC中是一个比较隐晦的元素,准确来说,每个Session都是一个映射,一个用户到多个Role角色的映射。当一个用户激活它所有角色的一个子集时会建立一个Session会话。每个Session会话和单个User用户可以关联到一个或多个Session会话。
RBAC的关注点在于角色、用户、权限三者之间的关系即用户授权(User Assignment, UA)和权限分配(Permission Assignment,PA),关系的左右都是多对多的关系,用户可以有多个角色,角色可以包括多个用户。简单来说,用户授权和权限分配相当于中间表,事实上整个RBAC都是基于关系的模型。
RBAC中用户实际上是在扮演角色,可以使用Actor取代User,考虑到多人可以拥有相同的权限,RBAC引入了Group组的概念,Group组同样也可以看作是Actor,而User的概念就是具体到一个人。
RBAC分析模型
RBAC作为一种分析模型,主要分为四部分RBAC0~RBAC3,RBAC96模型家族中包含了这四个概念模型。
NIST(The National Institute of Standards and Technology,美国国家标准与技术研究院)标准RBAC模型由四个部件模型组成,这四个部件模型分别是:
RBAC0(Core RBAC)基础模型
RBAC0是RBAC的核心,RBAC1、RBAC2、RBAC3都是先后在RBAC0的基础上进行扩展。
RBAC0定义了能够构成RBAC控制系统的最小的元素集合,换句话说,RBAC0定义了完全支持RBAC概念的任何系统的最低需求。
RBAC0由四部分构成:User用户、Role角色、Session会话、Permission权限
权限包含“操作”和“控制对象”,权限应该赋予角色而非用户。当一个用户被指派给一个角色时,此用户就拥有了该角色所包含的权限。另外会话是一个动态的概念,用户必须通过会话才可以设置角色,此时用户与激活的角色之间的映射关系。
RBAC1(Hierarchal RBAC)角色分层模型
RBAC1引入了角色间的继承关系,也就是说,角色上有了上下级的区别。
角色间的继承关系可分为一般继承关系和受限继承关系
- 一般继承关系仅仅要求角色继承关系是一个绝对偏序关系,允许角色之间的多继承。
- 受限继承关系则进一步要求角色继承关系是一个树状结构,实现角色间的单继承。
RBAC1适用于角色之间的层次明确,包含关系清晰的场景。
RBAC2(Constraint RBAC)角色限制模型
RBAC2是基于RBAC0的模型,并增加了对角色的限制:角色互斥、基数约束、先决条件角色...
RBAC2添加了责任分离关系,RBAC2的约束规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时应当遵循的强制性规则。
责任分离包括静态责任分离和动态责任分离,约束与“用户-角色-权限”关系一起决定了RBAC2中用户的访问许可。
RBAC2的约束分为
- 角色互斥
同一用户只能分配到一组互斥角色集合中最多一个角色,支持责任分离原则。互斥角色是指各自权限相互制约的两个角色,对于这类角色一个用户在某一次活动中只能被分配其中的一个角色,不能同时获得两个角色的使用权。例如,在审计活动中一个角色不能同时被指派为会计角色和审计员角色。
- 基数约束
一个角色被分配的用户数量受限,一个用户可拥有的角色数目受限,同样一个角色对应的访问权限数量也应当受限,以控制高级权限在系统中的分配。
- 先决条件角色
可以分配角色给用户仅当该用户已经是另一个角色的成员,对应的可以分配访问权限给角色,仅当该角色已经拥有另一种访问权限。要想获得较高的权限,需要首先拥有第一级别的权限。
- 运行时互斥
运行中不能同时激活多个角色
RBAC3(Combines RBAC)统一模型
RBAC3是最全面的权限管理,它是基于RBAC0基础上,将RBAC1和RBAC2整合后的统一模型。
RBAC3称为统一模型,包含了RBAC1和RBAC2,利用传递性也就将RBAC0包含在内。
RBAC安全原则
RBAC支持公认的安全原则:
- 最小特权的安全原则
在RBAC模型中可通过限制分配给角色权限的多少和大小来实现,分配给与某用户对应的角色的权限只要不超过该用户完成其任务的需要就可以了。
- 责任分离原则
在RBAC模型中可通过在完成敏感任务过程中分配两个任务上相互约束的两个角色来实现,例如在清查账目时,只需要设置财务管理员和会计两个角色参加就可以了。
- 数据抽象原则
数据抽象是借助于抽象许可权的概念实现的,例如在账目管理活动中,可使用信用、借方等抽象许可权,而不是使用操作系统提供的读、写、可执行等具体的许可权。RBAC中并强迫实现这些原则,安全管理员可以允许配置RBAC模型使其不支持这些原则。因此,RBAC支持数据抽象的程度与实现细节有关。
RBAC优缺点
- 基于角色与权限之间的变化要比角色与用户之间的变化相对少得多,也就减少了授权管理的复杂性,降低了管理的开销。
- 灵活地支持企业的安全策略,并对企业的变化由很大的伸缩性。
- RBAC没有提供操作顺序控制机制,这一缺陷使得RBAC模型很难应用于要求有严格操作次序的实体系统。
数据表设计
用户账号表
应用系统过的具体操作者,用户可以拥有权限信息,也可以归属于0~n个组。用户的权限集是自身具有的权限、所属组具有的权限、所属角色具有的权限的合集。用户与群组、角色、权限之间是多对多的关系。
CREATE TABLE `web_account` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`aid` int(11) unsigned DEFAULT '0' COMMENT '账户ID 唯一编号',
`account` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '账号',
`password` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '密码',
`salt` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '密码加盐',
`creator` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建人',
`create_time` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
`create_date` datetime DEFAULT NULL COMMENT '创建日期',
`updator` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新人',
`update_time` int(10) unsigned DEFAULT '0' COMMENT '修改时间',
`update_date` datetime DEFAULT NULL COMMENT '修改日期',
`login_time` int(10) unsigned DEFAULT '0' COMMENT '最近登录时间',
`login_date` datetime DEFAULT NULL COMMENT '最近登录日期',
`login_ip` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '最近登录IP',
`login_error` tinyint(4) unsigned DEFAULT '0' COMMENT '错误登录次数',
`logout_time` int(10) unsigned DEFAULT '0' COMMENT '下线时间',
`logout_date` datetime DEFAULT NULL COMMENT '下线日期',
`token` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '登录令牌',
`lock` tinyint(1) DEFAULT '0' COMMENT '锁定状态 0禁用 1启用',
`lock_time` int(10) DEFAULT '0' COMMENT '锁定时间',
`lock_date` datetime DEFAULT NULL COMMENT '锁定日期',
`online` tinyint(1) unsigned DEFAULT '0' COMMENT '在线状态 0下线 1在线',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '备注说明',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='账号';
群组表
为了更好的管理用户,对用户进行分组归类,简称为用户分组。群组是具有上下级关系,可形成树状层次结构的视图。在实际业务中,群组是可以具有自己的角色信息和权限信息的。对比QQ群会发现,一个群可以有多个用户,一个用户也可以加入多个群。每个群都具有自己的权限信息,例如查看群共享等。另外,群也具有自己的角色信息。
用户、群组、角色、权限这四者之间的关系由于自身都会存在上下层次的,相对而言有些繁琐。
CREATE TABLE `web_group` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增编号',
`gid` int(11) unsigned DEFAULT '0' COMMENT '群组ID 唯一',
`pid` int(11) unsigned DEFAULT '0' COMMENT '上级编号',
`level` int(11) unsigned DEFAULT '0' COMMENT '群组层级',
`path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '层级路径',
`type` tinyint(1) unsigned DEFAULT '1' COMMENT '群组类型',
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '群组名称',
`notice` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '群组公告',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '群组备注',
`owner_id` int(11) unsigned DEFAULT '0' COMMENT '拥有者ID',
`member_count` int(11) unsigned DEFAULT '0' COMMENT '成员数量',
`children_count` int(11) unsigned DEFAULT '0' COMMENT '子群数量',
`status` tinyint(3) unsigned DEFAULT '1' COMMENT '群组状态 0禁用 1启动',
`create_time` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
`create_date` datetime DEFAULT NULL COMMENT '创建日期',
`update_time` int(10) unsigned DEFAULT '0' COMMENT '更新时间',
`update_date` datetime DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='群组';
群组成员表
CREATE TABLE `web_group_member` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`gid` int(11) unsigned DEFAULT '0' COMMENT '群组编号',
`pid` int(11) unsigned DEFAULT '0' COMMENT '成员父级ID',
`gmid` int(11) unsigned DEFAULT '0' COMMENT '成员ID',
`role` tinyint(3) unsigned DEFAULT '0' COMMENT '成员角色',
`status` tinyint(3) unsigned DEFAULT '1' COMMENT '成员状态 0禁用 1启用 2踢出',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '备注',
`create_time` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
`create_date` datetime DEFAULT NULL COMMENT '创建日期',
`update_time` int(10) DEFAULT '0' COMMENT '更新时间',
`update_date` datetime DEFAULT NULL COMMENT '更新日期',
`entry_time` int(10) unsigned DEFAULT '0' COMMENT '进入时间',
`entry_date` datetime DEFAULT NULL COMMENT '进入日期',
`exit_time` int(10) unsigned DEFAULT '0' COMMENT '踢出时间',
`exit_date` datetime DEFAULT NULL COMMENT '踢出日期',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='群组成员';
角色表
为了对拥有相似权限的用户或群组进行分类管理,定义了角色的概念。角色具有上下层次关系,可形成树状层次结构的视图。父级角色的权限是自身及其子角色权限的综合。
CREATE TABLE `web_role` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增编号',
`rid` int(11) unsigned DEFAULT '0' COMMENT '唯一编号',
`pid` int(11) unsigned DEFAULT '0' COMMENT '父级编号',
`level` int(11) unsigned DEFAULT '0' COMMENT '所属层级',
`path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '层级路径',
`type` tinyint(1) unsigned DEFAULT '1' COMMENT '角色类型',
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '角色名称',
`status` tinyint(3) unsigned DEFAULT '1' COMMENT '角色状态',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '备注说明',
`create_time` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
`create_date` datetime DEFAULT NULL COMMENT '创建日期',
`update_time` int(10) unsigned DEFAULT '0' COMMENT '更新时间',
`update_date` datetime DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色';
权限节点表
CREATE TABLE `web_node` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`nid` int(11) unsigned DEFAULT '0' COMMENT '唯一编号',
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '节点名称',
`module` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '模块标识',
`controller` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '控制器标识',
`action` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '方法标识',
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '节点地址',
`pid` int(11) unsigned DEFAULT '0' COMMENT '父级编号',
`level` tinyint(3) unsigned DEFAULT '0' COMMENT '节点层级',
`path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '节点路径',
`type` tinyint(3) unsigned DEFAULT '0' COMMENT '节点类型',
`status` tinyint(3) unsigned DEFAULT '1' COMMENT '节点状态',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '备注说明',
`create_date` datetime DEFAULT NULL COMMENT '创建日期',
`create_time` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
`update_date` datetime DEFAULT NULL COMMENT '更新日期',
`update_time` int(10) unsigned DEFAULT '0' COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='权限节点';
未完待续...