前言
本文介绍了 RBAC 的基本概念,并对其常用的几种延伸模型进行了说明,最后使用 MySQL 给出了其中一种模型的具体实现。
介绍
RBAC 全称为基于角色的访问控制模型( Role-based access control ),在该模型中,通过让权限与角色关联来实现授权,给用户分配一系列的角色来让注册用户得到这些角色对应的权限,使系统权限分配更加方便。我们在一般的大型系统开发中,几乎都要考虑权限控制的相关问题,诸如:系统资源权限、用户行为权限等,此类问题的实现通常需要数据库在设计时做出考虑,经过 IT 届各种大佬的长期实践后,总结出了较为通用的针对权限控制的 RBAC 设计模型。 RBAC 不是某种技术框架,它类似于设计模式,是当下流行的一种数据库(表)设计的思想,它能通过为用户分配角色来实现权限的分配,只要你的数据库设计满足这种思想便可说你的数据库使用的是 RBAC 模型。
分类
概述
在RBAC模型中,一般有以下组成部分:
- 用户( User ):定义需要权限鉴别操作的主体
- 角色( Role ):定义一批相关联权限的集合
- 权限( Permission ):定义需要鉴别权限操作的对象
- 用户-角色关联( User-Role ):定义用户所具有的角色
- 角色-权限关联( Role-Permission ):定义角色所具有的权限
RBAC
RBAC0/基本模型
RBAC0 是最基本的模型,未做特殊要求和扩展,在该模型中,一个用户可以同时拥有多个角色,每个角色可以拥有多个权限。
RBAC0
RBAC1/继承模型
RBAC1 在 RBAC0 的基础上进行了拓展,主要变化在于增加了角色之间的继承关系(类似于 Java 类继承),子角色除了拥有自己的权限外也拥有父角色所具有的所有权限。此外 RBAC1 又分为一般继承和受限继承:一般继承关系允许角色间存在多继承;受限继承则要求角色继承关系是一个严格的树结构。总体来说这两种思想在设计上差别不大,仅在应用上有略微差别。
RBAC1
RBAC2/限制模型
在部分权限要求较为严格的系统中,会要求具有特定职责的用户不能具有职责之外的权限(角色)(责任分离),这些限制会体现在系统上层开发语言中而与数据库设计实现无关。例如:在一个公司中,经费申请部门不能拥有经费审核部门的权限。此模型中常用以下限制:
- 互斥角色 :同一用户只能分配到一组互斥角色集合中至多一个角色。
- 基数约束 :一个角色被分配的用户数量受限、一个用户可拥有的角色数目受限、同样一个角色对应的访问权限数目也应受限……
- 先决条件角色 :想获得B角色必须已有A角色。
- 运行时互斥 :在同一时刻只有一个角色生效。
RBAC3/综合模型
RBAC3 是 RBAC1 和 RBAC2 的综合,既包含角色间的继承关系,又对用户角色进行限制。
实现
以下是 RBAC1 模型的 MySQL 数据库的实现,系统ER图如下:
ER图
用户表
该表主要包含了基本的用户信息。
1
2
3
4
5
6
7
8
|
DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(255) NOT NULL UNIQUE,
`password` varchar(255) NOT NULL,
`last_login_time` datetime NULL COMMENT '最后登陆时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COMMENT='管理员表';
|
角色表
该表储存角色信息,其中pid
是父级角色的ID
值(用于实现角色继承)、code
是角色代码(BASE_ADMIN
、SUPER_ADMIN
)、icon
是前端图标,可有可无、sort
用于出现多种同级角色时排序。
1
2
3
4
5
6
7
8
9
10
|
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`pid` int(11) NOT NULL COMMENT '父级角色id',
`code` varchar(255) NOT NULL COMMENT '角色代码',
`icon` varchar(255) COMMENT '图标',
`description` varchar(255) NOT NULL COMMENT '描述',
`status` int(1) NULL DEFAULT 1 COMMENT '启用状态:0->禁用;1->启用',
`sort` int(11) NULL DEFAULT 0 COMMENT '权重'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COMMENT='角色表';
|
权限表
该表主要包含具体权限信息,其中name
是权限名称(介绍)、value
是权限值(识别标志)、type
是权限类型(目录权限、菜单权限、按钮权限)、uri
是前端资源路径(通常用于web
系统中)。
1
2
3
4
5
6
7
8
9
10
11
|
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(255) NOT NULL COMMENT '名称',
`value` varchar(255) NOT NULL COMMENT '权限值',
`icon` varchar(255) COMMENT '图标',
`type` int(1) DEFAULT 2 COMMENT '权限类型:0->目录;1->菜单;2->按钮(接口绑定权限)',
`uri` varchar(1024) COMMENT '前端资源路径',
`sort` int(11) NULL DEFAULT 0 COMMENT '权重',
`status` int(1) NULL DEFAULT 1 COMMENT '启用状态:0->禁用;1->启用'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COMMENT='权限表';
|
用户-角色关联表
该表主要记录某一用户具有哪些角色。
1
2
3
4
5
6
7
|
DROP TABLE IF EXISTS `admin_role`;
CREATE TABLE `admin_role` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`admin_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COMMENT='用户-角色关联表';
|
角色-权限关联表
该表主要记录某一角色具有哪些权限。
1
2
3
4
5
6
7
|
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`role_id` int(11) NOT NULL,
`permission_id` int(11) NOT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COMMENT='角色-权限关联表';
|
总体来说RBAC在理解上并不算很难,我在学习的过程中时间主要花费在了数据库的设计和实现方面,在使用上也确实可以很方便的对系统进行权限管理,有很大的通用性