OpenDistro Security 中 backend_roles 的设计哲学
- 1.OpenDistro Security 的特殊设计 🔍
- 为内部用户 "模拟" 外部用户的组关系
- 2.为什么这样设计?🤔
- 设计目的:让内部用户也能利用角色映射机制
- 3.实际使用场景对比 📊
- 3.1 场景一:标准 Elasticsearch 做法
- 3.2 场景二:OpenDistro 做法
- 4.权限计算流程 🔄
- 5.OpenDistro vs 原生 Elasticsearch 对比 ⚖️
- 6.OpenDistro 设计的优点与缺点 🎯
- 7.实际用例:为什么需要这个功能?💡
- 用例:批量权限调整
- 8.混合使用模式 🛠️
- 9.关键理解要点 📌
- 10.一句话总结 🎓
- 11.实战验证 ✨
- 场景一:用户 → Roles,用户 → Backend roles → Roles
- 场景二:用户 → Roles,用户 → Backend roles ❌ Roles
- 场景三:用户 → Roles,用户 ❌ Backend roles → Roles
- 场景四:用户 → Roles,用户 ❌ Backend roles ❌ Roles
- 场景五:用户 ❌ Roles,用户 → Backend roles → Roles
- 场景六:用户 ❌ Roles,用户 ❌ Backend roles → Roles
OpenDistro Security 的backend_roles字段设计比较特殊,与原生 Elasticsearch 的行为有所不同。
1.OpenDistro Security 的特殊设计 🔍
在 OpenDistro Security(现在叫 OpenSearch Security)中,backend_roles字段的作用是:
为内部用户 “模拟” 外部用户的组关系
2.为什么这样设计?🤔
设计目的:让内部用户也能利用角色映射机制
在标准的 Elasticsearch 中:
- 内部用户 → 直接分配角色
- 外部用户 → 通过后端角色映射角色
OpenDistro 的想法:“为什么不让内部用户也能享受角色映射的灵活性?”
3.实际使用场景对比 📊
3.1 场景一:标准 Elasticsearch 做法
// 内部用户:直接分配角色PUT/_security/user/kirk{"password":"kirkpass","roles":["command_officer","starship_captain"]// 没有 backend_roles 字段}3.2 场景二:OpenDistro 做法
// 内部用户:利用角色映射PUT_opendistro/_security/api/internalusers/kirk{"password":"kirkpass","backend_roles":["captains","starfleet"],"attributes":{"rank":"captain","assignment":"enterprise"}// 不直接分配角色!}// 角色映射配置PUT_opendistro/_security/api/rolesmapping/command_role{"backend_roles":["captains"]}PUT_opendistro/_security/api/rolesmapping/officer_role{"backend_roles":["starfleet"]}4.权限计算流程 🔄
5.OpenDistro vs 原生 Elasticsearch 对比 ⚖️
backend_roles字段 | 内部用户可以设置,用于角色映射 | 内部用户通常不设置(只在角色映射 API 中使用) |
| 权限管理方式 | 鼓励使用角色映射,统一权限管理 | 内部用户直接分配,外部用户通过映射 |
| 灵活性 | 内部用户权限可通过映射规则统一调整 | 内部用户需要逐个修改 |
| 混淆度 | 容易混淆内部/外部用户边界 | 概念清晰,职责分离 |
6.OpenDistro 设计的优点与缺点 🎯
- 优点
- ✅统一管理:所有用户都通过角色映射管理权限。
- ✅动态调整:修改映射规则,影响所有相关用户。
- ✅属性扩展:可以结合
attributes字段做更复杂的映射。
- 缺点
- ❌概念混淆:模糊了内部用户和外部用户的界限。
- ❌安全性:手工填写
backend_roles可能出错。 - ❌维护复杂:需要维护额外的映射关系。
7.实际用例:为什么需要这个功能?💡
用例:批量权限调整
# 场景:所有"舰长"需要新权限# 传统方式:修改每个舰长用户的角色-用户 kirk:添加 "new_command_privileges"-用户 picard:添加 "new_command_privileges"-用户 sisko:添加 "new_command_privileges"# ... 需要修改几十个用户!# OpenDistro 方式:修改一条映射规则角色映射规则:-captains → command_role,new_command_privileges# 所有 backend_roles 包含 "captains" 的用户自动获得新权限8.混合使用模式 🛠️
OpenDistro 还支持混合模式:
PUT_opendistro/_security/api/internalusers/spock{"password":"spockpass","opendistro_security_roles":["science_officer"],// 直接分配"backend_roles":["starfleet","vulcan"],// 映射分配"attributes":{"species":"vulcan","logic_level":"high"}}权限计算=science_officer+ (starfleet映射的角色) + (vulcan映射的角色)
9.关键理解要点 📌
- 不是真正的 “后端”:OpenDistro 中的
backend_roles并不真的来自后端系统,而是手工配置的标签。 - 两层角色分配:
- 第一层:
opendistro_security_roles(直接分配) - 第二层:
backend_roles→ 通过映射间接分配
- 第一层:
- 设计哲学差异:
- Elasticsearch:内部用户和外部用户应该分开管理。
- OpenDistro:所有用户都应该能用统一的方式管理权限。
10.一句话总结 🎓
在 OpenDistro Security 中,内部用户的backend_roles是一个 “虚拟标签”,让它能够像外部用户一样通过角色映射机制获得权限,从而实现更灵活的统一权限管理。
这种设计与原生 Elasticsearch 不同,是 OpenDistro/OpenSearch 团队为了简化权限管理而做出的设计选择。
11.实战验证 ✨
本小节针对下面 6 种场景进行验证。
场景一:用户 → Roles,用户 → Backend roles → Roles
用户xiaoming-01会获得test-02的权限,可以读log-开头的索引。
但没有权限读非log-开头的索引,会报错:no permissions for [indices:data/read/search] and User [name=xiaoming-01, backend_roles=[apple-01], requestedTenant=null]。
场景二:用户 → Roles,用户 → Backend roles ❌ Roles
虽然apple-01未与test-02关联,但xiaoming-01直接与test-02关联,仍然拥有权限读取log-开头的索引。
场景三:用户 → Roles,用户 ❌ Backend roles → Roles
虽然xiaoming-01未与apple-01关联,但xiaoming-01直接与test-02关联,仍然拥有权限读取log-开头的索引。
场景四:用户 → Roles,用户 ❌ Backend roles ❌ Roles
相当于没有 Backend roles,用户xiaoming-01直接与test-02关联,拥有读取log-开头索引的权限。
场景五:用户 ❌ Roles,用户 → Backend roles → Roles
虽然用户xiaoming-01没有直接与test-02关联,但是他们通过apple-01作为 “桥梁” 进行了关联,用户xiaoming-01将拥有读取log-开头索引的权限。
场景六:用户 ❌ Roles,用户 ❌ Backend roles → Roles
此种情况下,用户xiaoming-01根本没有与test-02关联起来,自然是没有权限的。