RBAC基础概念与原理

说起接口安全,你第一个想到的是什么?
?JWT?还是?
这些当然重要。但我做了几年安全设计后发现,少了权限模型做地基,这些技术就像沙滩上盖楼,早晚得出事。

今天咱们聊的是RBAC——基于角色的访问控制。
这东西不是新概念,上世纪90年代就有人提出来了。但直到今天,它依然是接口安全领域最实用、最经典的权限模型。

为什么呢?
因为它够简单,也够灵活。

RBAC的核心三要素

说白了,RBAC就三个东西:用户、角色、权限。

  • 用户(User):系统里的操作主体,可以是一个人,一个服务,甚至一个设备。
  • 角色(Role):权限的集合,代表一类职责或身份,比如“管理员”、“普通用户”、“审计员”。
  • 权限(Permission):对资源的操作许可,通常拆成“资源 + 操作”,比如“订单列表 + 查询”。

它们之间的关系是这样:

  1. 用户不直接拥有权限。
  2. 用户被赋予一个或多个角色。
  3. 每个角色包含一组权限。
  4. 用户通过角色获得权限。

嗯,绕了一层,但这就是RBAC的精髓。

核心原则:用户 → 角色 → 权限

权限不直接分配给用户,而是分配给角色。用户通过扮演角色获得权限。这让授权管理变得非常灵活。

我在项目中遇到过很多次,业务方说「给张三加个读权限」。
如果系统是直接给用户授权,那就得手动改用户表;但要是用了RBAC——直接把张三扔进「读者」角色就完了,所有读者该有的权限自动到位。

三元素 vs 传统授权

你对比一下传统方式和RBAC:

对比维度 传统直接授权 RBAC角色授权
新增用户 逐个分配权限,累死人 分配角色,秒完成
批量改权限 改每个用户,容易遗漏 改角色定义,一次搞定
权限审计 分散在用户上,难追踪 集中在角色上,一目了然
人员变动 权限清理麻烦,有风险 回收角色,干脆利落

一个很明显的结论:
RBAC把「谁有什么权限」这个问题,变成了「这个人是什么角色」。
业务逻辑一下子就清晰了。

RBAC的数据模型

实际落地时,数据库结构大概是这样:

-- 用户表
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50)
);

-- 角色表
CREATE TABLE roles (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    description VARCHAR(200)
);

-- 权限表
CREATE TABLE permissions (
    id INT PRIMARY KEY,
    resource VARCHAR(50),   -- 比如 "order"
    action VARCHAR(50)      -- 比如 "read", "write"
);

-- 用户-角色关联
CREATE TABLE user_roles (
    user_id INT REFERENCES users(id),
    role_id INT REFERENCES roles(id),
    PRIMARY KEY (user_id, role_id)
);

-- 角色-权限关联
CREATE TABLE role_permissions (
    role_id INT REFERENCES roles(id),
    permission_id INT REFERENCES permissions(id),
    PRIMARY KEY (role_id, permission_id)
);

我个人习惯把permissions表设计成 resource:action 的形式。
比如 order:read、user:write。这样写代码查权限时,字符串匹配就够了,很直接。

小技巧

权限字符串用英文冒号分隔资源与操作,比如 report:export。既容易读,也方便在代码里做通配符匹配(比如 report:* 代表报告模块的所有操作)。

RBAC 核心关系图 用户 (User) 角色 (Role) 权限 (Permission) 张三 李四 管理员 普通用户 order:read order:write user:read report:read 用户通过角色获得权限,不直接关联

为什么RBAC适合接口安全?

你看现在的微服务架构,接口少说几十个,多则几百上千。
如果每个接口都在代码里if-else判断「当前用户能不能调用」,

——你维护得过来吗?

RBAC的好处在于:

  • 职责分离:不同角色看到的、能操作的东西天然隔离。
  • 最小权限:角色定义时就控制了权限范围,用户不会越界。
  • 审计友好:谁是什么角色,角色有什么权限,查表就行。
  • 接口无关:权限判断与接口逻辑解耦,权限层可以单独做。

注意

RBAC不是万能的。如果你的业务权限规则极其复杂——比如「用户A只能查看自己部门且金额大于1000的订单,并且只能在周一操作」,纯RBAC会非常吃力。这时候要考虑ABAC(基于属性的访问控制)或者RBAC+ABAC混合方案。以后章节会细聊。

好了,这一章先把RBAC的骨架搭起来。
用户、角色、权限,这三个概念你记牢了,后面所有关于接口安全的设计都围着它们转。