角色继承
角色继承是数据墙DBW 减少权限配置重复的核心机制。你可以在 anonymous 上定义一次权限,所有更宽泛的角色——authenticated 和任意命名角色——自动获得相同的访问权限。不需要为每个角色在每个实体上重复写相同的权限块。
继承链
继承从权限最少的角色流向权限更高的角色:
命名角色(如 editor)→ authenticated → anonymous| 角色 | 继承自 | 何时生效 |
|---|---|---|
命名角色(如 editor) | authenticated | 该命名角色未显式配置权限块时 |
authenticated | anonymous | authenticated 未显式配置权限块时 |
anonymous | 无 | 继承链的根节点,无后备来源 |
继承是单向的——anonymous 不会从 authenticated 继承权限。继承链中的每个角色只会向上(向更宽泛的角色)查找。
继承解析过程
当请求到达并确定了最终生效角色后,引擎按以下步骤解析权限:
1. 在实体的 permissions 中查找与当前角色完全匹配的显式权限块
↓
2. 找到匹配?
├── 是 → 使用该权限块,解析完成
└── 否 → 沿继承链向上查找
├── 当前角色是命名角色 → 查找 authenticated
├── 当前角色是 authenticated → 查找 anonymous
└── 当前角色是 anonymous → 无后备
↓
3. 在链上找到匹配?
├── 是 → 使用该权限块,标记为 "inherited from: <source>"
└── 否 → 返回 403 ForbiddenIMPORTANT
继承不合并权限。引擎使用找到的第一个匹配权限块,不会将不同角色的权限加在一起。如果 editor 没有显式配置,引擎使用 authenticated 的配置——editor 不会同时拥有自己配置的权限和 authenticated 配置的权限。
示例一:最小配置——所有角色继承同一权限
只在 anonymous 上配置读取权限:
{
"entities": {
"Book": {
"source": "dbo.books",
"permissions": [
{ "role": "anonymous", "actions": ["read"] }
]
}
}
}有效权限:
Entity: Book
Role: anonymous | Actions: Read
Role: authenticated | Actions: Read (inherited from: anonymous)
Unconfigured roles | Inherit from: anonymousauthenticated 和所有未配置的命名角色(如 editor、viewer)都自动获得 read 权限。一个权限块,覆盖所有角色。
示例二:分层配置——不同角色不同权限
显式配置了部分角色,其余角色继承:
{
"entities": {
"Order": {
"source": "dbo.orders",
"permissions": [
{ "role": "anonymous", "actions": ["read"] },
{ "role": "authenticated", "actions": ["read", "create"] },
{ "role": "admin", "actions": ["*"] }
]
}
}
}有效权限:
Entity: Order
Role: anonymous | Actions: Read
Role: authenticated | Actions: Read, Create
Role: admin | Actions: Create, Read, Update, Delete
Unconfigured roles | Inherit from: authenticated除 admin 外所有命名角色(如 viewer、support)从 authenticated 继承,获得 read + create 权限。admin 有单独的显式配置,不参与继承。
示例三:完全隔离——只有特定角色可访问
只配置一个命名角色,不配置 anonymous 和 authenticated:
{
"entities": {
"AuditLog": {
"source": "dbo.audit_log",
"permissions": [
{ "role": "admin", "actions": ["read"] }
]
}
}
}有效权限:
Entity: AuditLog
Role: admin | Actions: Read
Role: authenticated | No matching permission (403 Forbidden)
Role: anonymous | No matching permission (403 Forbidden)因为继承链的根(anonymous)没有配置,authenticated 和所有未配置角色都无法找到继承来源,请求被拒绝。这是实现"仅内部管理员可访问"的推荐方式。
查看有效权限
使用 CLI 查看继承应用后的最终权限,无需启动服务:
dab configure --show-effective-permissions指定配置文件:
dab configure --show-effective-permissions --config my-config.json输出示例:
Entity: Book
Role: anonymous | Actions: Read
Role: authenticated | Actions: Read (inherited from: anonymous)
Unconfigured roles inherit from: anonymous
Entity: Order
Role: admin | Actions: Create, Read, Update, Delete
Role: anonymous | Actions: Read
Role: authenticated | Actions: Read, Create
Unconfigured roles inherit from: authenticated--show-effective-permissions 显示每个实体上每个角色的最终权限,并标注继承来源。这是验证权限配置是否符合预期的最快方式。
继承与显式配置的取舍
| 场景 | 策略 |
|---|---|
| 所有角色应有相同权限 | 只在 anonymous 配置一次 |
| 认证用户需要比匿名更多权限 | anonymous 配置基础权限,authenticated 显式配置额外操作 |
特定角色需要比 authenticated 更多 | 显式配置该角色 |
特定角色需要比 authenticated 更少 | 必须显式配置该角色,限制其操作 |
| 实体需完全私有 | 只配置某个特定角色,不配置 anonymous 和 authenticated |
注意事项
| 注意事项 | 说明 |
|---|---|
| 不影响操作权限的判定 | 继承只影响"找不到显式配置时用谁的配置",不影响权限块的内部逻辑 |
| Unauthenticated 模式下命名角色不生效 | 使用 Unauthenticated 认证时所有请求都是 anonymous,引擎会在启动时对此发出警告 |
| 不能部分继承 | 要么完全继承某个角色的全部权限块,要么完全显式配置——不能"从 A 继承 read,自己配置 write" |
| 字段和策略同继承 | 如果继承的权限块中包含 fields 或 policy,这些也会一并继承 |
