다음을 통해 공유

使用标识将应用连接到 Azure AI 搜索

在应用程序代码中,可以设置与 Azure AI 搜索的无密钥连接,使用 Microsoft Entra ID 和角色进行身份验证和授权。 应用程序对大多数 Azure 服务的请求必须使用密钥或无密钥连接进行身份验证。 开发人员必须尽量避免在不安全的位置公开密钥。 能够访问密钥的任何人都可以对服务进行身份验证。 与帐户密钥相比,无密钥身份验证具有更好的管理和安全优势,因为无需存储密钥(或连接字符串)。

本文介绍如何在应用程序代码中使用 DefaultAzureCredential

若要在代码中实现无键连接,请执行以下步骤:

  • 在搜索服务上启用基于角色的访问
  • 根据需要设置环境变量。
  • 使用 Azure 标识库凭据类型创建 Azure AI 搜索客户端对象。

先决条件

  • Azure AI 搜索,任何区域,但它必须是计费层(基本层或更高层)。

  • 在搜索服务上启用基于角色的访问

  • Azure AI 搜索上的角色分配。 将这些角色分配给身份:

    • 用于本地开发的搜索服务参与者搜索索引数据参与者(完全访问权限)
    • 用于生产只读查询的搜索索引数据读取器

    有关分步说明,请参阅 “分配角色进行开发”。

安装 Azure 标识客户端库

要使用无密钥方法,请使用 Azure 标识客户端库更新启用了 AI 搜索的代码。

安装 适用于 .NET 的 Azure 标识客户端库Azure 搜索文档客户端库

dotnet add package Azure.Identity
dotnet add package Azure.Search.Documents

更新源代码以使用 DefaultAzureCredential

使用 Azure 标识库的 DefaultAzureCredential,可以在本地开发环境和 Azure 云中运行相同的代码。 创建一个单一凭据,并在需要时重复使用该凭据实例,以利用令牌缓存。

有关适用于 .NET 的 DefaultAzureCredential 的详细信息,请参阅适用于 .NET 的 Azure 标识客户端库

using Azure;
using Azure.Search.Documents;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.Models;
using Azure.Identity;
using System;
using static System.Environment;

string endpoint = GetEnvironmentVariable("AZURE_SEARCH_ENDPOINT");
string indexName = "my-search-index";

DefaultAzureCredential credential = new();
SearchClient searchClient = new(new Uri(endpoint), indexName, credential);
SearchIndexClient searchIndexClient = new(endpoint, credential);

Reference:SearchClient、SearchIndexClientDefaultAzureCredential

验证连接

设置客户端后,通过运行一个简单的操作来验证连接。 以下示例列出搜索服务上的索引:

// List indexes to verify connection
var indexes = searchIndexClient.GetIndexNames();
foreach (var name in indexes)
{
    Console.WriteLine(name);
}

成功的连接将输出索引的名称(如果没有索引,则为空列表)。 如果收到身份验证错误,请验证是否已启用基于角色的访问,并且您的身份具有所需的角色分配。

默认颁发机构为 Azure 公有云。 主权云或专用云的自定义 audience 值包括:

  • https://search.azure.cn(适用于由世纪互联运营的 Azure)

本地开发

使用角色的本地开发过程包括以下步骤:

  • 为特定资源的 RBAC 角色分配个人标识。
  • 使用 Azure CLI 或 Azure PowerShell 等工具向 Azure 进行身份验证。
  • 为资源建立环境变量。

用于本地开发的角色

作为本地开发人员,你的 Azure 标识需要能够完全控制数据平面操作。 以下是建议的角色:

  • 搜索服务参与者,创建和管理对象
  • 搜索索引数据参与者,加载和查询索引

使用以下工具之一查找个人标识。 使用该标识作为 <identity-id> 值。

在以下命令中,将<role-name><identity-id><subscription-id><resource-group-name>这些占位符替换为您的实际值。

  1. 登录到 Azure CLI。

    az login
    

    此时会打开浏览器窗口进行身份验证。 成功登录后,终端会显示订阅信息。

  2. 获取个人标识。

    az ad signed-in-user show \
        --query id -o tsv
    

    该命令返回用户对象 ID(GUID)。 请保存其值供下一步骤使用。

  3. 将基于角色的访问控制 (RBAC) 角色分配给资源组的标识。

    az role assignment create \
        --role "<role-name>" \
        --assignee "<identity-id>" \
        --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>"
    

    成功的分配返回具有角色分配详细信息的 JSON 对象。

用于本地开发的身份验证

在本地开发环境中使用工具向 Azure 标识进行身份验证。 进行身份验证后,您的源代码中的DefaultAzureCredential 实例会查找并使用您的身份进行身份验证。

选择一个工具,在本地开发过程中用于身份验证

为本地开发配置环境变量

若要连接到 Azure AI 搜索,代码需要知道资源终结点。

为 Azure AI 搜索终结点创建一个名为 AZURE_SEARCH_ENDPOINT 的环境变量。 此 URL 通常采用 https://<YOUR-RESOURCE-NAME>.search.azure.cn/ 格式。

生产工作负载

部署生产工作负载包括以下步骤:

  • 选择遵循最低特权原则的 RBAC 角色。
  • 将对特定资源的 RBAC 角色分配给生产标识。
  • 为资源设置环境变量。

用于生产工作负载的角色

若要创建生产资源,需要创建用户分配的托管标识,然后使用正确的角色将该标识分配给资源。

建议对生产应用程序使用以下角色:

角色名称 Id
搜索索引数据读取者 1407120a-92aa-4202-b7e9-c0e197c71c8f

生产工作负载的身份验证

使用以下 Azure AI 搜索 Bicep 模板创建资源并设置 的身份验证identityId。 Bicep 需要角色 ID。 此 Bicep 代码片段中显示的 name 不是 Azure 角色;它特定于 Bicep 部署。

// main.bicep
param environment string = 'production'
param roleGuid string = ''

module aiSearchRoleUser 'core/security/role.bicep' = {
    scope: aiSearchResourceGroup
    name: 'aiSearch-role-user'
    params: {
        principalId: (environment == 'development') ? principalId : userAssignedManagedIdentity.properties.principalId 
        principalType: (environment == 'development') ? 'User' : 'ServicePrincipal'
        roleDefinitionId: roleGuid
    }
}

main.bicep 文件调用以下通用 Bicep 代码,用于创建任何角色。 可以选择创建多个 RBAC 角色,例如为用户创建一个角色,再为生产创建另一个角色。 这样,就可以在同一 Bicep 部署中同时启用开发和生产环境。

// core/security/role.bicep
metadata description = 'Creates a role assignment for an identity.'
param principalId string // passed in from main.bicep

@allowed([
    'Device'
    'ForeignGroup'
    'Group'
    'ServicePrincipal'
    'User'
])
param principalType string = 'ServicePrincipal'
param roleDefinitionId string // Role ID

resource role 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
    name: guid(subscription().id, resourceGroup().id, principalId, roleDefinitionId)
    properties: {
        principalId: principalId
        principalType: principalType
        roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId)
    }
}

为生产工作负载配置环境变量

若要连接到 Azure AI 搜索,代码需要知道资源终结点以及托管标识的 ID。

为已部署的无密钥 Azure AI 搜索资源创建环境变量:

  • AZURE_SEARCH_ENDPOINT:此 URL 是 Azure AI 搜索资源的接入点。 此 URL 通常采用 https://<YOUR-RESOURCE-NAME>.search.azure.cn/ 格式。
  • AZURE_CLIENT_ID:这是要进行身份验证的标识。

解决常见问题

错误 原因 解决方案
AuthenticationFailedException 凭据缺失或无效 确保已使用 az login (CLI) 或 Connect-AzAccount (PowerShell) 登录。 验证 Azure 帐户是否有权访问订阅。
403 Forbidden 标识缺少所需角色 分配适当的角色(用于查询的搜索索引数据读取者、用于索引编制的搜索索引数据参与者)。 角色分配最多可能需要 10 分钟才能传播。
401 Unauthorized 搜索服务上未启用 RBAC 在 Azure 门户中的“设置>>”下启用基于角色的访问。
ResourceNotFoundException 终结点或索引名称无效 AZURE_SEARCH_ENDPOINT验证环境变量是否与搜索服务 URL 匹配(格式: https://<service-name>.search.azure.cn) 。
CredentialUnavailableException 找不到有效的凭据 DefaultAzureCredential 尝试多种身份验证方法。 确保至少配置了一个(Azure CLI、Visual Studio、环境变量)。