2. RBAC基础:核心概念与最小权限原则
今天我们来聊RBAC,也就是基于角色的访问控制。说实话,这是整个权限模型设计里最常用的基础框架。我刚入行时以为权限设计就是把用户和权限直接挂钩,后来踩了坑才明白,中间加一层"角色"才是真正的精髓。
这一节,我会把用户、角色、权限这三个核心对象拆开讲清楚,再谈谈那个"够用就行"的最小权限原则。嗯,这些都是我实际项目里反复验证过的。
2.1 三个核心对象:用户、角色、权限
先看一张整体图,帮你快速建立认知。
看图说话:用户不直接和权限挂钩,而是通过角色中转。这个设计,说白了就是为了便于管理。
2.2 为什么需要"角色"这一层?
我记得早期做一个企业内部系统时,有800多个员工,每个员工都需要配置"查看多少报表""能改什么数据"。最开始我们直接为用户分配权限,结果权限变更时,600多条记录需要逐一更新,简直是一场噩梦。
引入角色后,问题就简单了:
| 场景 | 无角色(直接授权) | 有角色(RBAC) |
|---|---|---|
| 新增员工 | 手动配置几十条权限 | 分配1个角色搞定 |
| 岗位调整 | 逐条删除旧权限,再添加新权限 | 切换角色即可 |
| 批量变更 | 遍历所有相应用户,逐条更新 | 修改角色定义,所有用户自动同步 |
| 权限审计 | 查看每个用户拥有哪些权限,杂乱无章 | 查看角色定义,清晰直观 |
你想想看,角色就像是一个"职位模板":研发工程师该看什么代码、能修改什么配置,一次性定义好。新人入职直接套用模板,省心省力。
2.3 核心关系详解
2.3.1 用户与角色:多对多
一个用户可以有多个角色。比如,张三是"研发工程师",同时也可以被指定为"项目管理员",拥有查看项目进度的额外权限。
反过来,一个角色也可以分配给多个用户。所以用户和角色之间的关系是"多对多"。这种关系在关系型数据库里通常用一张关联表来实现。
-- 用户表
CREATE TABLE t_user (
id BIGINT PRIMARY KEY,
name VARCHAR(50) NOT NULL
);
-- 角色表
CREATE TABLE t_role (
id BIGINT PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(50) NOT NULL
);
-- 用户-角色关联表
CREATE TABLE t_user_role (
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
PRIMARY KEY (user_id, role_id),
FOREIGN KEY (user_id) REFERENCES t_user(id),
FOREIGN KEY (role_id) REFERENCES t_role(id)
);
2.3.2 角色与权限:多对多
一个角色可以拥有很多权限,一个权限也可以被多个角色拥有。这同样是一个"多对多"的关系。
举个例子,"研发工程师"角色可能拥有"查看代码""提交代码""查看日志"这三个权限;而"查看日志"这个权限,同时也可以被"运维工程师"角色拥有。
-- 权限表
CREATE TABLE t_permission (
id BIGINT PRIMARY KEY,
code VARCHAR(50) UNIQUE NOT NULL,
description TEXT
);
-- 角色-权限关联表
CREATE TABLE t_role_permission (
role_id BIGINT NOT NULL,
permission_id BIGINT NOT NULL,
PRIMARY KEY (role_id, permission_id),
FOREIGN KEY (role_id) REFERENCES t_role(id),
FOREIGN KEY (permission_id) REFERENCES t_permission(id)
);
关键理解:权限是最小粒度的控制单元,通常对应一个具体的操作(比如“点击提交按钮”“读取某字段数据”)。而角色将这些权限组合成一个有意义的集合,代表一个岗位的工作职责范围。
2.4 最小权限原则
这个概念听起来很高大上,其实核心就一句话:只给用户完成任务所必需的最小权限,绝不多给。
有一次客户找到我,说系统被内部员工误删了重要数据。我一看日志,发现那个员工被赋予了"系统管理员"角色,而他的实际工作只需要查看报表。这就是违反了最小权限原则。
2.4.1 为什么必须坚持最小权限?
- 降低误操作风险——权限越小,犯大错的可能性越低。
- 减少攻击面——被攻破一个普通账号,影响范围可控。
- 简化审计——权限范围小,出事时排查链条更短。
2.4.2 如何落地最小权限?
我个人总结了四个步骤:
- 先禁用,后开放。新建用户默认不授予任何权限,按需逐步放开。
- 从业务场景出发。和需求方一起梳理"这个员工到底需要做什么",而不是"他可能会用到什么"。
- 按角色拆分,避免全能角色。比如"报表查看员"只给查看权限,"数据录入员"只给写入权限。
- 定期审计。每季度检查一次角色-权限映射,清理长期不用的授权。
2.5 实战贴士:从零开始设计一套简单的RBAC
如果你现在要从0搭建一套RBAC,我建议按这个顺序下手:
| 步骤 | 做什么 | 产出物 |
|---|---|---|
| 1 | 罗列所有业务操作(增删改查等) | 权限清单 |
| 2 | 将操作按岗位职责分组 | 角色清单 |
| 3 | 为每个角色分配对应的权限 | 角色-权限映射表 |
| 4 | 将现有用户映射到角色 | 用户-角色映射表 |
| 5 | 验证:检查每个用户是否只有"够用"的权限 | 最小权限确认表 |
是不是很简单?但我在实际项目中发现,很多团队到第4步就停下了,跳过第5步。结果上线后各种绕路去"临时授权",最后权限模型又回到了混乱状态。