你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

迁移应用程序以将无密码连接用于 Azure 服务总线

必须使用帐户访问密钥或无密码连接对 Azure 服务总线的应用程序请求进行身份验证。 但是,应尽可能确定应用程序中无密码连接的优先级。 本教程介绍如何从传统身份验证方法迁移到更安全、无密码的连接。

与访问密钥相关的安全风险

以下代码示例演示如何使用包含访问密钥的连接字符串连接到 Azure 服务总线。 当你创建服务总线时,Azure 会自动生成这些密钥和连接字符串。 许多开发人员都倾向于使用此解决方案,因与过去使用的选项类似。 如果应用程序当前使用连接字符串,请考虑使用本文档介绍的步骤迁移到使用无密码连接。

await using ServiceBusClient client = new("<CONNECTION-STRING>");

应慎用连接字符串。 开发人员必须尽量避免在不安全的位置公开密钥。 能够访问密钥的任何人员都可以进行身份验证。 例如,如果帐户密钥意外签入源代码管理、通过不安全的电子邮件发送、粘贴到错误的聊天中,或由应不具有权限的人员查看,则存在恶意用户访问应用程序的风险。 请考虑改为将应用程序更新为使用无密码连接。

迁移到无密码连接

许多 Azure 服务通过 Microsoft Entra ID 和基于角色的访问控制 (RBAC) 支持无密码连接。 这些技术提供可靠的安全功能,可使用 Azure 标识客户端库中的 DefaultAzureCredential 实现。

重要

某些语言必须在代码中显式实现 DefaultAzureCredential,而其他语言则通过基础插件或驱动程序在内部使用 DefaultAzureCredential

DefaultAzureCredential 支持多种身份验证方法,并自动确定应在运行时使用哪种方法。 应用通过此方法能够在不同环境(本地开发与生产)中使用不同的身份验证方法,而无需实现特定于环境的代码。

DefaultAzureCredential 搜索凭据的顺序和位置可在 Azure 标识库概述中找到,并且因语言而异。 例如,在本地使用 .NET 时,DefaultAzureCredential 通常会使用开发人员用于登录 Visual Studio、Azure CLI 或 Azure PowerShell 的帐户进行身份验证。 将应用部署到 Azure 时,DefaultAzureCredential 将自动发现并使用关联托管服务(例如 Azure 应用服务)的托管标识。 此转换不需要进行任何代码更改。

注意

托管标识提供用于表示应用或服务的安全标识。 标识由 Azure 平台托管,无需设置或转交任何机密。 可以在概述文档中详细了解托管标识。

以下代码示例演示如何使用无密码连接连接到服务总线。 下一部分将更详细地介绍如何为特定服务迁移到此设置。

.NET 应用程序可以将 DefaultAzureCredential 的实例传递给服务客户端类的构造函数。 DefaultAzureCredential 将自动发现该环境中可用的凭据。

ServiceBusClient serviceBusClient = new(
    new Uri($"https://{serviceBusNamespace}.blob.core.windows.net"),
    new DefaultAzureCredential());

将应用迁移到使用无密码身份验证的步骤

以下步骤说明如何将现有应用程序迁移到使用无密码连接,而不是使用基于密钥的解决方案。 首先配置本地开发环境,然后将这些概念应用于 Azure 应用托管环境。 无论是直接使用访问密钥还是通过连接字符串,这些迁移步骤都应适用。

为本地开发身份验证配置角色和用户

在本地开发时,请确保访问服务总线的用户帐户具有正确的权限。 在此示例中,你将使用“Azure 服务总线数据所有者”角色来发送和接收数据,不过也可以使用更精细的角色。 若要为你自己分配此角色,需要具有“用户访问管理员”角色,或者具有包含 Microsoft.Authorization/roleAssignments/write 操作的其他角色。 可使用 Azure 门户、Azure CLI 或 Azure PowerShell 向用户分配 Azure RBAC 角色。 可以在范围概述页上详细了解角色分配的可用范围。

在此方案中,你将为自己的用户帐户分配权限(范围限定为特定的服务总线命名空间)以遵循最低特权原则。 这种做法仅为用户提供所需的最低权限,并创建更安全的生产环境。

以下示例将“Azure 服务总线数据所有者”角色分配到你的用户帐户,这样你就可以发送和接收数据。

重要

在大多数情况下,角色分配在 Azure 中传播需要一两分钟的时间,但极少数情况下最多可能需要 8 分钟。 如果在首次运行代码时收到身份验证错误,请稍等片刻再试。

  1. 在 Azure 门户中,使用主搜索栏或左侧导航找到你的服务总线命名空间。

  2. 在服务总线概述页上,从左侧菜单中选择“访问控制(IAM)”。

  3. 在“访问控制 (IAM)”页上,选择“角色分配”选项卡。

  4. 从顶部菜单中选择“+ 添加”,然后从出现的下拉菜单中选择“添加角色分配”。

    A screenshot showing how to assign a role.

  5. 使用搜索框将结果筛选为所需角色。 对于此示例,请搜索“Azure 服务总线数据所有者”,选择匹配的结果,然后选择“下一步”。

  6. 在“访问权限分配对象”下,选择“用户、组或服务主体”,然后选择“+ 选择成员”。

  7. 在对话框中,搜索 Microsoft Entra ID 用户名(通常是 user@domain 电子邮件地址),然后选中对话框底部的“选择”。

  8. 选择“查看 + 分配”转到最后一页,然后再次选择“查看 + 分配”完成该过程。

登录并迁移应用代码以使用无密码连接

对于本地开发,请确保使用角色所分配到的 Microsoft Entra 帐户(范围限定为服务总线命名空间)进行身份验证。 可通过 Azure CLI、Visual Studio、Azure PowerShell 或其他工具(如 IntelliJ)进行身份验证。

对于本地开发,请确保使用分配了该角色的同一 Microsoft Entra 帐户进行身份验证。 可以通过常用的开发工具(如 Azure CLI 或 Azure PowerShell)进行身份验证。 可用于进行身份验证的开发工具因语言而异。

使用以下命令通过 Azure CLI 登录到 Azure:

az login

接下来,更新代码以使用无密码连接。

  1. 若要在 .NET 应用程序中使用 DefaultAzureCredential,请安装 Azure.Identity 包:

    dotnet add package Azure.Identity
    
  2. 在文件的顶部,添加以下代码:

    using Azure.Identity;
    
  3. 识别创建连接到 Azure 服务总线的 ServiceBusClient 对象的代码。 更新代码,使之与以下示例一致:

     var serviceBusNamespace = $"https://{namespace}.servicebus.windows.net";
     ServiceBusClient client = new(
         serviceBusNamespace,
         new DefaultAzureCredential());
    

在本地运行应用

进行这些代码更改后,在本地运行应用程序。 新配置应选取本地凭据,例如 Azure CLI、Visual Studio 或 IntelliJ。 分配给 Azure 中本地开发用户的角色将允许应用在本地连接到 Azure 服务。

配置 Azure 托管环境

将应用程序配置为使用无密码连接并在本地运行后,相同的代码可以在应用程序部署到 Azure 后向 Azure 服务进行身份验证。 例如,部署到启用了托管标识的 Azure 应用服务实例的应用程序可以连接到 Azure 服务总线。

使用 Azure 门户创建托管标识

以下步骤演示如何为各种 Web 托管服务创建系统分配的托管标识。 托管标识可以使用之前设置的应用配置安全地连接到其他 Azure 服务。

某些应用托管环境支持服务连接器,这有助于将 Azure 计算服务连接到其他支持服务。 服务连接器会自动配置网络设置和连接信息。 可以在概述页上详细了解服务连接器以及支持哪些方案。

目前支持以下计算服务:

  • Azure 应用服务
  • Azure Spring Cloud
  • Azure 容器应用(预览版)

在本迁移指南中,你将使用应用服务,但步骤与 Azure Spring Apps 和 Azure 容器应用的类似。

注意

Azure Spring Apps 目前仅支持使用连接字符串的服务连接器。

  1. 在应用服务的主概述页上,从左侧导航中选择“服务连接器”。

  2. 在顶部菜单中选择“+ 创建”,这将打开“创建连接”面板。 输入以下值:

    • 服务类型:选择“服务总线”。
    • 订阅:选择要使用的订阅。
    • 连接名称:为连接输入一个名称,例如“connector_appservice_servicebu”。
    • 客户端类型:保持选中默认值,或选择要使用的特定客户端。

    选择“下一步: 身份验证”。

  3. 确保已选中“系统分配的托管标识(推荐)”,然后选择“下一步: 网络”。

  4. 保持选中默认值,然后选择“下一步: 查看 + 创建”。

  5. 在 Azure 验证你的设置后,请选择“创建”。

服务连接器将自动为应用服务创建系统分配的托管标识。 连接器还会为托管标识分配所选服务总线的“Azure 服务总线数据所有者”角色。

另外,你还可以使用 Azure CLI 在 Azure 托管环境中启用托管标识。

可以使用 Azure CLI 通过服务连接器在 Azure 计算托管环境和目标服务之间创建连接。 CLI 会自动处理创建托管标识并分配适当的角色,如门户说明中所述。

如果使用的是 Azure 应用服务,请使用 az webapp connection 命令:

az webapp connection create servicebus \
    --resource-group <resource-group-name> \
    --name <webapp-name> \
    --target-resource-group <target-resource-group-name> \
    --namespace <target-service-bus-namespace> \
    --system-identity

如果使用的是 Azure Spring Apps,请使用 az spring connection 命令:

az spring connection create servicebus \
    --resource-group <resource-group-name> \
    --service <service-instance-name> \
    --app <app-name> \
    --deployment <deployment-name> \
    --target-resource-group <target-resource-group> \
    --namespace <target-service-bus-namespace> \
    --system-identity

如果使用的是 Azure 容器应用,请使用 az containerapp connection 命令:

az containerapp connection create servicebus \
    --resource-group <resource-group-name> \
    --name <webapp-name> \
    --target-resource-group <target-resource-group-name> \
    --namespace <target-service-bus-namespace> \
    --system-identity

为托管标识分配角色

接下来,需要向创建的托管标识授予访问服务总线的权限。 可通过将角色分配给托管标识来执行此操作,就像对本地开发用户的操作一样。

如果使用服务连接器连接服务,则无需完成此步骤。 已为你完成必要的配置:

  • 如果在创建连接时选择了托管标识,则会为应用创建系统分配的托管标识,并为该标识分配服务总线上的“Azure 服务总线数据所有者”角色。

  • 如果选择了连接字符串,则连接字符串已添加为应用环境变量。

测试应用程序

进行这些代码更改后,在浏览器中浏览到托管应用程序。 应用应该可以成功连接到服务总线。 请记住,角色分配通过 Azure 环境传播最长可能需要五分钟的时间。 应用程序现在配置为在本地和生产环境中运行,开发人员无需管理应用程序本身的机密。

后续步骤

本教程介绍了如何将应用程序迁移到无密码连接。