对 Azure 认知服务的请求进行身份验证

对 Azure 认知服务的每个请求都必须包含身份验证标头。 此标头传递订阅密钥或身份验证令牌,用于验证服务或服务组订阅。 本文介绍三种对请求进行身份验证的方法以及每种方法的要求。

先决条件

在发出请求之前,需要具有 Azure 帐户和 Azure 认知服务订阅。 如果已有帐户,请继续并跳到下一节。 如果还没有帐户,我们会提供指南,可在几分钟内完成设置:创建 Azure 认知服务帐户

创建帐户后,可以从 Azure 门户获取订阅密钥。

身份验证标头

让我们快速查看可用于 Azure 认知服务的身份验证标头。

标头 说明
Ocp-Apim-Subscription-Key 使用此标头通过特定服务订阅密钥或多服务订阅密钥进行身份验证。
Ocp-Apim-Subscription-Region 只有在使用具有 Translator 服务的多服务订阅密钥时才需要此标头。 使用此标头指定订阅区域。
授权 如果使用的是访问令牌,则使用此标头。 以下各节详细介绍了执行令牌交换的步骤。 提供的值遵循以下格式:Bearer <TOKEN>

使用单服务订阅密钥进行身份验证

第一个选项是使用特定服务(如 Translator)的订阅密钥对请求进行身份验证。 Azure 门户中的密钥可用于已创建的每个资源。 要使用订阅密钥对请求进行身份验证,必须将其作为 Ocp-Apim-Subscription-Key 标头传递。

这些示例请求演示了如何使用 Ocp-Apim-Subscription-Key 标头。 请记住,使用此示例时,需要包括有效的订阅密钥。

这是对 Translator 服务的示例调用:

curl -X POST 'https://api.translator.azure.cn/translate?api-version=3.0&from=en&to=de' \
-H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
-H 'Content-Type: application/json' \
--data-raw '[{ "text": "How much for the cup of coffee?" }]' | json_pp

以下视频演示如何使用认知服务密钥。

使用多服务订阅密钥进行身份验证

警告

目前,多服务密钥不支持异常检测器。

此选项仍使用订阅密钥对请求进行身份验证。 主要区别在于订阅密钥未绑定到特定服务,而单个密钥可用于对多个认知服务的请求进行身份验证。 有关区域可用性、支持的功能和定价的信息,请参阅认知服务定价

订阅密钥在每个请求中作为 Ocp-Apim-Subscription-Key 标头提供。

支持的区域

使用多服务订阅密钥向 api.cognitive.azure.cn 发出请求时,必须在 URL 中包含该区域。 例如:chinaeast2.api.cognitive.azure.cn

将多服务订阅密钥与 Translator 服务配合使用时,必须使用 Ocp-Apim-Subscription-Region 标头指定订阅区域。

以下区域支持多服务身份验证:

  • chinaeast2
  • chinanorth2

示例请求

这是对 Translator 服务的示例调用:

curl -X POST 'https://api.translator.azure.cn/translate?api-version=3.0&from=en&to=de' \
-H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
-H 'Ocp-Apim-Subscription-Region: YOUR_SUBSCRIPTION_REGION' \
-H 'Content-Type: application/json' \
--data-raw '[{ "text": "How much for the cup of coffee?" }]' | json_pp

使用访问令牌进行身份验证

某些 Azure 认知服务接受并在某些情况下需要访问令牌。 目前,以下服务支持访问令牌:

  • 文本翻译 API
  • 语音服务:语音转文本 API
  • 语音服务:文本转语音 API

警告

支持访问令牌的服务可能会随时间而变化,请在使用此身份验证方法之前检查服务的 API 参考。

单服务订阅密钥和多服务订阅密钥均可用于交换认证令牌。 身份验证令牌有效期为 10 分钟。 它们以 JSON Web 令牌 (JWT) 格式存储,可供使用 JWT 库以编程方式查询。

访问令牌作为 Authorization 标头包含在请求中。 提供的令牌值必须以 Bearer 开头,例如:Bearer YOUR_AUTH_TOKEN

示例请求

使用以下 URL 将订阅密钥交换为访问令牌:https://YOUR-REGION.api.cognitive.azure.cn/sts/v1.0/issueToken

curl -v -X POST \
"https://YOUR-REGION.api.cognitive.azure.cn/sts/v1.0/issueToken" \
-H "Content-type: application/x-www-form-urlencoded" \
-H "Content-length: 0" \
-H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY"

以下多服务区域支持令牌交换:

  • chinaeast2
  • chinanorth2

获得访问令牌后,需要在每个请求中将其作为 Authorization 标头传递。 这是对 Translator 服务的示例调用:

curl -X POST 'https://api.translator.azure.cn/translate?api-version=3.0&from=en&to=de' \
-H 'Authorization: Bearer YOUR_AUTH_TOKEN' \
-H 'Content-Type: application/json' \
--data-raw '[{ "text": "How much for the cup of coffee?" }]' | json_pp

向 Azure Active Directory 进行身份验证

重要

AAD 身份验证必须始终与 Azure 资源的自定义子域名一起使用。 区域终结点不支持 AAD 身份验证。

在前面的部分中,我们演示了如何使用单一服务或多服务订阅密钥完成 Azure 认知服务的身份验证。 虽然这些密钥提供了一种快速简便的途径快速开始开发,但还不足以支持需要 Azure 基于角色的访问控制 (Azure RBAC) 的更复杂的方案。 让我们来看看使用 Azure Active Directory (AAD) 进行身份验证所需的条件。

在以下部分中,你将使用 Azure CLI 创建子域、分配角色并获取持有者令牌来调用 Azure 认知服务。 如果遇到问题,每个部分都提供了可供参考和使用的链接以及 Azure CLI 中每个命令的所有可用选项。

使用自定义子域创建资源

第一步是创建自定义子域。 如果要使用没有自定义子域名的现有认知服务资源,请按照认知服务自定义子域中的说明为资源启用自定义子域。

  1. 首先打开 Azure CLI。 然后选择一个订阅

    Set-AzContext -SubscriptionName <SubscriptionName>
    
  2. 接下来,使用自定义子域创建认知服务资源。 子域名需为全局唯一,不能包括特殊字符,例如:“.”、“!”、“,”。

    $account = New-AzCognitiveServicesAccount -ResourceGroupName <RESOURCE_GROUP_NAME> -name <ACCOUNT_NAME> -Type <ACCOUNT_TYPE> -SkuName <SUBSCRIPTION_TYPE> -Location <REGION> -CustomSubdomainName <UNIQUE_SUBDOMAIN>
    
  3. 如果成功,Endpoint 应会显示资源独有的子域名

向服务主体分配角色

现在,已有了与资源关联的自定义子域,接着需要将角色分配给服务主体。

注意

请记住,Azure 角色分配可能需要最多五分钟的时间进行传播。

  1. 首先,注册一个 AAD 应用程序

    $SecureStringPassword = ConvertTo-SecureString -String <YOUR_PASSWORD> -AsPlainText -Force
    
    $app = New-AzADApplication -DisplayName <APP_DISPLAY_NAME> -IdentifierUris <APP_URIS> -Password $SecureStringPassword
    

    在下一步中,需要 ApplicationId

  2. 接下来,需要为 AAD 应用程序创建服务主体

    New-AzADServicePrincipal -ApplicationId <APPLICATION_ID>
    

    备注

    如果在 Azure 门户中注册应用程序,将自动为你完成此步骤。

  3. 最后一步是向服务主体分配“认知服务用户”角色(范围限定为资源)。 通过分配角色,将向服务主体授予对此资源的访问权限。 可以向服务主体授予对订阅中多个资源的访问权限。

    备注

    此过程使用服务主体的 ObjectId,而不是应用程序的 ObjectId。 ACCOUNT_ID 是所创建的认知服务帐户的 Azure 资源 ID。 可以从 Azure 门户中资源的“属性”中找到 Azure 资源 ID。

    New-AzRoleAssignment -ObjectId <SERVICE_PRINCIPAL_OBJECTID> -Scope <ACCOUNT_ID> -RoleDefinitionName "Cognitive Services User"
    

示例请求

在此示例中,使用密码对服务主体进行身份验证。 然后,使用提供的令牌调用计算机视觉 API。

  1. 获取 TenantId

    $context=Get-AzContext
    $context.Tenant.Id
    
  2. 获取令牌:

    $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList "https://login.partner.microsoftonline.cn/<TENANT_ID>"
    $secureSecretObject = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.SecureClientSecret" -ArgumentList $SecureStringPassword
    $clientCredential = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential" -ArgumentList $app.ApplicationId, $secureSecretObject
    $token=$authContext.AcquireTokenAsync("https://cognitiveservices.azure.cn/", $clientCredential).Result
    $token
    
  3. 调用计算机视觉 API:

    $url = $account.Endpoint+"vision/v1.0/models"
    $result = Invoke-RestMethod -Uri $url  -Method Get -Headers @{"Authorization"=$token.CreateAuthorizationHeader()} -Verbose
    $result | ConvertTo-Json
    

或者,可以使用证书对服务主体进行身份验证。 除了服务主体之外,还通过使用另一个 AAD 应用程序来委派权限的方式提供用户主体支持。 在这种情况下,获取令牌时,将提示用户进行双重身份验证,而不是提供密码或证书。

授权访问托管标识

认知服务支持使用 Azure 资源的托管标识进行 Azure Active Directory (Azure AD) 身份验证。 Azure 资源的托管标识可以从 Azure 虚拟机 (VM)、函数应用、虚拟机规模集和其他服务中运行的应用程序使用 Azure AD 凭据授权对认知服务资源的访问权限。 将 Azure 资源的托管标识与 Azure AD 身份验证结合使用,可避免将凭据随在云中运行的应用程序一起存储。

在 VM 上启用托管标识

在使用 Azure 资源的托管标识对 VM 中的认知服务资源授予访问权限之前,必须在 VM 上启用 Azure 资源的托管标识。 若要了解如何为 Azure 资源启用托管标识,请参阅:

有关托管标识的详细信息,请参阅 Azure 资源的托管标识

使用 Azure 密钥保管库安全地访问凭据

可以使用 Azure Key Vault 安全地开发认知服务应用程序。 Key Vault 使你能够将身份验证凭据存储在云中,并且降低了机密意外泄漏的可能性,因为你不会在应用程序中存储安全信息。

身份验证通过 Azure Active Directory 来完成。 授权可以通过 Azure 基于角色的访问控制 (Azure RBAC) 或 Key Vault 访问策略来完成。 Azure RBAC 可用于管理保管库和访问存储在该保管库中的数据,而密钥保管库访问策略仅能在尝试访问存储在保管库中的数据时使用。

另请参阅