Python 聊天文档安全性入门

将 RAG 模式与自己的数据一起使用生成聊天应用程序时,请确保每个用户根据其权限接收答案。 按照本文中的过程将文档访问控制添加到聊天应用。

授权用户应有权访问聊天应用文档中包含的答案。

具有所需身份验证访问权限的聊天应用的屏幕截图。

未经授权的用户不应有权从他们无权查看的安全文档访问答案。

聊天应用的屏幕截图,其中显示了指示用户无权访问数据的答案。

注意

本文使用一个或多个 AI 应用模板作为本文中的示例和指南的基础。 AI 应用模板为你提供了维护良好、易于部署的参考实现,可帮助确保 AI 应用有一个高质量的起点。

体系结构概述

如果没有文档安全功能,企业聊天应用具有使用 Azure AI 搜索和 Azure OpenAI 的简单体系结构。 答案是从存储文档的 Azure AI 搜索到 Azure AI 搜索的查询中确定的,并结合 Azure OpenAI GPT 模型的响应。 此简单流中不使用用户身份验证。

显示从查询到存储文档的 Azure AI 搜索确定的答案的体系结构图,以及来自 Azure OpenAI 的提示响应。

若要为文档添加安全性,需要更新企业聊天应用:

  • 使用 Microsoft Entra 将客户端身份验证添加到聊天应用。
  • 添加服务器端逻辑,以使用用户和组访问权限填充搜索索引。

体系结构图显示了对 Microsoft Entra ID 进行身份验证,然后将该身份验证传递给 Azure AI 搜索。

Azure AI 搜索不提供 本机 文档级权限,并且无法根据用户权限在索引中更改搜索结果。 相反,应用程序可以使用搜索筛选器来确保特定用户或特定组可以访问文档。 在搜索索引中,每个文档都应具有一个可筛选字段,用于存储用户或组标识信息。

体系结构图显示,为了保护 Azure AI 搜索中的文档,每个文档都包含在结果集中返回的用户身份验证。

由于授权未在 Azure AI 搜索中本机包含,因此需要添加一个字段来保存用户或组信息,然后 筛选 不匹配的任何文档。 若要实现此技术,需要:

  • 在索引中创建文档访问控制字段,专用于存储具有文档访问权限的用户或组的详细信息。
  • 使用相关的用户或组详细信息填充文档的访问控制字段。
  • 每当用户或组访问权限发生更改时,更新此访问控制字段。
  • 如果索引更新是使用索引器计划的,则下次运行索引器时会选取更改。 如果不使用索引器,则需要手动重新编制索引。

在本文中,可以使用示例脚本(作为搜索管理员运行)实现在 Azure AI 搜索中保护文档的过程。 这些脚本将单个文档与单个用户标识相关联。 可以采用这些 脚本 ,并应用自己的安全性和生产化要求,以满足需求。

确定安全配置

该解决方案提供布尔环境变量来启用此示例中文档安全性所需的功能。

参数 目的
AZURE_USE_AUTHENTICATION 设置为 “true设置为”后,允许用户登录到聊天应用并App 服务身份验证。 在聊天应用开发人员设置中启用Use oid security filter
AZURE_ENFORCE_ACCESS_CONTROL 设置为 true“设置为”时,需要对任何文档访问进行身份验证。 oid 和组安全性的开发人员设置将打开并禁用,以便无法从 UI 禁用它们。
AZURE_ENABLE_GLOBAL_DOCUMENTS_ACCESS 如果设置为 true此设置,则此设置允许经过身份验证的用户搜索未分配访问控制的文档,即使需要访问控制也是如此。 仅当启用此参数时 AZURE_ENFORCE_ACCESS_CONTROL ,才应使用此参数。
AZURE_ENABLE_UNAUTHENTICATED_ACCESS true设置为此设置时,即使强制实施访问控制,此设置也允许未经身份验证的用户使用该应用。 仅当启用此参数时 AZURE_ENFORCE_ACCESS_CONTROL ,才应使用此参数。

使用以下部分了解此示例中支持的安全配置文件。 本文配置 企业配置文件

企业:所需帐户 + 文档筛选器

网站的 每个用户必须 登录,网站包含所有用户公开的内容。 文档级别安全筛选器应用于所有请求。

环境变量:

  • AZURE_USE_AUTHENTICATION=true
  • AZURE_ENABLE_GLOBAL_DOCUMENTS_ACCESS=true
  • AZURE_ENFORCE_ACCESS_CONTROL=true

混合使用:可选帐户 + 文档筛选器

网站的 每个用户都可以 登录,网站包含所有用户公开的内容。 文档级别安全筛选器应用于所有请求。

环境变量:

  • AZURE_USE_AUTHENTICATION=true
  • AZURE_ENABLE_GLOBAL_DOCUMENTS_ACCESS=true
  • AZURE_ENFORCE_ACCESS_CONTROL=true
  • AZURE_ENABLE_UNAUTHENTICATED_ACCESS=true

先决条件

开发容器环境可用于完成本文所需的所有依赖项。 可以在 GitHub Codespaces(在浏览器中)或在本地使用 Visual Studio Code 运行开发容器。

若要使用本文,需要满足以下先决条件:

  • Azure 订阅。 免费创建一个
  • Azure 帐户权限 - Azure 帐户必须具有
  • 已在所需的 Azure 订阅中授予对 Azure OpenAI 的访问权限。 目前,仅应用程序授予对此服务的访问权限。 可以通过在 https://aka.ms/oai/access 上填写表单来申请对 Azure OpenAI 的访问权限。

需要更多先决条件,具体取决于首选的开发环境。

打开开发环境

现在从安装了完成本文所需的所有依赖项的开发环境开始。

GitHub Codespaces 运行由 GitHub 托管的开发容器,将 Visual Studio Code 网页版作为用户界面。 对于最简单的开发环境,请使用 GitHub Codespaces,以便预先安装完成本文所需的合适的开发人员工具和依赖项。

重要

所有 GitHub 帐户每月可以使用 Codespaces 最多 60 小时,其中包含 2 个核心实例。 有关详细信息,请参阅 GitHub Codespaces 每月包含的存储和核心小时数

  1. 开始在 Azure-Samples/azure-search-openai-demo GitHub 存储库的 main 分支上创建新的 GitHub Codespace。

  2. 右键单击以下按钮,然后选择“在新窗口中打开链接”,以便同时提供开发环境和文档

    在 GitHub Codespaces 中打开

  3. 在“创建 codespace”页上,查看 codespace 配置设置,然后选择“新建 codespace

    新建 codespace 之前的确认屏幕的截图。

  4. 等待 Codespace 启动。 此启动过程会花费几分钟时间。

  5. 在终端的屏幕底部,使用 Azure Developer CLI 登录到 Azure。

    azd auth login
    
  6. 完成身份验证过程。

  7. 本文中的剩余任务需要在此开发容器的上下文中完成。

使用 Azure CLI 获取所需信息

使用以下 Azure CLI 命令获取订阅 ID 和租户 ID。 复制要用作你的 AZURE_TENANT_ID值。

az account list --query "[].{subscription_id:id, name:name, tenantId:tenantId}" -o table

如果收到有关租户条件访问策略的错误,则需要没有条件访问策略的第二个租户。

  • 与用户帐户关联的第一个租户用于 AZURE_TENANT_ID 环境变量。
  • 第二个租户(没有条件访问)用于 AZURE_AUTH_TENANT_ID 环境变量来访问 Microsoft Graph。 对于具有条件访问策略的租户,请查找没有条件访问策略或 创建新租户的第二个租户的 ID。

设置环境变量。

  1. 运行以下命令,为 企业 配置文件配置应用程序。

    azd env set AZURE_USE_AUTHENTICATION true
    azd env set AZURE_ENABLE_GLOBAL_DOCUMENTS_ACCESS true
    azd env set AZURE_ENFORCE_ACCESS_CONTROL true
    
  2. 运行以下命令来设置租户,该租户授权用户登录到托管的应用程序环境。 替换为 <YOUR_TENANT_ID> 租户 ID。

    azd env set AZURE_TENANT_ID <YOUR_TENANT_ID>
    

注意

如果在用户租户上具有条件访问策略,则需要 指定身份验证租户

将聊天应用部署到 Azure

部署包括创建 Azure 资源、上传文档、创建 Microsoft Entra 标识应用(客户端和服务器),以及打开托管资源的标识。

  1. 运行以下 Azure Developer CLI 命令来预配 Azure 资源并部署源代码:

    azd up
    
  2. 使用下表回答 AZD 部署提示:

    提示 Answer
    环境名称 使用短名称来标识别名和应用等信息。 tjones-secure-chat
    订阅 选择要在其中创建资源的订阅。
    Azure 资源的位置 选择附近的位置。
    位置 documentIntelligentResourceGroupLocation 选择附近的位置。
    位置 openAIResourceGroupLocation 选择附近的位置。

    在部署应用后等待 5 或 10 分钟,以允许应用启动。

  3. 成功部署应用程序后,终端中会显示一个 URL。

  4. 选择标记为 (✓) Done: Deploying service webapp 的 URL 在浏览器中打开聊天应用程序。

    浏览器中聊天应用的屏幕截图,其中显示了有关聊天输入的多个建议以及用于输入问题的聊天文本框。

  5. 同意应用身份验证弹出窗口。

  6. 显示聊天应用时,请注意右上角用户已登录。

  7. 打开 “开发人员”设置 ,并注意已选中这两个选项并灰显(已禁用更改)。

    • 使用 oid 安全筛选器
    • 使用组安全组筛选器
  8. 选择包含 What does a product manager do?的卡片。

  9. 你会收到如下答案: The provided sources do not contain specific information about the role of a Product Manager at Contoso Electronics.

    浏览器中聊天应用的屏幕截图,其中显示了无法返回答案

为用户打开对文档的访问权限

打开确切文档的权限,以便 获取 答案。 这些信息需要几条信息:

  • Azure 存储
    • 帐户名
    • 容器名称
    • Blob/文档 URL role_library.pdf
  • Microsoft Entra ID 中的用户 ID

了解此信息后,更新文档的 role_library.pdf Azure AI 搜索索引oids字段。

获取存储中文档的 URL

  1. .azure 项目根目录的文件夹中,找到环境目录,并使用该目录打开 .env 该文件。

  2. AZURE_STORAGE_ACCOUNT搜索条目并复制其值。

  3. 使用以下 Azure CLI 命令获取内容容器中role_library.pdf blob 的 URL。

    az storage blob url \
        --account-name <REPLACE_WITH_AZURE_STORAGE_ACCOUNT \
        --container-name 'content' \
        --name 'role_library.pdf' 
    
    参数 目的
    --account-name Azure 存储帐户名称
    --container-name 此示例中的容器名称为 content
    --name 此步骤中的 Blob 名称为 role_library.pdf
  4. 复制 Blob URL 以供以后使用。

获取用户 ID

  1. 在 chap 应用中,选择 “开发人员设置”。
  2. “ID 令牌声明 ”部分中,复制你的 objectidentifier。 下一部分中的 USER_OBJECT_ID已知为 .
  1. 使用以下脚本更改 oids Azure AI 搜索 role_library.pdf 中的字段,以便你有权访问该字段。

    ./scripts/manageacl.sh \
        -v \
        --acl-type oids \
        --acl-action add \
        --acl <REPLACE_WITH_YOUR_USER_OBJECT_ID> \
        --url <REPLACE_WITH_YOUR_DOCUMENT_URL>
    
    参数 目的
    -v 详细输出。
    --acl-type 组或用户对象 ID(OID): oids
    --acl-action 添加到 搜索索引字段。 其他选项包括 removeremove_alllist
    --acl 组或用户 USER_OBJECT_ID
    --url 文件在 Azure 存储中的位置,例如 https://MYSTORAGENAME.blob.core.windows.net/content/role_library.pdf。 不要在 CLI 命令中用引号括住 URL。
  2. 此命令的控制台输出如下所示:

    Loading azd .env file from current environment...
    Creating Python virtual environment "app/backend/.venv"...
    Installing dependencies from "requirements.txt" into virtual environment (in quiet mode)...
    Running manageacl.py. Arguments to script: -v --acl-type oids --acl-action add --acl 00000000-0000-0000-0000-000000000000 --url https://mystorage.blob.core.windows.net/content/role_library.pdf
    Found 58 search documents with storageUrl https://mystorage.blob.core.windows.net/content/role_library.pdf
    Adding acl 00000000-0000-0000-0000-000000000000 to 58 search documents
    
  3. (可选)使用以下命令验证是否为 Azure AI 搜索中的文件列出了权限。

    ./scripts/manageacl.sh \
        -v \
        --acl-type oids \
        --acl-action list \
        --acl <REPLACE_WITH_YOUR_USER_OBJECT_ID> \
        --url <REPLACE_WITH_YOUR_DOCUMENT_URL>
    
    参数 目的
    -v 详细输出。
    --acl-type 组或用户(oids): oids
    --acl-action 列出 搜索索引字段 oids。 其他选项包括 removeremove_alllist
    --acl 组或用户 USER_OBJECT_ID
    --url 文件在 Azure 存储中的位置,例如 https://MYSTORAGENAME.blob.core.windows.net/content/role_library.pdf。 不要在 CLI 命令中用引号括住 URL。
  4. 此命令的控制台输出如下所示:

    Loading azd .env file from current environment...
    Creating Python virtual environment "app/backend/.venv"...
    Installing dependencies from "requirements.txt" into virtual environment (in quiet mode)...
    Running manageacl.py. Arguments to script: -v --acl-type oids --acl-action view --acl 00000000-0000-0000-0000-000000000000 --url https://mystorage.blob.core.windows.net/content/role_library.pdf
    Found 58 search documents with storageUrl https://mystorage.blob.core.windows.net/content/role_library.pdf
    [00000000-0000-0000-0000-000000000000]
    

    输出末尾的数组包括USER_OBJECT_ID,用于确定文档是否在答案中使用 Azure OpenAI。

验证 Azure AI 搜索是否包含USER_OBJECT_ID

  1. 打开Azure 门户并搜索你的 AI Search

  2. 从列表中选择搜索资源。

  3. 选择 “搜索管理 -> 索引”。

  4. 选择 gptkbindex

  5. 选择“ 视图 -> JSON”视图

  6. 将 JSON 替换为以下 JSON。

    {
      "search": "*",
      "select": "sourcefile, oids",
      "filter": "oids/any()"
    }
    

    这会搜索字段具有任何值并返回sourcefileoids字段的所有文档oids

  7. role_library.pdf如果没有 oid,请返回到“提供用户对 Azure 搜索”部分中文档的访问权限并完成这些步骤。

验证用户对文档的访问权限

如果已完成这些步骤但未看到正确的答案,请在 Azure AI 搜索 role_library.pdf中验证是否已正确设置USER_OBJECT_ID。

  1. 返回到聊天应用。 可能需要再次登录。

  2. 输入相同的查询,以便在 role_library Azure OpenAI 答案中使用内容: What does a product manager do?

  3. 查看结果,该结果现在包括角色库文档中的相应答案。

    浏览器中聊天应用的屏幕截图,其中显示了答案已返回。

清理资源

清理 Azure 资源

本文中创建的 Azure 资源的费用将计入你的 Azure 订阅。 如果你预计将来不需要这些资源,请将其删除,以避免产生更多费用。

运行以下 Azure Developer CLI 命令以删除 Azure 资源并删除源代码:

azd down --purge

清理 GitHub Codespaces

删除 GitHub Codespaces 环境可确保可以最大程度地提高帐户获得的每核心免费小时数权利。

重要

有关 GitHub 帐户权利的详细信息,请参阅 GitHub Codespaces 每月包含的存储和核心小时数

  1. 登录到 GitHub Codespaces 仪表板 (https://github.com/codespaces)。

  2. 找到当前正在运行的、源自 Azure-Samples/azure-search-openai-demo GitHub 存储库的 Codespaces。

    所有正在运行的 Codespaces 的屏幕截图,其中包含它们的状态和模板。

  3. 打开 codespace 的上下文菜单,然后选择“删除”。

    单个 codespace 的上下文菜单的屏幕截图,突出显示了删除选项。

获取帮助

此示例存储库提供故障排除信息

故障排除

本部分提供有关本文特定问题的疑难解答。

提供身份验证租户

当身份验证位于独立于托管应用程序的租户中时,需要使用以下过程设置该身份验证租户。

  1. 运行以下命令,将示例配置为对身份验证租户使用第二个租户。

    azd env set AZURE_AUTH_TENANT_ID <REPLACE-WITH-YOUR-TENANT-ID>
    
    参数 目的
    AZURE_AUTH_TENANT_ID 如果 AZURE_AUTH_TENANT_ID 已设置,则它是托管应用的租户。
  2. 使用以下命令重新部署解决方案。

    azd up
    

后续步骤