向其他Azure资源验证Azure托管应用的建议方法是使用 managed identity。 大多数Azure服务都支持此方法,包括托管在Azure App Service、Azure Container Apps和Azure Virtual Machines上的应用。 有关详细信息,请参阅Azure支持托管标识的服务和资源类型。 有关不同身份验证技术和方法的详细信息,请参阅 使用 Azure 标识库将 Java 应用程序验证到 Azure 服务。
在以下部分中,你将了解以下内容:
- 基本托管标识概念。
- 如何为应用创建用户分配的托管标识。
- 如何将角色分配给用户指定的托管标识。
- 如何通过应用代码使用用户分配的托管标识进行身份验证。
基本托管标识概念
托管标识使应用能够安全地连接到其他Azure资源,而无需使用密钥或其他应用程序机密。 在内部,Azure会跟踪身份以及其被允许连接的资源。 Azure使用此信息自动获取应用的Microsoft Entra令牌,以允许它连接到其他Azure资源。
配置托管应用时,需要考虑两种类型的托管标识:
-
由系统分配的托管标识会直接在 Azure 资源上启用,并关联到其生命周期。 删除资源时,Azure 会自动为您删除身份。 系统分配的标识提供了使用托管标识的极简方法。
-
用户分配的托管标识作为独立的 Azure 资源创建,并提供更大的灵活性和功能。 它们非常适合涉及需要共享相同标识和权限的多个Azure资源的解决方案。 例如,如果多个虚拟机需要访问同一组Azure资源,则用户分配的托管标识可提供可重用性和优化的管理。
小窍门
在托管标识 最佳做法建议 文章中,详细了解如何选择和管理系统分配的托管标识和用户分配的托管标识。
以下部分介绍了为Azure托管应用启用和使用用户分配的托管标识的步骤。 如果需要使用系统分配的托管标识,请参阅 通过系统分配的托管标识验证在 Azure 上托管的 Java 应用访问 Azure 资源。
创建用户分配的托管标识
用户分配的托管标识是使用 Azure 门户或 Azure CLI 在您的 Azure 订阅中创建的独立资源。 Azure CLI命令可以在Azure Cloud Shell中运行,也可以在安装了Azure CLI的工作站上运行。
在 Azure 门户中,在主搜索栏中输入 Managed identities,然后在 Services 节下选择匹配结果。
在托管标识页面上,选择+ 创建。
在“ 创建用户分配的托管标识 ”页上,为用户分配的托管标识选择订阅、资源组和区域,然后提供名称。
选择 “审阅 + 创建 ”以查看并验证输入。
选择“ 创建 ”以创建用户分配的托管标识。
创建标识后,选择“ 转到资源”。
在新标识的 “概述 ”页上,复制 客户端 ID 值,以便在以后配置应用程序代码时使用。
使用 Azure CLI 命令 az identity create 创建托管标识:
az identity create \
--resource-group <resource-group-name> \
--name <identity-name> \
--query 'clientId' \
--output json
该命令输出将输出所创建用户分配的托管标识的客户端 ID。 客户端 ID 用于配置依赖于标识的应用程序代码。
你可以随时使用命令 az identity show 再次查看托管标识属性。
az identity show \
--resource-group <your-resource-group> \
--name <your-managed-identity-name> \
--output json
将托管身份标识分配给您的应用程序
用户分配的托管标识可以与一个或多个Azure资源相关联。 使用该标识的所有资源都通过该标识的角色获得应用的权限。
在Azure门户中,导航到托管应用代码的资源,例如Azure App Service或Azure Container Apps实例。
在资源的 概述 页中,展开 设置,并从导航菜单中选择 身份。
在“标识”页上,切换到“用户分配”选项卡。
选择 “+ 添加” 以打开 “添加用户分配的托管标识 ”面板。
在 添加用户分派管理身份 面板中,使用 订阅 下拉列表筛选身份的搜索结果。 使用 用户分配的托管标识搜索框查找为托管应用的Azure资源启用的用户分配托管标识。
选择标识,然后选择面板底部的 “添加” 以继续。
Azure CLI提供了不同的命令,用于将用户分配的托管标识分配给不同类型的托管服务。
若要使用 Azure CLI 将用户分配的托管身份分配给资源,例如 Azure App Service web 应用程序,您需要身份的资源 ID。
az identity show使用命令检索资源 ID:
az identity show \
--resource-group <your-resource-group> \
--name <your-managed-identity-name> \
--output json \
--query id
获得资源 ID 后,请使用 Azure CLI 命令 az <resourceType> identity assign 命令将用户分配的托管标识与不同的资源相关联,例如:
对于Azure App Service,请使用 Azure CLI 命令 az webapp identity assign:
az webapp identity assign \
--resource-group <resource-group-name> \
--name <webapp-name> \
--identities <user-assigned-identity-resource-id>
对于Azure Container Apps,请使用 Azure CLI 命令 az containerapp identity assign:
az containerapp identity assign \
--resource-group <resource-group-name> \
--name <containerapp-name> \
--user-assigned <user-assigned-identity-resource-id>
对于Azure Virtual Machines,请使用 az vm identity assign Azure CLI 命令:
az vm identity assign \
--resource-group <resource-group-name> \
--name <vm-name> \
--identities <user-assigned-identity-resource-id>
为托管标识分配角色
接下来,确定应用需要哪些角色并将这些角色分配给托管标识。 你可以为托管标识分配以下范围内的角色:
-
资源:分配的角色仅适用于该特定资源。
-
资源组:分配的角色适用于资源组中包含的所有资源。
-
订阅:被分配的角色适用于订阅中包含的所有资源。
以下示例演示如何在资源组范围内分配角色,因为许多应用使用单个资源组管理其所有相关Azure资源。
导航到包含具有用户分配托管标识的应用的资源组的 “概述 ”页。
在左侧导航栏中,选择“访问控制(IAM)”。
在 访问控制(IAM) 页上,选择顶部菜单上的 + 添加,然后选择 添加角色分配 导航到 添加角色分配 页。
“添加角色分配”页展示了一个分步骤的选项卡式工作流程,用于将角色分配给标识。 在初始“角色”选项卡上,使用顶部的搜索框来定位你想要分配给标识的角色。
从结果中选择角色,然后选择 “下一步” 以进入“成员”选项卡。
对于“将访问权限分配到”选项,请选择“托管标识”。
对于“成员”选项,请选择“+ 选择成员”,以打开“选择托管标识”面板。
在 选择托管标识 面板中,使用 订阅 和 托管标识 下拉列表来筛选标识的搜索结果。 使用 Select 搜索框查找您为托管应用的 Azure 资源启用的用户分配托管标识。
选择标识,并在面板底部选择选择以继续。
选择页面底部的“查看 + 分配”。
在最终的 审阅 + 分配 选项卡中,选择 审阅 + 分配 以完成整个工作流程。
若要使用 Azure CLI 将角色分配给用户分配的托管标识,需要托管标识的主体 ID。 使用az identity show命令检索主体 ID。
az identity show \
--resource-group <your-resource-group> \
--name <your-managed-identity-name> \
--output json \
--query principalId
使用 az role definition list 命令来查看可分配给托管标识的角色:
az role definition list \
--query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
--output table
使用 az role assignment create 命令为托管标识分配角色:
az role assignment create \
--assignee <your-principal-id> \
--role <role-name> \
--scope <scope>
例如,若要允许 ID 为 99999999-9999-9999-9999-999999999999 的托管标识读取、写入和删除 msdocs-sdk-auth-example 资源组中所有存储帐户的 Azure Storage blob 容器及数据的访问权限,请使用以下命令将应用程序服务主体分配到 Storage Blob Data Contributor 角色。
az role assignment create \
--assignee 99999999-9999-9999-9999-999999999999 \
--role "Storage Blob Data Contributor" \
--scope "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/msdocs-sdk-auth-example"
有关使用 Azure CLI 在资源或订阅级别分配权限的信息,请参阅文章 使用 Azure CLI 分配 Azure 角色。
通过应用向Azure服务进行身份验证
Azure标识库提供不同的凭据作为 TokenCredential 的实现。 每个实现都支持不同的方案和Microsoft Entra身份验证流。 对于用户分配的托管标识,在配置凭据时,需要指定该标识的客户端 ID、资源 ID 或对象 ID。
实现代码
将 azure-identity 依赖项添加到 pom.xml 文件:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
</dependency>
可以使用Azure SDK客户端库中的专用客户端类访问Azure服务。 以下代码示例演示如何为用户分配的托管标识身份验证配置凭据。
使用 DefaultAzureCredential
使用 DefaultAzureCredential 作为Azure托管应用的凭据。 对于用户分配的托管标识,请通过使用 managedIdentityClientId 方法来配置客户端 ID。
import com.azure.identity.DefaultAzureCredential;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
// Configure DefaultAzureCredential with the user-assigned managed identity's client ID
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
.managedIdentityClientId("<user-assigned-managed-identity-client-id>")
.build();
// Azure SDK client builders accept the credential as a parameter
SecretClient client = new SecretClientBuilder()
.vaultUrl("https://<your-key-vault-name>.vault.azure.net")
.credential(credential)
.buildClient();
使用 ManagedIdentityCredential
如果要显式使用托管身份凭据并避免在 DefaultAzureCredential 中查找凭据链,请直接使用 ManagedIdentityCredential 。 对于用户分配的托管标识,可以使用客户端 ID、资源 ID 或对象 ID 来指定标识。
配置需要使用该标识进行身份验证的应用程序或服务时,使用客户端 ID 标识托管标识。
使用以下命令检索分配给用户托管身份的客户端 ID:
az identity show \
--resource-group <resource-group-name> \
--name <identity-name> \
--query clientId \
--output tsv
将 ManagedIdentityCredential 配置为客户端 ID:
import com.azure.identity.ManagedIdentityCredential;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
// Specify the client ID of the user-assigned managed identity
ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder()
.clientId("<user-assigned-managed-identity-client-id>")
.build();
// Azure SDK client builders accept the credential as a parameter
SecretClient client = new SecretClientBuilder()
.vaultUrl("https://<your-key-vault-name>.vault.azure.net")
.credential(credential)
.buildClient();
资源 ID 是用户分配的托管标识资源的完整 Azure 资源管理器 (ARM) 路径。
使用以下命令来检索分配给用户分配托管身份的资源标识符:
az identity show \
--resource-group <resource-group-name> \
--name <identity-name> \
--query id \
--output tsv
使用资源 ID 配置 ManagedIdentityCredential:
import com.azure.identity.ManagedIdentityCredential;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
// Specify the resource ID of the user-assigned managed identity
ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder()
.resourceId("/subscriptions/<subscription-id>/resourcegroups/<resource-group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identity-name>")
.build();
// Azure SDK client builders accept the credential as a parameter
SecretClient client = new SecretClientBuilder()
.vaultUrl("https://<your-key-vault-name>.vault.azure.net")
.credential(credential)
.buildClient();
对象 ID 是 Microsoft Entra ID 中托管标识的服务主体的唯一标识符。
使用以下命令检索分配给用户分配的托管标识的对象 ID:
az identity show \
--resource-group <resource-group-name> \
--name <identity-name> \
--query principalId \
--output tsv
使用对象 ID 配置 ManagedIdentityCredential:
import com.azure.identity.ManagedIdentityCredential;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
// Specify the object ID of the user-assigned managed identity
ManagedIdentityCredential credential = new ManagedIdentityCredentialBuilder()
.objectId("<user-assigned-managed-identity-object-id>")
.build();
// Azure SDK client builders accept the credential as a parameter
SecretClient client = new SecretClientBuilder()
.vaultUrl("https://<your-key-vault-name>.vault.azure.net")
.credential(credential)
.buildClient();
后续步骤
本文介绍使用用户分配的托管标识进行身份验证。 这种形式的身份验证是可在Java的Azure SDK中进行身份验证的多种方式之一。 以下文章介绍了其他身份验证方法:
如果遇到与Azure托管的应用程序身份验证相关的问题,请参阅 Troubleshoot Azure 托管的应用程序身份验证。
在掌握身份验证后,请参阅 在 Azure SDK for Java 中配置日志记录 以获取有关 SDK 提供的日志功能的信息。