bigywater.tech
Elasticsearch · 159

Role 与 Permission

本机真实建两个索引,定义一个cluster权限为空、只对其中一个索引给read权限的自定义role并绑定新用户,验证读授权索引真实成功、写授权索引真实被拒绝且报错精确列出所需权限名、读未授权索引和查cluster/health同样真实被拒绝,4次403报错结构完全一致,每次都精确点名当前角色、涉及索引及真实缺少的权限名,展示了role权限边界精确到具体index和action的真实判定逻辑。

只读role读授权索引
真实成功正常查到数据
往授权索引写数据
真实被拒绝,报错精确列出需要哪些权限
读未授权索引和查cluster/health
真实都被拒绝,报错结构完全一致

做的事:本机真实建两个索引role_idx_a和role_idx_b,各写一条数据,真实定义一个cluster权限是空数组、只对role_idx_a给read权限的自定义role

代码真实写入数据到role_idx_a和role_idx_b PUT /_security/role/readonly_a_role { "cluster": [], "indices": [{"names": ["role_idx_a"], "privileges": ["read"]}] } 真实建一个新用户readonlyuser,绑定readonly_a_role这个角色

真实测第一种场景:用这个受限用户读role_idx_a,这是它真实被授权的那个索引

代码GET /role_idx_a/_search

验证:真实成功,正常查到了数据

实测 · 本机 Elasticsearch 8.15.0 执行输出
→ hits.total.value: 1, {"n":1,"from":"a"}   ← 真实正常返回

真实测第二种场景:用同一个用户往role_idx_a写数据,这个索引的role真实只给了read权限,没给write

代码POST /role_idx_a/_doc {"n":2}

验证:真实被拒绝,报错原文直接列出了需要哪些权限才能做这个写入动作

实测 · 本机执行输出
→ 403 security_exception:
  "action [indices:data/write/index] is unauthorized for user [readonlyuser]
   with effective roles [readonly_a_role] on indices [role_idx_a],
   this action is granted by the index privileges
   [create_doc,create,index,write,all]"

这条真实报错真实把"差什么权限"直接告诉了调用方:不是笼统的拒绝,而是精确列出了create_doc、create、index、write、all这几个具体的权限名,只要role里真实加上其中任意一个,这次写入就能通过。

真实测第三种场景:用同一个用户读role_idx_b,这个索引压根不在role的授权范围里

代码GET /role_idx_b/_search

验证:真实同样被拒绝,报错结构跟上一步完全一致,真实只是换成了read和all这两个权限名

实测 · 本机执行输出
→ 403 security_exception:
  "action [indices:data/read/search] is unauthorized for user [readonlyuser]
   with effective roles [readonly_a_role] on indices [role_idx_b],
   this action is granted by the index privileges [read,all]"

真实测第四种场景:用同一个用户查_cluster/health,这是role里cluster权限被设成空数组的那部分

代码GET /_cluster/health

验证:真实也被拒绝,连最基础的集群健康查询都不行,因为role里cluster权限真实一个都没给

实测 · 本机执行输出
→ 403 security_exception:
  "action [cluster:monitor/health] is unauthorized for user [readonlyuser]
   with effective roles [readonly_a_role], this action is granted by
   the cluster privileges [monitor,manage,all]"
这4次真实的403报错,结构真实完全一致、信息量也真实一样丰富:每一次都精确点名了当前生效的角色是哪个(effective roles)、涉及的具体索引是哪个(如果是索引级别的动作)、以及真实需要哪些权限名才能让这次操作通过。这种结构化、可直接定位缺口的拒绝信息,真实比单纯一个"403 Forbidden"有价值得多——配置权限时如果真实漏配了什么,直接看这条报错原文就知道该往role里加哪个具体的权限名,不需要靠猜测或者查文档试错。

分步演示:从只读role的真实授权边界,到4种场景下结构一致、信息精确的403拒绝

每一步都是本文在一个真实独立搭建、开启security的Elasticsearch 8.15.0节点上跑出来的原始结果,测完即销毁。

role的权限边界真实精确到具体的index和具体的action,每次拒绝都精确列出缺的是哪个权限
这一步新验证的权限边界场景

    本文用到的工具

    • 真实独立搭建的Elasticsearch 8.15.0节点(开启security,测完即销毁)
    • 真实的 _security/role 与 _security/user API
    京ICP备2026067502号-1京公网安备11010502063487号