组织级 RBAC
组织级 RBAC 是 Code Bird Cloud 多组织(B2B)场景下的权限管理核心,允许同一用户在不同组织中拥有不同的角色和权限。
核心概念
组织成员
用户可以成为一个或多个组织的成员。成员关系是组织级 RBAC 的基础,只有成为组织的成员,才能在该组织内被分配角色。
用户 A
├── 组织 X 的成员 → 拥有 admin 角色
├── 组织 Y 的成员 → 拥有 member 角色
└── 组织 Z 的成员 → 拥有 viewer 角色组织用户角色(Organization User Role)
组织用户角色是一个三元组关系:用户 + 组织 + 组织角色模板。它描述了某个用户在某个特定组织内被分配的角色。
| 维度 | 说明 |
|---|---|
| 用户(User) | 具体的系统用户 |
| 组织(Organization) | 用户所属的组织 |
| 组织角色模板(Organization Role) | 在该组织内分配给用户的角色 |
关键特性:同一用户在不同组织中可以拥有完全不同的角色。
示例场景
假设系统中有以下组织角色模板:
admin(管理员):拥有完整组织管理权限member(成员):拥有基本协作权限viewer(观察者):仅有只读权限
用户张三同时属于两个组织:
| 组织 | 角色 | 权限说明 |
|---|---|---|
| Acme 公司 | admin | 可以管理成员、修改设置、管理项目 |
| Beta 工作室 | member | 可以查看成员、参与项目,但不能管理成员或设置 |
组织成员管理
获取组织成员列表
GET /api/v1/organizations/:id/users响应示例:
{
"code": 0,
"data": {
"items": [
{
"id": "user_001",
"username": "zhangsan",
"email": "zhangsan@example.com",
"roles": [
{ "id": "role_001", "name": "admin" }
]
},
{
"id": "user_002",
"username": "lisi",
"email": "lisi@example.com",
"roles": [
{ "id": "role_002", "name": "member" }
]
}
],
"total": 2
}
}添加组织成员
POST /api/v1/organizations/:id/users
Content-Type: application/json
{
"user_ids": ["user_003"]
}移除组织成员
DELETE /api/v1/organizations/:id/users/:userId移除成员时会同时清除该用户在该组织内的所有角色分配。
组织用户角色管理
获取用户在组织内的角色
GET /api/v1/organizations/:id/users/:userId/roles响应示例:
{
"code": 0,
"data": [
{
"id": "role_001",
"name": "admin",
"description": "组织管理员"
}
]
}设置用户在组织内的角色
使用 PUT 方法完全替换用户在该组织内的角色分配:
PUT /api/v1/organizations/:id/users/:userId/roles
Content-Type: application/json
{
"role_ids": ["role_001", "role_002"]
}| 字段 | 类型 | 说明 |
|---|---|---|
role_ids | string[] | 组织角色模板 ID 列表,替换用户在该组织内的所有角色 |
使用说明
- 传入空数组
[]将清除用户在该组织内的所有角色 - 此操作是全量替换,不是增量添加
- 只能使用系统中已存在的组织角色模板的 ID(参见 组织配置)
权限检查流程
组织级权限检查的完整流程:
API 请求(携带组织上下文)
|
v
提取 Access Token,识别用户身份
|
v
确定目标组织 ID
|
v
查询用户在该组织内的角色
(Organization User Role)
|
v
聚合角色绑定的权限模板
(Organization Role -> Organization Permission)
|
v
匹配请求所需的权限
|
v
允许 / 拒绝完整操作示例
以下示例演示从创建组织到分配成员角色的完整流程:
1. 创建组织
POST /api/v1/organizations
{
"name": "Acme 公司",
"description": "一家示例公司"
}
// 响应
{
"code": 0,
"data": {
"id": "org_001",
"name": "Acme 公司"
}
}2. 添加成员
POST /api/v1/organizations/org_001/users
{
"user_id": "user_zhangsan"
}3. 为成员分配角色
PUT /api/v1/organizations/org_001/users/user_zhangsan/roles
{
"role_ids": ["role_admin"]
}4. 验证角色分配
GET /api/v1/organizations/org_001/users/user_zhangsan/roles
// 响应
{
"code": 0,
"data": [
{
"id": "role_admin",
"name": "admin",
"description": "组织管理员"
}
]
}权限在 OIDC Token 中的体现
组织角色和权限会通过 OIDC Token 传递给第三方应用。根据获取 Token 的方式不同,返回的内容也不同。
两种权限类型
组织角色可以绑定两种权限,它们分别出现在不同类型的 Token 中:
| 权限类型 | 说明 | 出现在哪种 Token 中 |
|---|---|---|
| 组织权限模板(Organization Scope) | 自定义的组织级权限,如 manage:members、read:projects | 组织操作 Token(Path A) |
| API 资源权限(Resource Scope) | 系统级 API 资源权限,如 read:orders、write:products | 组织 API 资源 Token(Path B) |
一阶段模式 — 仅返回角色名称
通过 authorize 请求携带 organization_id 登录时,ID Token 和 Access Token 中包含角色名称,但不包含具体权限列表:
{
"sub": "user_zhangsan",
"organization_id": "org_123",
"organizations": ["org_123"],
"organization_roles": ["org_123:admin", "org_123:member"]
}第三方应用需要根据角色名称自行判断权限(例如约定 admin 拥有所有权限)。
两阶段模式 Path A — 返回组织权限
使用 refresh_token + organization_id(不带 resource)获取的 Token,scope 字段包含角色绑定的组织权限模板名称:
{
"aud": "urn:codebird:organization:org_123",
"sub": "user_zhangsan",
"organization_id": "org_123",
"organization_name": "Acme 公司",
"organization_roles": ["admin"],
"scope": "manage:members read:members manage:projects read:projects"
}scope 是该用户在该组织中所有角色绑定的组织权限模板的并集。
两阶段模式 Path B — 返回 API 资源权限
使用 refresh_token + organization_id + resource 获取的 Token,scope 字段包含角色绑定的 API 资源权限名称:
{
"aud": "https://api.yourapp.com",
"sub": "user_zhangsan",
"organization_id": "org_123",
"scope": "read:orders write:orders"
}Token 类型对比
| 维度 | 一阶段模式 | 两阶段 Path A | 两阶段 Path B |
|---|---|---|---|
| 获取方式 | authorize + org_id | refresh_token + org_id | refresh_token + org_id + resource |
| audience | 应用 client_id | urn:codebird:organization:{orgID} | API 资源 URI |
| 角色名称 | "org_id:role" 格式 | "role" 格式 | 不返回 |
| 具体权限 | 不返回 | 组织权限 scope | API 资源权限 scope |
| 适用场景 | 简单角色判断 | 组织内部细粒度授权 | 组织上下文 API 访问 |
详细的登录流程和 Token 获取方法参见 组织级登录。
注意事项
- 成员前置:用户必须先成为组织的成员,才能在该组织内被分配角色
- 角色隔离:用户在不同组织中的角色完全独立,修改一个组织内的角色不会影响其他组织
- 成员移除级联:移除组织成员时,该用户在该组织内的所有角色分配会被自动清除
- 模板变更传播:如果组织角色模板的权限绑定发生变化,所有持有该角色的组织成员权限会实时更新
- 多角色支持:用户在同一组织内可以被分配多个角色,有效权限为所有角色权限的并集
