你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
迁移应用程序以将无密码连接用于 Azure 事件中心
必须使用帐户访问密钥或无密码连接等配置对 Azure 服务的应用程序请求进行身份验证。 但是,应尽可能确定应用程序中无密码连接的优先级。 使用密码或密钥的传统身份验证方法会产生安全风险和复杂性。 访问 Azure 服务中心的无密码连接,详细了解迁移到无密码连接的优势。
以下教程介绍了如何使用无密码连接迁移现有应用程序以进行连接。 无论是使用访问密钥、连接字符串还是其他基于机密的方法,都适用这些相同的迁移步骤。
无密码连接可以配置为同时用于本地和 Azure 托管的环境。 在本部分中,你将应用配置以允许单个用户向 Azure 事件中心进行身份验证,以便进行本地开发。
分配用户角色
在本地开发时,请确保访问 Azure 事件中心的用户帐户具有正确的权限。 需要“Azure 事件中心数据接收方”角色和“Azure 事件中心数据发送方”角色才能读取和写入消息数据。 若要为你自己分配此角色,需要具有“用户访问管理员”角色,或者具有包含 Microsoft.Authorization/roleAssignments/write 操作的其他角色。 可使用 Azure 门户、Azure CLI 或 Azure PowerShell 向用户分配 Azure RBAC 角色。 可在范围概述页上详细了解角色分配的可用范围。
以下示例将“Azure 事件中心数据发送方”角色和“Azure 事件中心数据接收方”角色分配给用户帐户。 这些角色授予对事件中心消息的读取和写入访问权限。
在 Azure 门户中,使用主搜索栏或左侧导航找到你的事件中心。
在事件中心概述页上,从左侧菜单中选择“访问控制(IAM)”。
在“访问控制 (IAM)”页上,选择“角色分配”选项卡。
从顶部菜单中选择“+ 添加”,然后从出现的下拉菜单中选择“添加角色分配”。
使用搜索框将结果筛选为所需角色。 对于此示例,请搜索“Azure 事件中心数据发送方”,选择匹配的结果,然后选择“下一步”。
在“访问权限分配对象”下,选择“用户、组或服务主体”,然后选择“+ 选择成员”。
在对话框中,搜索 Microsoft Entra ID 用户名(通常是 user@domain 电子邮件地址),然后选中对话框底部的“选择”。
选择“查看 + 分配”转到最后一页,然后再次选择“查看 + 分配”完成该过程。
对“Azure 事件中心数据接收方”角色重复这些步骤,以允许帐户发送和接收消息。
若要使用 Azure CLI 在资源级别分配角色,首先必须使用 az eventhubs eventhub show
命令检索资源 ID。 可以使用 --query
参数筛选输出属性。
az eventhubs eventhub show \
--resource-group '<your-resource-group-name>' \
--namespace-name '<your-event-hubs-namespace>' \
--name '<your-event-hub-name>' \
--query id
复制上述命令的输出 Id
。 然后,可以使用 Azure CLI 的 az role 命令分配角色。
az role assignment create --assignee "<user@domain>" \
--role "Azure Event Hubs Data Receiver" \
--scope "<your-resource-id>"
az role assignment create --assignee "<user@domain>" \
--role "Azure Event Hubs Data Sender" \
--scope "<your-resource-id>"
若要使用 Azure PowerShell 在资源级别分配角色,首先必须使用 Get-AzResource
命令检索资源 ID。
Get-AzResource -ResourceGroupName "<yourResourceGroupname>" -Name "<yourEventHubsNamespace>"
复制上述命令输出中的 Id
值。 然后,可以使用 PowerShell 中的 New-AzRoleAssignment 命令分配角色。
New-AzRoleAssignment -SignInName <user@domain> `
-RoleDefinitionName "Azure Event Hubs Data Receiver" `
-Scope <yourEventHubsId>
New-AzRoleAssignment -SignInName <user@domain> `
-RoleDefinitionName "Azure Event Hubs Data Sender" `
-Scope <yourEventHubsId>
重要
在大多数情况下,角色分配在 Azure 中传播需要一两分钟,但在极少数情况下,可能最多需要 8 分钟。 如果在首次运行代码时收到身份验证错误,请稍等片刻再试。
在本地登录到 Azure
对于本地开发,请确保使用分配了该角色的同一 Microsoft Entra 帐户进行身份验证。 可以通过常用的开发工具(如 Azure CLI 或 Azure PowerShell)进行身份验证。 可用于进行身份验证的开发工具因语言而异。
使用以下命令通过 Azure CLI 登录到 Azure:
az login
选择 Visual Studio 右上角的“登录”按钮。
使用你之前为其分配角色的 Microsoft Entra 帐户登录。
需要安装 Azure CLI 才能通过 Visual Studio Code 使用 DefaultAzureCredential
。
在 Visual Studio Code 的主菜单上,导航到“终端”>“新建终端”。
使用以下命令通过 Azure CLI 登录到 Azure:
az login
通过以下命令使用 PowerShell 登录到 Azure:
Connect-AzAccount
更新应用程序代码以使用无密码连接
对于以下每个生态系统,Azure 标识客户端库都提供了一个 DefaultAzureCredential
类,可处理对 Azure 的无密码身份验证:
DefaultAzureCredential
支持多种身份验证方法。 要使用的方法将在运行时确定。 通过这种方法,你的应用可在不同环境(本地与生产)中使用不同的身份验证方法,而无需实现特定于环境的代码。 有关 DefaultAzureCredential
查找凭据的顺序和位置,请参阅上述链接。
若要在 .NET 应用程序中使用 DefaultAzureCredential
,请安装 Azure.Identity
包:
dotnet add package Azure.Identity
在文件的顶部,添加以下代码:
using Azure.Identity;
确定代码中创建 EventHubProducerClient
或 EventProcessorClient
对象以连接到 Azure 事件中心的位置。 更新代码,使之与以下示例一致:
DefaultAzureCredential credential = new();
var eventHubNamespace = $"https://{namespace}.servicebus.windows.net";
// Event Hubs producer
EventHubProducerClient producerClient = new(
eventHubNamespace,
eventHubName,
credential);
// Event Hubs processor
EventProcessorClient processorClient = new(
storageClient,
EventHubConsumerClient.DefaultConsumerGroupName,
eventHubNamespace,
eventHubName,
credential);
若要在 Go 应用程序中使用 DefaultAzureCredential
,请安装 azidentity
模块:
go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
在文件的顶部,添加以下代码:
import (
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
)
确定代码中创建 ProducerClient
或 ConsumerClient
实例以连接到 Azure 事件中心的位置。 更新代码,使之与以下示例一致:
credential, err := azidentity.NewDefaultAzureCredential(nil)
eventHubNamespace := fmt.Sprintf(
"https://%s.servicebus.windows.net",
namespace)
if err != nil {
// handle error
}
// Event Hubs producer
producerClient, err = azeventhubs.NewProducerClient(
eventHubNamespace,
eventHubName,
credential,
nil)
if err != nil {
// handle error
}
// Event Hubs processor
processorClient, err = azeventhubs.NewConsumerClient(
eventHubNamespace,
eventHubName,
azeventhubs.DefaultConsumerGroup,
credential,
nil)
if err != nil {
// handle error
}
若要在 Java 应用程序中使用 DefaultAzureCredential
,请通过以下方法之一安装 azure-identity
包:
- 包括 BOM 文件。
- 包括直接依赖项。
在文件的顶部,添加以下代码:
import com.azure.identity.DefaultAzureCredentialBuilder;
确定代码中创建 EventHubProducerClient
或 EventProcessorClient
对象以连接到 Azure 事件中心的位置。 更新代码,使之与以下示例一致:
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.build();
String eventHubNamespace = "https://" + namespace + ".servicebus.windows.net";
// Event Hubs producer
EventHubProducerClient producerClient = new EventHubClientBuilder()
.credential(eventHubNamespace, eventHubName, credential)
.buildProducerClient();
// Event Hubs processor
EventProcessorClient processorClient = new EventProcessorClientBuilder()
.consumerGroup(consumerGroupName)
.credential(eventHubNamespace, eventHubName, credential)
.checkpointStore(new SampleCheckpointStore())
.processEvent(eventContext -> {
System.out.println(
"Partition ID = " +
eventContext.getPartitionContext().getPartitionId() +
" and sequence number of event = " +
eventContext.getEventData().getSequenceNumber());
})
.processError(errorContext -> {
System.out.println(
"Error occurred while processing events " +
errorContext.getThrowable().getMessage());
})
.buildEventProcessorClient();
若要在 Node.js 应用程序中使用 DefaultAzureCredential
,请安装 @azure/identity
包:
npm install --save @azure/identity
在文件的顶部,添加以下代码:
import { DefaultAzureCredential } from "@azure/identity";
确定代码中创建 EventHubProducerClient
或 EventHubConsumerClient
对象以连接到 Azure 事件中心的位置。 更新代码,使之与以下示例一致:
const credential = new DefaultAzureCredential();
const eventHubNamespace = `https://${namespace}.servicebus.windows.net`;
// Event Hubs producer
const producerClient = new EventHubProducerClient(
eventHubNamespace,
eventHubName,
credential);
// Event Hubs processor
const processorClient = new EventHubConsumerClient(
consumerGroupName,
eventHubNamespace,
eventHubName,
credential
);
若要在 Python 应用程序中使用 DefaultAzureCredential
,请安装 azure-identity
包:
pip install azure-identity
在文件的顶部,添加以下代码:
from azure.identity import DefaultAzureCredential
确定代码中创建 EventHubProducerClient
或 EventHubConsumerClient
对象以连接到 Azure 事件中心的位置。 更新代码,使之与以下示例一致:
credential = DefaultAzureCredential()
event_hub_namespace = "https://%s.servicebus.windows.net" % namespace
# Event Hubs producer
producer_client = EventHubProducerClient(
fully_qualified_namespace = event_hub_namespace,
eventhub_name = event_hub_name,
credential = credential
)
# Event Hubs processor
processor_client = EventHubConsumerClient(
fully_qualified_namespace = event_hub_namespace,
eventhub_name = event_hub_name,
consumer_group = "$Default",
checkpoint_store = checkpoint_store,
credential = credential
)
确保在 EventHubProducerClient
或 EventProcessorClient
对象的 URI 中更新事件中心命名空间。 可以在 Azure 门户的概述页上找到该命名空间名称。
在本地运行应用
进行这些代码更改后,在本地运行应用程序。 新配置应选取本地凭据,例如 Azure CLI、Visual Studio 或 IntelliJ。 你在 Azure 中分配给用户的角色将会允许应用在本地连接到 Azure 服务。
将应用程序配置为使用无密码连接并在本地运行后,相同的代码可以在应用程序部署到 Azure 后向 Azure 服务进行身份验证。 以下各部分介绍了如何配置已部署的应用程序,以使用托管标识连接到 Azure 事件中心。 托管标识在 Microsoft Entra ID 中提供了一个自动托管标识,供应用程序在连接到支持 Microsoft Entra 身份验证的资源时使用。 详细了解托管标识:
创建托管标识
你可以使用 Azure 门户或 Azure CLI 创建用户分配的托管标识。 应用程序将使用该标识向其他服务进行身份验证。
- 在 Azure 门户顶部搜索“托管标识”。 选择“托管标识”结果。
- 选择“托管标识”概述页面顶部的“+ 创建”。
- 在“基本信息”选项卡中,输入以下值:
- “订阅”:选择所需的订阅。
- “资源组”:选择所需的资源组。
- 区域:选择你所在位置附近的区域。
- “名称”:输入标识的可识别名称,例如“MigrationIdentity”。
- 在页面底部选择“查看 + 创建”。
- 验证检查完成后,选择“创建”。 Azure 将创建新的用户分配的标识。
创建资源后,选择“转到资源”以查看托管标识的详细信息。
使用 az identity create 命令创建用户分配的托管标识:
az identity create --name MigrationIdentity --resource-group <your-resource-group>
将托管标识与 Web 应用相关联
你需要将 Web 应用配置为使用自己创建的托管标识。 使用 Azure 门户或 Azure CLI 将标识分配给应用。
在 Azure 门户中完成以下步骤,从而将标识与应用相关联。 这些步骤同样也适用于以下 Azure 服务:
- Azure Spring Apps
- Azure Container Apps
- Azure 虚拟机
- Azure Kubernetes 服务
导航到 Web 应用的概述页面。
从左侧导航菜单中,选择“标识”。
在“标识”页面上,切换到“用户分配的”选项卡。
选择“+ 添加”,打开“添加用户分配的托管标识”浮出控件。
选择之前用于创建标识的订阅。
按名称搜索“MigrationIdentity”,并从搜索结果中选择该标识。
选择“添加”,以将该标识与应用相关联。
使用以下 Azure CLI 命令将标识与应用相关联:
使用 az identity show 命令检索创建的托管标识的 ID。 复制输出值以在下一步中使用。
az identity show --name MigrationIdentity -g <your-identity-resource-group-name> --query id
可以使用 az webapp identity assign 命令将托管标识分配给 Azure 应用服务实例。
az webapp identity assign \
--resource-group <resource-group-name> \
--name <webapp-name>
--identities <managed-identity-id>
可以使用 az spring app identity assign 命令将托管标识分配给 Azure Spring Apps 实例。
az spring app identity assign \
--resource-group <resource-group-name> \
--name <app-name> \
--service <service-name>
--user-assigned <managed-identity-id>
你可以使用 az vm identity assign 命令将托管标识分配给虚拟机。
az containerapp identity assign \
--resource-group <resource-group-name> \
--name <app-name>
--user-assigned <managed-identity-id>
可以使用 az vm identity assign 命令将托管标识分配给虚拟机。
az vm identity assign \
--resource-group <resource-group-name> \
--name <virtual-machine-name>
--identities <managed-identity-id>
可以使用 az aks update 命令将托管标识分配给 Azure Kubernetes 服务 (AKS) 实例。
az aks update \
--resource-group <resource-group-name> \
--name <cluster-name> \
--enable-managed-identity \
--assign-identity <managed-identity-id> \
--assign-kubelet-identity <managed-identity-id>
可以使用 Azure CLI 通过服务连接器在 Azure 计算托管环境和目标服务之间创建连接。 该服务连接器 CLI 命令会自动将适当的角色分配给标识。 可以在概述页上详细了解服务连接器以及支持哪些方案。
使用 az identity show
命令检索创建的托管标识的客户端 ID。 复制该值供以后使用。
az identity show \
--name MigrationIdentity \
--resource-group <your-resource-group> \
--query clientId
使用相应的 CLI 命令建立服务连接:
如果使用的是某个 Azure 应用程序服务,请使用 az webapp connection 命令:
az webapp connection create eventhub \
--resource-group <resource-group-name> \
--name <webapp-name> \
--target-resource-group <target-resource-group-name> \
--account <target-event-hub-namespace> \
--user-identity "client-id=<your-identity-client-id>" "subs-id=<your-subscription-id>"
如果使用的是 Azure Spring Apps,请使用 az spring connection 命令:
az spring connection create eventhub \
--resource-group <resource-group-name> \
--service <service-instance-name> \
--app <app-name> \
--deployment <deployment-name> \
--target-resource-group <target-resource-group> \
--account <target-event-hub-namespace> \
--user-identity "client-id=<your-identity-client-id>" "subs-id=<your-subscription-id>"
如果使用的是 Azure 容器应用,请使用 az containerapp connection 命令:
az containerapp connection create eventhub \
--resource-group <resource-group-name> \
--name <containerapp-name> \
--target-resource-group <target-resource-group> \
--account <target-event-hub-namespace> \
--user-identity "client-id=<your-identity-client-id>" "subs-id=<your-subscription-id>"
为托管标识分配角色
接下来,需要向创建的托管标识授予访问事件中心的权限。 通过为托管标识分配角色来授予权限,就像对本地开发用户的操作一样。
导航到事件中心概述页,并在左侧导航栏中选择“访问控制(IAM)”。
选择“添加角色分配”
在“角色”搜索框中,搜索“Azure 事件中心数据发送方”,这是用于管理队列数据操作的常用角色。 可以分配适合你的用例的任何角色。 从列表中选择“Azure 事件中心数据发送方”,然后选择“下一步”。
在“添加角色分配”屏幕上,针对“将访问权限分配给”选项,请选择“托管标识”。 然后选择“+选择成员”。
在浮出控件中,按名称搜索创建的托管标识,并从结果中选择该标识。 选择“选择”以关闭浮出控件菜单。
多次选择“下一步”,直到可以选择“查看 + 分配”,从而完成角色分配。
对“Azure 事件中心数据接收方”角色重复这些步骤。
若要使用 Azure CLI 在资源级别分配角色,必须首先使用 az eventhubs eventhub show
show 命令检索资源 ID。 可以使用 --query
参数筛选输出属性。
az eventhubs eventhub show \
--resource-group '<your-resource-group-name>' \
--namespace-name '<your-event-hubs-namespace>' \
--name '<your-event-hub-name>' \
--query id
复制上述命令中的输出 ID。 然后,可以使用 Azure CLI 的 az role assignment 命令分配角色。
az role assignment create --assignee "<user@domain>" \
--role "Azure Event Hubs Data Receiver" \
--scope "<your-resource-id>"
az role assignment create --assignee "<user@domain>" \
--role "Azure Event Hubs Data Sender" \
--scope "<your-resource-id>"
如果使用服务连接器连接服务,则无需完成此步骤。 在你运行服务连接器 CLI 命令时,系统已为你处理必要的角色配置。
更新应用程序代码
需要配置应用程序代码,以查找在部署到 Azure 时创建的特定托管标识。 在某些情况下,显式设置应用的托管标识还可以防止其他环境标识被意外检测到并自动使用。
在托管标识概述页面上,将客户端 ID 值复制到剪贴板。
应用以下特定于语言的更改:
创建一个 DefaultAzureCredentialOptions
对象并将其传递给 DefaultAzureCredential
。 将 ManagedIdentityClientId 属性设置为客户端 ID。
DefaultAzureCredential credential = new(
new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = managedIdentityClientId
});
将 AZURE_CLIENT_ID
环境变量设置为托管标识客户端 ID。 DefaultAzureCredential
读取此环境变量。
调用 managedIdentityClientId 方法。 将客户端 ID 传递给它。
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.managedIdentityClientId(managedIdentityClientId)
.build();
创建一个 DefaultAzureCredentialClientIdOptions
对象,其 managedIdentityClientId 属性设置为客户端 ID。 将该对象传递给 DefaultAzureCredential
构造函数。
const credential = new DefaultAzureCredential({
managedIdentityClientId
});
将 DefaultAzureCredential
构造函数的 managed_identity_client_id 参数设置为客户端 ID。
credential = DefaultAzureCredential(
managed_identity_client_id = managed_identity_client_id
)
进行此更改后,将代码重新部署到 Azure,以便应用配置更新。
测试应用程序
部署更新后的代码后,请在浏览器中导航到你的托管应用程序。 应用应该可以成功连接到事件中心。 请记住,在 Azure 环境中传播角色分配可能需要几分钟的时间。 应用程序现在配置为在本地和生产环境中运行,开发人员无需管理应用程序本身的机密。
后续步骤
本教程介绍了如何将应用程序迁移到无密码连接。
可以阅读以下资源,更深入地了解本文中讨论的概念: