You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Elasticsearch中实现基于自定义权限的表单搜索结果过滤?

Elasticsearch 表单级权限搜索结果过滤实现方案

核心原则:禁止在业务层拉取全量结果后二次过滤,这种方案在数据量上涨后会出现分页异常、性能骤降问题,还极易因逻辑疏漏产生越权漏洞,所有过滤逻辑必须下沉到ES查询层执行。


方案1:权限字段标记 + 查询前置过滤(适配自定义权限集的首选方案)

这套方案灵活度最高,完全适配单表单独立配置自定义权限集的场景,落地成本最低:

  • 索引映射层面:给表单文档新增keyword类型的权限字段,比如命名为allowed_perms,不要给这个字段开分词,字段值存储当前表单允许访问的全部自定义权限标识,比如某张报销表单可以存["form:reimburse:view", "dept:finance:member", "user:1001:owner"]
  • 查询逻辑层面:每次处理用户搜索请求时,先在业务侧获取当前登录用户持有的全部权限标识列表,拼接ES查询时,将权限过滤条件作为bool查询的filter子句强制写入,和用户输入的搜索条件平级,filter子句不参与相关性算分,会自动走缓存,查询性能极高。

参考查询DSL示例:

{
  "query": {
    "bool": {
      "must": [
        // 此处放用户实际搜索条件,比如匹配表单标题、表单内容
        {"match": {"form_title": "差旅报销"}}
      ],
      "filter": [
        // 强制拼接的权限过滤条件,仅返回用户持有的权限命中的表单
        {"terms": {"allowed_perms": ["user:10086:view", "dept:product:member", "public:form:view"]}}
      ]
    }
  }
}

如果存在公开无权限限制的表单,只需要给这类表单的allowed_perms字段统一加入公共权限标识public:form:view,给所有合法登录用户默认带上该权限标识即可,不需要额外调整逻辑。


方案2:ES原生文档级安全(DLS,适合强管控零漏判场景)

如果担心业务开发写查询时遗漏权限过滤条件导致越权,可以用ES自带的文档级安全功能(X-Pack基础版即可使用,无需付费授权):

  • 提前在ES侧给不同角色配置对应的数据访问规则,比如给普通员工角色配置规则:仅允许查询allowed_perms字段包含当前用户所持权限标识的文档
  • 应用侧使用对应用户角色的认证凭证访问ES,所有查询请求会在ES引擎底层自动套用权限过滤规则,业务代码不需要手动拼接权限条件,从基础设施层面杜绝越权可能
  • 该方案的局限性:如果表单权限自定义程度极高、用户权限动态调整非常频繁,需要频繁更新ES侧的角色规则,维护成本会高于方案1,更适合权限模型相对固定的场景。

避坑提示

  • 权限字段必须使用keyword类型:如果误用text类型存储权限标识,分词器会把完整权限码拆成多个词元,会出现跨权限误命中的问题
  • 不要开启source过滤后就忽略权限校验:即便前端不展示敏感字段,只要结果返回了无权限的文档ID,依然属于越权漏洞
  • 分页查询不需要特殊调整:因为过滤逻辑在查询阶段执行,分页是基于过滤后的结果集计算,不会出现漏数据、跨权限展示的问题

内容的提问来源于stack exchange,提问作者kylie.zoltan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:39:19