使用 Microsoft Entra ID 对托管标识进行身份验证以访问 Azure 服务总线资源

Azure 资源的托管标识在 Microsoft Entra ID 中为 Azure 服务提供了一个自动托管标识。 可以使用此标识向支持 Microsoft Entra 身份验证的任何服务(例如 Azure 服务总线)进行身份验证,而无需在代码中放入任何凭据。 如果不熟悉托管标识,请参阅 Azure 资源的托管标识,然后再继续阅读本文。

下面是使用托管标识访问服务总线实体的大致步骤:

  1. 为客户端应用或环境启用托管标识。 例如,为 Azure 应用服务应用、Azure Functions 应用或在其中运行应用的虚拟机启用托管标识。 下面的文章可帮助你完成此步骤:

  2. 将 Azure 服务总线数据所有者、Azure 服务总线数据发送方或 Azure 服务总线数据接收方角色分配给相应范围(Azure 订阅、资源组、服务总线命名空间或服务总线队列/主题)的托管标识。 有关向托管标识分配角色的说明,请参阅使用 Azure 门户分配 Azure 角色

  3. 在应用程序中,使用托管标识和服务总线命名空间的终结点连接到命名空间。

    例如,在 .NET 中,使用采用 TokenCredentialfullyQualifiedNamespace(字符串,例如:cotosons.servicebus.chinacloudapi.cn)参数的 ServiceBusClient 构造函数通过托管标识连接到服务总线。 需要传入 DefaultAzureCredential,其派生自 TokenCredential 并使用托管标识。 在 DefaultAzureCredentialOptions 中,将 ManagedIdentityClientId 设置为客户端托管标识的 ID。

    string fullyQualifiedNamespace = "<your namespace>.servicebus.chinacloudapi.cn>";
    string userAssignedClientId = "<your managed identity client ID>";
    
    var credential = new DefaultAzureCredential(
        new DefaultAzureCredentialOptions
        {
            ManagedIdentityClientId = userAssignedClientId
        });
    
    var sbusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);
    

    重要

    可以为服务总线命名空间禁用本地或 SAS 密钥身份验证,仅允许 Microsoft Entra 身份验证。 有关分步说明,请参阅禁用本地身份验证

适用于 Azure 服务总线的 Azure 内置角色

Microsoft Entra 通过 Azure 基于角色的访问控制 (RBAC) 授予对受保护资源的访问权限。 Azure 服务总线定义了一组 Azure 内置角色,它们包含用于访问服务总线实体的通用权限集。 还可以定义自定义角色来访问这些数据。

Azure 提供了以下 Azure 内置角色,用于授予对服务总线命名空间的访问权限:

若要将角色分配给 Azure 门户中的托管标识,请使用“访问控制 (IAM)”页。 通过在“服务总线命名空间”页、“服务总线队列”页或“服务总线主题”页上选择“访问控制 (IAM)”导航到此页。 有关分配角色的分步说明,请参阅使用 Azure 门户分配 Azure 角色

资源范围

在将 Azure 角色分配给托管标识之前,请确定托管标识应具有的访问范围。 最佳做法指出,最好是授予尽可能小的范围。

以下列表描述了可将服务总线资源访问权限限定到哪些级别,从最小的范围开始:

  • 队列主题订阅:角色分配适用于特定的服务总线实体。

  • 服务总线命名空间:角色分配跨越命名空间下服务总线的整个拓扑。

  • 资源组:角色分配适用于资源组下的所有服务总线资源。

  • 订阅:角色分配适用于订阅的所有资源组中的所有服务总线资源。

    注意

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

目前,Azure 门户不支持在订阅级别为服务总线 Azure 角色分配用户、组或托管标识。 下面是使用 Azure CLI 命令 az-role-assignment-create 为服务总线 Azure 角色分配标识的示例:

az role assignment create \
    --role $service_bus_role \
    --assignee $assignee_id \
    --scope /subscriptions/$subscription_id/resourceGroups/$resource_group/providers/Microsoft.ServiceBus/namespaces/$service_bus_namespace/topics/$service_bus_topic/subscriptions/$service_bus_subscription

有关如何定义内置角色的详细信息,请参阅了解角色定义。 若要了解如何创建 Azure 自定义角色,请参阅 Azure 自定义角色

使用 SDK

在 .NET 中,ServiceBusClient 对象通过使用采用完全限定命名空间和 TokenCredential 的构造函数进行初始化。 DefaultAzureCredential 派生自 TokenCredential,因而会自动使用为应用配置的托管标识。 从托管标识上下文到服务总线的流以及授权握手都是由令牌凭据自动处理。 这是比使用 SAS 更简单的模型。

var client = new ServiceBusClient('cotosons.servicebus.chinacloudapi.cn', new DefaultAzureCredential());

可以像往常一样使用 ServiceBusSenderServiceBusReceiverServiceBusProcessor 发送和接收消息。

有关使用托管标识发送和接收消息的完整分步说明,请参阅以下快速入门。 这些快速入门包含使用服务主体发送和接收消息的代码,但该代码与使用托管标识时的代码相同。

注意

托管标识仅适用于 Azure 环境、应用服务、Azure VM 和规模集。 对于 .NET 应用程序,Microsoft.Azure.Services.AppAuthentication 库(由服务总线 NuGet 包使用)提供此协议的摘要并支持本地开发体验。 此库还允许通过 Visual Studio、Azure CLI 2.0 或 Active Directory 集成身份验证使用用户帐户,在开发计算机上对代码进行本地测试。 有关此库的本地开发选项的详细信息,请参阅使用 .NET 向 Azure Key Vault 进行服务到服务身份验证

后续步骤

请参阅 GitHub 上的 .NET Web 应用程序示例,该示例使用托管标识连接到服务总线来发送和接收消息。 将应用服务的标识添加到“Azure 服务总线数据所有者”角色。