2. RBAC基础:角色、权限、用户模型
说起零信任的权限隔离,RBAC 几乎是绕不开的起点。我自己刚接触权限设计时,也踩过不少坑——最典型的就是把权限直接绑在用户身上,结果后期每来一个新需求都要改表结构,简直欲哭无泪。后来我才意识到,角色才是权限管理的核心枢纽。
这一节,我们就来拆解 RBAC 最基础的三个元素:用户、角色、权限。搞清楚它们之间的关系,你就能搭出一套可扩展、易维护的权限模型。
3.1 三个核心概念
先看一张表,快速区分它们:
| 概念 | 英文 | 定义 | 我理解的本质 |
|---|---|---|---|
| 用户 | User | 系统的操作者,可以是人、服务账号、设备 | 权限的最终承担者 |
| 角色 | Role | 一组权限的集合,代表一种职责或岗位 | 权限的“容器” |
| 权限 | Permission | 对某个资源执行特定操作的能力 | 最细粒度的控制单元 |
这三个概念的关系,说白了就是一句话:用户通过角色获得权限。你想想看,如果直接给用户分配权限,一个项目几十个人,每个人都是独立的权限列表——维护成本会爆炸。加上角色这一层,权限管理和复用就优雅多了。
3.2 核心关系模型
RBAC 标准模型(也叫 RBAC0)定义了三个基本关系:
- 用户-角色分配 (UA, User Assignment):一个用户可以拥有多个角色,一个角色也可以被多个用户拥有。多对多关系。
- 角色-权限分配 (PA, Permission Assignment):一个角色可以包含多个权限,一个权限也可以出现在多个角色里。也是多对多。
- 角色层级 (RH, Role Hierarchy):角色之间可以继承。比如“管理员”继承“操作员”的所有权限,再额外加一些管理权限。
下面这张图展示了它们之间的完整结构:
小技巧:在实际建模时,我习惯把角色层级限制在3层以内。超过3层,权限继承逻辑就容易混乱,排查问题时得一层层翻,脑仁疼。
3.3 如何落地:数据模型示例
拿关系型数据库来说,RBAC 通常需要五张核心表:
-- 用户表
CREATE TABLE `users` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(64) NOT NULL UNIQUE,
`enabled` TINYINT(1) DEFAULT 1
);
-- 角色表
CREATE TABLE `roles` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(64) NOT NULL UNIQUE,
`parent_id` INT DEFAULT NULL, -- 用于角色层级
FOREIGN KEY (`parent_id`) REFERENCES `roles`(`id`)
);
-- 权限表
CREATE TABLE `permissions` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`resource` VARCHAR(128) NOT NULL, -- 资源标识,如 "order:123"
`action` VARCHAR(32) NOT NULL, -- 操作,如 "read"、"write"
UNIQUE KEY `uk_res_act` (`resource`, `action`)
);
-- 用户-角色关联表
CREATE TABLE `user_roles` (
`user_id` INT NOT NULL,
`role_id` INT NOT NULL,
PRIMARY KEY (`user_id`, `role_id`),
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`),
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`)
);
-- 角色-权限关联表
CREATE TABLE `role_permissions` (
`role_id` INT NOT NULL,
`permission_id` INT NOT NULL,
PRIMARY KEY (`role_id`, `permission_id`),
FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`),
FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`)
);
这个结构非常清晰。你想想看,以后要给某个部门新增一个“数据导出员”角色,只需要在roles表加一行,再给它分配几个权限就行。用户侧完全不用动。
3.4 避坑指南
我曾经犯过的错:角色层级用得太随意,让“普通用户”继承了“VIP用户”的部分权限,结果导致权限膨胀。后来我定了个规则:角色层级只用于“向上继承”,即子角色只能继承父角色的所有权限,不能反向或跨级。这样逻辑就干净多了。
另外,有个细节容易被忽视——静态职责分离(SSD)。比如一个用户不能同时拥有“采购员”和“审批员”角色,否则他就能自己采购自己审批,形成利益冲突。我一般在分配用户角色时做一次校验,不允许互斥角色同时出现。
3.5 小结
用户、角色、权限这三者的关系,就是 RBAC 的骨架。记住:角色是权限的容器,用户通过角色获得权限。建好这几张表,配合角色层级和互斥约束,你的权限系统就已经具备可扩展的基础了。