2. RICE 角色模型拆解:四个核心维度的精确含义

多租户权限设计中最致命的错误,是将“角色”当作唯一维度直接绑定菜单。RICE 模型把权限拆解为四个独立但互锁的要素:Role(角色)、Identity(身份)、Capability(能力)、Entity(实体)。只有厘清每一层的职责,才能在跨租户、跨业务线、跨数据域的场景中实现精细而可扩展的授权。

2.1 四要素定义速览

要素 缩写 一句话定义 核心问题
Role(角色) R 一组预定义的职责集合,通常与岗位对应 谁做什么?
Identity(身份) I 用户在系统中的唯一标识及其上下文属性 你是谁?属于哪个租户?
Capability(能力) C 可执行的操作原子,如“创建订单”“删除报表” 能做什么操作?
Entity(实体) E 操作作用的对象,如“客户A的订单”“部门B的预算” 对什么资源做?
📌 记忆口诀:“角色定岗,身份定户,能力定权,实体定数。” —— 四者组合才构成一条完整的授权规则。

2.2 逐层深度拆解

▸ Role(角色)—— 职责的容器

角色是将多个Capability打包的逻辑组。典型的角色如“销售经理”“财务审核员”。角色本身不包含数据范围,只说明“这个人应该拥有哪些操作权限”。在多租户环境下,角色模板可以跨租户共享,但各租户可修改其绑定的能力集。

▸ Identity(身份)—— 租户与用户的双重锚

Identity = 用户全局标识 + 租户归属 + 额外属性(部门、职级、区域)。同一个用户在不同租户下拥有不同的身份。身份决定了默认的角色指派以及数据隔离边界。

▸ Capability(能力)—— 不可再拆的原子操作

每个Capability对应一个REST API端点、一个页面按钮或一个后台服务调用。例如:order:create、report:export。能力不关心“谁在做”和“对哪条数据做”,只描述动作本身。

▸ Entity(实体)—— 数据的范围与归属

实体是权限的“宾语”。常见实体类型:租户实例、客户、项目、合同、发票等。每个实体自带所属租户ID,因此通过Entity即可天然实现跨租户隔离。实体还支持层级(如“部门 → 小组 → 员工”)和条件(如“金额 < 1000 的订单”)。

2.3 四要素的协作关系

核心公式:一次权限判断 = 检查 User.Identity 是否拥有 Role,该 Role 包含所需 Capability,且该 Capability 的作用域覆盖目标 Entity。
RICE 四要素协作图 Identity 用户+租户+属性 Role 职责集合 Capability 原子操作 Entity 数据对象 绑定 包含 作用 授权判断链 Identity → Role → Capability → Entity(缺一不可) 案例1:跨租户管理员 Identity:超级管理员@租户A Role:全局管理员 Capability:user:manage Entity:租户A所有用户 案例2:部门预算审核 Identity:张三@租户B·财务部 Role:预算审核员 Capability:budget:approve Entity:本部门预算 案例3:跨实体只读 Identity:临时审计员@租户C Role:审计员 Capability:invoice:read Entity:租户C所有发票

2.4 类比:图书借阅系统

把权限系统比作图书馆管理:

  • Role = 借阅员、图书管理员、馆长(岗位职责)
  • Identity = 小明(员工编号A-123,所属分馆:朝阳分馆)
  • Capability = 借书、还书、罚款、上架
  • Entity = 哪本书、哪个书架、哪个读者的借阅记录

小明拥有“借阅员”角色,因此拥有“借书”能力,但只能操作“本分馆的图书实体”。换到另一分馆,Entity 范围变化,权限自动失效。

2.5 常见误区

⚠️ 误区1:把“角色”当作数据权限做控制。
后果:一个“销售经理”在A租户能看全部客户,在B租户却只能看自己跟进的客户,被迫创建“A租户销售经理”和“B租户销售经理”两个角色,角色爆炸。
正确做法:角色只管理操作集合,数据范围由Entity隔离。
⚠️ 误区2:混淆“身份”与“角色”。
后果:在代码中把用户ID直接映射为角色,导致跨租户共用身份时权限错乱。
正确做法:身份是上下文,角色是权限模板,永远通过“租户内的身份”去关联角色。
⚠️ 误区3:Capability 粒度过粗或过细。
过粗(如一个“全部权限”能力)导致无法精细控制;过细(如每个按钮一个能力)导致角色配置工作量爆炸。
建议:一个 Capability 对应一个业务操作(如“提交审批”),而非一个HTTP方法。

2.6 练习题

  1. 以下哪个属于 RICE 中的 Entity?
    A. 财务审核员 B. 用户张三@租户A C. 删除发票 D. 合同编号 CON-20250301
  2. 小明在租户A拥有“管理员”角色,具备user:create能力,但无法创建租户B的用户。这是因为 Entity 限制了什么?
  3. 请用 RICE 四要素描述:李四(租户C财务部)可以导出自己部门的季度报表。

2.7 应用边界

场景 适用性 说明
单一租户小团队(<50人) 🔴 过度设计 RBAC + 数据软删除即可,不需要 Entity 层
多租户 SaaS(租户数>100) 🟢 强烈推荐 RICE 天然支持租户隔离与角色模板共享
内部企业门户(无多租户) 🟡 可选 可降级为 RCE(Identity 弱化为部门)
需要跨租户数据聚合的场景 🟢 必需 Entity 层支持多实例范围查询