排查 Azure 托管的应用程序身份验证问题
本文提供了通过各种 TokenCredential
实现,对 Azure 上托管的 Azure SDK for Java 应用程序进行身份验证时遇到的问题的处理指南。 有关详细信息,请参阅对 Azure 托管的 Java 应用程序进行身份验证。
排查 DefaultAzureCredential 问题
使用 DefaultAzureCredential
时,可以为 CredentialUnavailableException
选择 try/catch。 下表显示了此异常指示的错误以及缓解方法:
错误消息 | 说明 | 缓解操作 |
---|---|---|
CredentialUnavailableException raised with message "DefaultAzureCredential failed to retrieve a token from the included credentials." |
DefaultAzureCredential 链中的所有凭据都未能检索令牌,每个凭据都引发一个 CredentialUnavailableException 。 |
启用日志记录以验证正在尝试的凭据,并获取进一步的诊断信息。 有关详细信息,请参阅以下基础凭据类型之一的故障排除指南: - EnvironmentCredential - ManagedIdentityCredential - VisualStudioCodeCredential - AzureCLICredential - AzurePowershellCredential |
HttpResponseException raised from the client with a status code of 401 or 403 |
身份验证成功,但授权 Azure 服务的响应为 401(身份验证)或 403(禁止)状态代码。 当 DefaultAzureCredential 验证的帐户不是预期的帐户,或者预期的帐户没有正确的权限或分配的角色时,通常会出现此问题。 |
启用日志记录以确定链中哪个凭据返回了身份验证令牌。 如果非预期凭据返回令牌,请通过注销相应的开发工具来绕过此问题。 确保为正在使用的帐户分配了正确的角色。 例如,特定于服务的角色,而不是订阅所有者角色。 |
排查 EnvironmentCredential 问题
使用 EnvironmentCredential
时,可以为 CredentialUnavailableException
选择 try/catch。 下表显示了此异常指示的错误以及缓解方法:
错误消息 | 说明 | 缓解操作 |
---|---|---|
Environment variables aren't fully configured. |
未设置环境变量的有效组合。 | 请确保在应用程序启动之前为预期的身份验证方法设置适当的环境变量,如以下列表所述: - 若要使用客户端机密对服务主体进行身份验证,请确保变量 AZURE_CLIENT_ID 、AZURE_TENANT_ID 和 AZURE_CLIENT_SECRET 设置正确。 - 若要使用证书对服务主体进行身份验证,请确保变量 AZURE_CLIENT_ID 、AZURE_TENANT_ID 、AZURE_CLIENT_CERTIFICATE_PATH 和可选的 AZURE_CLIENT_CERTIFICATE_PASSWORD 设置正确。 - 若要使用密码对用户进行身份验证,请确保变量 AZURE_USERNAME 和 AZURE_PASSWORD 设置正确。 |
排查 ManagedIdentityCredential 问题
ManagedIdentityCredential
设计用于在提供托管标识的各种 Azure 主机上工作。 配置托管标识和故障排除失败因主机而异。 以下列表显示了可以分配托管标识并且 ManagedIdentityCredential
支持的 Azure 主机环境:
- Azure 应用程序服务和 Azure Functions - 配置 - 故障排除
- Azure Arc - 配置
- Azure Kubernetes 服务 - 配置 - 故障排除
- Azure Service Fabric -配置
- Azure 虚拟机和规模集 -配置 - 故障排除
Azure 虚拟机托管标识
使用 ManagedIdentityCredential
时,可以为 CredentialUnavailableException
选择 try/catch。 下表显示了此异常指示的错误以及缓解方法:
错误消息 | 说明 | 缓解操作 |
---|---|---|
The requested identity hasn't been assigned to this resource. |
Azure 实例元数据服务 (IMDS) 终结点的响应状态代码为 400,指示请求的标识未分配给虚拟机 (VM)。 | 如果使用用户分配的标识,请确保指定的 clientId 正确。 如果使用系统分配的标识,请确保已正确启用它。 有关详细信息,请参阅使用使用 Azure 门户在 VM 上配置 Azure 资源托管标识的在现有 VM 上启用系统分配托管标识部分。 |
The request failed due to a gateway error. |
由于网关错误,对 IMDS 终结点的请求失败,状态代码为 502 或 504。 | IMDS 不支持通过代理或网关进行调用。 禁用在 VM 上运行的代理或网关以调用 IMDS 终结点 http://169.254.169.254/ |
No response received from the managed identity endpoint. |
未收到对 IMDS 的请求的响应或请求超时。 | - 确保已在 VM 上正确配置托管标识。 有关详细信息,请参阅使用 Azure 门户在 VM 上配置 Azure 资源托管标识。 - 验证 VM 上是否可以访问 IMDS 终结点。 有关详细信息,请参阅下一节。 |
Multiple attempts failed to obtain a token from the managed identity endpoint. |
从 IMDS 终结点检索令牌的重试已用尽。 | - 有关特定故障的详细信息,请参阅内部异常消息。 如果数据已被截断,可以通过收集日志来获取更多详细信息。 - 确保已在 VM 上正确配置托管标识。 有关详细信息,请参阅使用 Azure 门户在 VM 上配置 Azure 资源托管标识。 - 验证 VM 上是否可以访问 IMDS 终结点。 有关详细信息,请参阅下一节。 |
验证 VM 上的 IMDS 是否可用
如果有权访问 VM,则可以使用 curl
命令行验证托管标识终结点是否可用,如以下示例所示:
curl 'http://169.254.169.254/metadata/identity/oauth2/token?resource=https://management.core.windows.net&api-version=2018-02-01' -H "Metadata: true"
警告
此命令的输出包含有效的访问令牌。 为了避免危及帐户安全性,请不要共享此访问令牌。
Azure 应用服务和 Azure Functions 托管标识
使用 ManagedIdentityCredential
时,可以为 CredentialUnavailableException
选择 try/catch。 下表显示了此异常指示的错误以及缓解方法:
错误消息 | 说明 | 缓解操作 |
---|---|---|
ManagedIdentityCredential authentication unavailable. |
应用程序服务主机配置的环境变量不存在。 | - 确保已在应用程序服务实例上正确配置了托管标识。 有关详细信息,请参阅如何使用应用服务和 Azure Functions 的托管标识。 - 验证是否已正确配置应用程序服务环境,以及托管标识终结点是否可用。 有关详细信息,请参阅下一节。 |
验证应用程序服务托管标识终结点是否可用
如果你有权通过 SSH 访问应用程序服务实例,则可以验证托管标识在环境中是否可用。 首先,确保已在环境中设置了环境变量 MSI_ENDPOINT
和 MSI_SECRET
。 然后,可以使用 curl
验证托管标识终结点是否可用,如以下示例所示:
curl 'http://169.254.169.254/metadata/identity/oauth2/token?resource=https://management.core.windows.net&api-version=2018-02-01' -H "Metadata: true"
警告
此命令的输出包含有效的访问令牌。 为了避免危及帐户安全性,请不要共享此访问令牌。
Azure Kubernetes 服务托管标识
Kubernetes 的 Pod 标识
使用 ManagedIdentityCredential
时,可以为 CredentialUnavailableException
选择 try/catch。 下表显示了此异常指示的错误以及缓解方法:
错误消息 | 说明 | 缓解操作 |
---|---|---|
No Managed Identity endpoint found |
应用程序在为其 pod 分配标识之前尝试进行身份验证。 | 验证 Pod 是否已正确标记。 当正确标记的 Pod 在标识准备就绪之前进行身份验证时,也会出现此问题。 为了防止初始化竞争,请配置 NMI 在其响应中设置 Retry-After 标头。 有关详细信息,请参阅 Pod 标识文档中的在 NMI 响应中设置 Retry-After 标头。 |
排查 WorkloadIdentityCredential 问题
使用 WorkloadIdentityCredential
时,可以为 CredentialUnavailableException
选择 try/catch。 下表显示了此异常指示的错误以及缓解方法:
错误消息 | 说明 | 缓解操作 |
---|---|---|
WorkloadIdentityCredential authentication unavailable. The workload options aren't fully configured. |
WorkloadIdentityCredential 需要 clientId 、tenantId 和 tokenFilePath 使用 Microsoft Entra ID 进行身份验证。 |
如果正在使用 DefaultAzureCredential ,则:- 确保通过 workloadIdentityClientId 资源库或 AZURE_CLIENT_ID 环境变量指定客户端 ID。 - 确保通过 AZURE_TENANT_ID 环境变量指定租户 ID。 - 确保已通过 AZURE_FEDERATED_TOKEN_FILE 环境变量指定了令牌文件路径。 - 确保通过 AZURE_AUTHORITY_HOST 环境变量指定颁发机构主机。 如果正在使用 WorkloadIdentityCredential ,则:- 确保通过凭据生成器上的 tenantId 资源库或 AZURE_TENANT_ID 环境变量指定租户 ID。 - 确保通过凭据生成器上的 clientId 资源库或 AZURE_CLIENT_ID 环境变量指定客户端 ID。 - 确保通过凭据生成器上的 tokenFilePath 资源库或 AZURE_FEDERATED_TOKEN_FILE 环境变量指定令牌文件路径。 - 有关其他问题,请参阅产品故障排除指南。 |
后续步骤
如果本文中的故障排除指南无法帮助你解决使用 Azure SDK for Java 客户端库时出现的问题,建议您在 Azure SDK for Java GitHub 存储库中提交问题。