Elasticsearch:将文档级安全性 (DLS) 添加到你的内部知识搜索

作者:来自 Elastic Sean Story

你的企业很可能淹没在内部数据中。

你拥有问题跟踪、笔记记录、会议记录、维基页面、视频录制、聊天以及即时消息和私信。 并且不要忘记电子邮件!

难怪如此多的企业都在尝试创造工作场所搜索体验 - 为员工提供集中、一站式的内部信息搜索服务。

通过 Elastic 的连接器(connectors)目录,这相对容易做到。 但是,当你将所有数据编入索引并准备好进行搜索后,如何确保其安全? 毕竟,苔丝(来自工程部门)不应该查看鲍勃(来自人力资源部门)关于绩效评估的笔记。 你如何确保访问此统一搜索栏的每个单独用户都只能获得他们有权查看的数据的独特视图?

进入文档级安全性 (document level security - DLS)。

背景

关注 Elasticsearch 一段时间的人可能已经意识到,DLS 已经成为 Elasticsearch 的一项功能相当长一段时间了。 它是用户授权(user authorization)这一更大主题的一部分,而且确实非常简单。 你将元数据嵌入到 Elasticsearch 文档中,然后创建一个 Elasticsearch 查询,根据描述用户授权的文档元数据进行过滤。 该查询用于创建 Elasticsearch 角色。

在查询时,当搜索用户进行身份验证时,他们的角色(如果有)将被识别,并且嵌入的查询过滤器(如果有)将应用于他们的搜索。

让我们看一个简单的例子。 假设我们有两个文档:

PUT example/_doc/1
{
  "my-data": true,
  "text": "This data is mine"
}

PUT example/_doc/2
{
  "my-data": false,
  "text": "This data belongs to someone else"
}

仅获取我的数据的查询是:

GET example/_search
{
  "query": {
    "term": {
      "my-data": {
        "value": true
      }
    }
  }
}

该查询可以嵌入到角色中,例如:

POST /_security/role/my_role
{
  "indices": [
    {
      "names": [ "example" ],
      "privileges": ["read"],
      "query": {
        "term": {
          "my-data": {
            "value": true
          }
        }
      }
    }
  ]
}

注意:我们必须为我们的 Elasticsearch 集群配置安全才可以顺利地运行上面的命令。

因此,如果我的用户被分配角色 my_role,如果我这样做:

GET example/_search

我们可以使用如下的命令来进行验证:

curl -k -XGET -u liuxg:password "https://localhost:9200/example/_search" -H "kbn-xsrf: reporting"

从上面的输出中,我们可以看到只有文档 1 被搜索到。文档 2 没有被搜索到。

虽然这个例子在理论上很简单,但它有相对较多的移动部件。

  • 你必须确保文档包含相关元数据("my-data": true 与 "my-data": false)
  • 你必须相信这些文档中的元数据是准确的
  • 你必须使用精心设计的 Elasticsearch 查询为每个搜索用户创建一个角色
  • 你必须确保您创建的每个角色在查询时正确映射到正确的用户
  • 你必须确保上述所有内容均保持最新。

最后一项尤其困难。 当你企业中的人员加入、离开、切换团队或晋升时,这需要进行更改 - 可能会更改你的(元)数据和你的角色。 如果你添加支持共享或访问编辑的数据源,你肯定需要确保你的(元)数据保持最新。

使用 Elastic 连接器

连接器文档级安全性基于 Elasticsearch DLS 构建。 对于许多连接器来说,这包括同步相关元数据和角色描述符以支持 DLS。 这会导致内容索引中的文档自动包含元数据(通常在 _allow_access_control 字段中)来描述有权搜索该文档的人员/组,以及特殊 .search-acl-filter-<index 中的文档 -name> 索引,包含为给定搜索用户构建具体角色或 API 密钥所需的角色描述符 JSON。

你可以在此处找到哪些连接器具有可用的 DLS。 在本博客中,我们将引用一个使用 Sharepoint Online 连接器的示例应用程序。 这是我们启用 DLS 的第一个连接器,但该示例可以轻松适应任何启用 DLS 的连接器。

如果你的连接器符合条件,并且你拥有 Platinum+ Elasticsearch 许可证,则可以通过连接器配置页面上的开关启用 DLS。

从那里开始,只需运行完全同步和访问控制同步,Elasticsearch 将获得所需的所有数据。

一个例子

然后什么?

一旦 Elasticsearch 拥有角色描述符和文档数据以及这些角色过滤器的足够元数据,你就可以构建安全的搜索体验。

我们已经构建了一个示例知识搜索应用程序,我们将在本博客中使用它,欢迎你查看其源代码。 但是,我们确实想强调,这只是一个示例 - 它尚未准备好在生产中自行运行。 请运用良好的判断力,不要运行你未阅读或不理解的代码。

该应用程序的架构非常简单。

它由 Flask 后端和 React 前端组成。 后端配置了环境变量以与 Elasticsearch 建立连接。

export ELASTICSEARCH_URL=...
export ELASTIC_USERNAME=...
export ELASTIC_PASSWORD=...

使用此连接,后端提供三个端点:

  • GET /api/persona 此端点列出连接器在访问控制同步期间找到的 “身份” 或 “角色” 的标识符。 前端使用此列表填充角色下拉列表,以便演示搜索结果如何根据所选角色而变化。
  • GET /api/indices 该端点列出了你的搜索应用程序中已包含的索引。 前端使用此列表来允许你选择要搜索的列表。
  • GET /api/api_key?persona=<persona> 此端点根据所选角色创建并返回 Elasticsearch API 密钥。 在生产系统中,角色不会是请求参数,而是从身份验证凭据中推断出来。 然后前端使用此 API 密钥向 Elasticsearch 发出搜索请求。

注意事项

如上所述,该示例不应在生产中使用。 差距包括:

  • 它不实现身份验证。 生产就绪的应用程序需要一种方法让用户进行身份验证并验证其身份,而不是从下拉列表中选择用户。
  • 它不使用 SSL/TLS。 后端当前通过 HTTP(而不是 HTTPS)将 Elasticsearch API 密钥传输到前端。
  • 前端直接向 Elasticsearch 发出 /_search 请求。 根据生产用例,你可能不希望像这样向最终用户公开 Elasticsearch。 相反,建议从前端向后端发出请求(同样,实施身份验证),然后让后端将这些请求转换为 Elasticsearch 查询。

源代码

下面我们链接到使用 DLS 实现搜索所需的关键代码片段。

创建经过身份验证的用户的角色描述符

代码链接


            identity = elasticsearch_client.get(
                index=identities_index, id=persona)
            permissions = identity["_source"]["query"]["template"]["params"][
                "access_control"
            ]
            role_descriptor = {
                "dls-role": {
                    "cluster": ["all"],
                    "indices": [
                        {
                            "names": [search_app_name],
                            "privileges": ["read"],
                            "query": {
                                "template": {
                                    "params": {"access_control": permissions},
                                    "source": """{
                                        "bool": {
                                            "should": [
                                                {
                                                    "bool": {
                                                        "must_not": {
                                                            "exists": {
                                                                "field": "_allow_access_control"
                                                            }
                                                        }
                                                    }
                                                },
                                                {
                                                    "terms": {
                                                        "_allow_access_control.enum": {{#toJson}}access_control{{/toJson}}
                                                    }
                                                }
                                            ]
                                        }
                                    }""",
                                }
                            },
                        }
                    ],
                    "restriction": {"workflows": ["search_application_query"]},
                }
            }

你可能会注意到,此角色描述符中的查询模板比本博客前面提供的简单示例要复杂得多。 这个查询做了几件事:

  1. 它使用查询模板,而不是显式查询。 这使得在阅读时更容易将一长串权限列表与查询语法分开。
  2. 它使用布尔查询。 这使我们能够结合多个逻辑检查。
  3. 它授予对不包含 _allow_access_control 字段的任何文档的访问权限
  4. 它授予对 _allow_access_control 字段包含此用户 permissions 中找到的值的文档的访问权限

从该角色描述符创建 API 密钥

代码链接


        api_key = elasticsearch_client.security.create_api_key(
            name=search_app_name+"-internal-knowledge-search-example-"+persona, expiration="1h", role_descriptors=role_descriptor)
        return {"api_key": api_key['encoded']}

使用 API 密钥搜索

代码链接


      const apiKey = searchPersonaAPIKey;

      const client = SearchApplicationClient(
        appName,
        searchEndpoint,
        apiKey,
        {
          facets: {
            description: {
              type: "text",
            },
          },
        },
        {
          disableCache: true,
        }
      );

      const sortArray = Object.values(sorts).map((sort) => ({
        [sort.title]: sort.sortDirection,
      }));

      const rawResults = await client()
        .query(query)
        .setSort(sortArray)
        .setPageSize(10)
        .addParameter("indices", indexFilter)
        .search();

      const searchResults = rawResults.hits.hits.map((hit: any) => {
        return mapHitToSearchResult(hit);
      });

原文:Adding Document Level Security (DLS) to your Internal Knowledge Search — Elastic Search Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/363786.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RPC教程 7.服务发现与注册中心

0.前言 这一节的内容只能解决只有一个服务的情况。要是有多个服务(即是多个结构体&#xff09;这种就解决不了&#xff0c;也即是没有服务ip地址和服务实例的映射关系。 1.为什么需要注册中心 在上一节中&#xff0c;客户端想要找到服务实例的ip,需要硬编码把ip写到代码中。…

python+selenium的web自动化】- 元素的常用操作详解(一)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

PySimpleGUI 综合应用|英语文本朗读以及转换为语音Mp3

PySimpleGUI 综合应用 目录 PySimpleGUI 综合应用 应用界面 完整代码 所需模块 PySimpleGUI pyttsx3 pyaudio rapidfuzz 字典格式 应用界面 完整代码 英语朗读器.pyw import PySimpleGUI as sg import pyttsx3,pyaudio,pyperclip import os,re,datetime,wave,threa…

EasyExcel使用,实体导入导出

简介 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存&#xff0c;poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题&#xff0c;但POI还是有一些缺陷&#xff0c;比如07版Excel解压缩以及解压后存储都是在内存中…

@JsonProperty(“xx“)的使用

JsonProperty(“xx”) 指定JSON字段的名称 常见的场景 1、第三方调用本系统&#xff0c;参数接收不到 &#xff0c;没有使用驼峰命名&#xff0c;或者传参格式不一致问题 2、前后端调试&#xff0c;接收不到个别参数 遇到的场景描述&#xff1a; 1&#xff0c;项目提供ope…

Vue中的指令修饰符计算属性和方法的区别

一、指令修饰符 1.什么是指令修饰符&#xff1f; 所谓指令修饰符就是通过“.”指明一些指令后缀 不同的后缀封装了不同的处理操作 —> 简化代码 2.按键修饰符 keyup.enter —>当点击enter键的时候才触发 代码演示&#xff1a; <!DOCTYPE html> <html lang…

【ChatGPT】文本向量化与余弦相似度:揭开文本处理的神秘面纱(5)

1、引言 在这个数字化的时代&#xff0c;我们每天都会面对大量的文本信息&#xff0c;从社交媒体到新闻报道&#xff0c;文本无处不在。但是&#xff0c;计算机要如何理解和处理这些文字呢&#xff1f;本文将为大家揭开其中的一些奥秘&#xff0c;详细解释文本向量化的概念&am…

C++ hash—unordered_mapset

目录 一. unordered系列关联式容器 1、文档说明 2、接口说明 1. 构造 2. 容量 3. 迭代器 4. 元素访问 5. 查询 6. 修改 7. 桶操作 8. 测试 二、unordered_set 1、​​​​​​​文档说明 2、接口说明 1. 构造 2. 容量 3. 迭代器 4. 元素访问 5. 插入和删除…

【脑电信号处理与特征提取】P7-贾会宾:基于EEG/MEG信号的大尺度脑功能网络分析

基于EEG/MEG信号的大尺度脑功能网络分析 Q: 什么是基于EEG/MEG信号的大尺度脑功能网络分析&#xff1f; A: 基于脑电图&#xff08;EEG&#xff09;或脑磁图&#xff08;MEG&#xff09;信号的大尺度脑功能网络分析是一种研究大脑活动的方法&#xff0c;旨在探索脑区之间的功能…

Win11系统连接带HDMI接口的显示器后,电脑没有声音如何调试

解决这个问题的方法很简单&#xff0c;没有那么复杂。之所以使用HDMI接口连接了显示器后没声音&#xff0c;原因就是HDMI接口是包含音频视频两种信号的接口。当电脑的HDMI接口被使用时&#xff0c;系统就会默认从HDMI设备输出声音信号了&#xff0c;而此时如果HDMI设备没有声音…

vivado里的LUT、LUTRAM、FF、BRAM、DSP、IO、BUFG、MMCM资源介绍

vivado里的LUT、LUTRAM、FF、BRAM、DSP、IO、BUFG、MMCM资源介绍 提示&#xff1a;以下是本篇文章正文内容&#xff0c;写文章实属不易&#xff0c;希望能帮助到各位&#xff0c;转载请附上链接。 vivado实现电路用到的资源类型 LUT&#xff08;Look-Up Table&#xff09;&am…

文心一言APP上线新功能,一张照片、三句话即可生成专属数字分身

只需一张照片、录制三句话&#xff0c;就能拥有一个自己的数字分身&#xff1f;这不是科幻电影&#xff0c;而是文心一言APP上线的新功能 - 数字分身。 目前&#xff0c;文心一言APP正在内测数字分身新功能&#xff0c;明天起&#xff0c;iOS和Android用户升级新版本后&#xf…

给定长度为n的递增数组a,进行n - 1次操作:求当前a数组的差分数组,然后使a为差分数组,继续进行操作。求最后数组的元素是什么

题目 思路: #include <bits/stdc++.h> using namespace std; #define int long long typedef long long ll; #define pb push_back #define lson p << 1 #define rson p << 1 | 1 #define fi first #define se second const int maxn = 1e6 + 5, maxm = 5e…

java之基础知识、零碎知识

MENU java学习路程之篇一、知识点、path环境变量、计算机发展史、数据的存储和运算、人机交互、计算机语言java学习路程之篇二、知识点、JAVA背景介绍、配置JAVA_HOME、跨平台、JVM、JRE、JDKjava学习路程之篇三、知识点、类、模块、项目、操作、下载、安装、IDEA、开发工具jav…

Vue-49、Vue技术实现动画效果

1、首先&#xff0c;在Vue项目中的src/components文件夹下创建一个名为AnimatedBox.vue的文件。 2、编辑AnimatedBox.vue文件&#xff0c;添加以下代码&#xff1a; <template><div class"animated-box" click"toggle"><transition name&q…

Excel没有内置统计字数功能,但可以用一些变通的方法

是否需要计算Excel工作簿中某个单元格或单元格范围内的单词数? 出于多种原因,你可能需要计算文本数据中的字数。也许你有逗号分隔的列表,需要计算每个列表中的项目数。 不幸的是,Excel没有内置的单词计数方法。但是有一些聪明的方法可以得到你需要的结果。 这篇文章将向…

【Docker】【深度学习算法】在Docker中使用gunicorn启动多个并行算法服务,优化算法服务:从单进程到并行化

文章目录 优化算法服务&#xff1a;从单进程到并行化单个服务架构多并行服务架构Docker化并指定并行服务数量 扩展知识 优化算法服务&#xff1a;从单进程到并行化 在实际应用中&#xff0c;单个算法服务的并发能力可能无法满足需求。为了提高性能和并发处理能力&#xff0c;我…

OpenHarmony—开发及引用静态共享包(API 9)

HAR(Harmony Archive&#xff09;是静态共享包&#xff0c;可以包含代码、C库、资源和配置文件。通过HAR可以实现多个模块或多个工程共享ArkUI组件、资源等相关代码。HAR不同于HAP&#xff0c;不能独立安装运行在设备上&#xff0c;只能作为应用模块的依赖项被引用。 接下来&a…

Matlab图像模拟加噪——高斯噪声、椒盐噪声、泊松噪声、乘性噪声、均匀噪声、指数噪声

1.高斯噪声 (1)通过均值和方差来产生 Jimnoise(I, gaussian, 0, 0.01);%高斯噪声&#xff0c;均值为0&#xff0c;方差为0.01(2)通过位置信息来产生 Iim2double(I); Vzeros(size(I)); %建立矩阵V for i1:size(V, 1)V(i,:)0.02*i/size(V,1); end Jimnoise(I, localvar, V); …

Android Jetpack Compose之底部导航栏的实现

目录 1.概述2. 效果展示3. 代码实现3.1 定义底部导航栏的tab项3.2 整体页面架构搭建3.3 底部导航栏的实现3.4 所有代码 4.总结 1.概述 写过一段Android jetpack compose 界面的小伙伴应该都用过Compose的脚手架Scaffold&#xff0c;利用它我们可以很快的实现一个现代APP的主流…