Spring Cloud Azure 身份验证

本文介绍 Spring Cloud Azure身份验证方法,并帮助你选择正确的凭据类型来保护对Azure资源的访问。

使用 Microsoft Entra ID 进行身份验证和授权

通过使用Microsoft Entra ID,可以使用Azure基于角色的访问控制(Azure RBAC)向安全主体(可以是用户或应用程序服务主体)授予权限。 当安全主体(用户或应用程序)尝试访问Azure资源(例如事件中心资源)时,必须授权请求。 通过使用Microsoft Entra ID,访问资源的过程分为两个步骤:

  1. 首先,对安全主体的标识进行身份验证并返回 OAuth 2.0 令牌。
  2. 接下来,将令牌作为请求的一部分传递给Azure服务,以授权访问指定资源。

凭据类型

Spring Cloud Azure使你可以为身份验证(包括DefaultAzureCredential、WorkloadIdentityCredential、ManagedIdentityCredential、ClientSecretCredential)AzureCliCredential等配置不同的凭据类型。

DefaultAzureCredential

DefaultAzureCredential 适用于应用程序在 Azure 云中运行的大多数方案,因为它结合了以下凭据:

  • 通常用于在部署时进行身份验证的凭据。
  • 用于在开发环境中进行身份验证的凭据。

注意

DefaultAzureCredential通过处理具有合理默认行为的常见方案,简化了Azure SDK入门。 如果想要更多控制或默认设置不支持你的方案,请使用其他凭据类型。

DefaultAzureCredential 尝试按以下顺序通过以下机制进行身份验证:

DefaultAzureCredential 身份验证流和凭据顺序的屏幕截图。

  • 环境 - DefaultAzureCredential 尝试读取通过环境变量指定的帐户信息,并使用它进行身份验证。
  • 托管标识 - 如果应用程序部署到启用了托管标识的Azure主机,DefaultAzureCredential则尝试使用该帐户进行身份验证。
  • 工作负荷标识 - 如果应用程序部署到虚拟机(VM), DefaultAzureCredential 则尝试使用该帐户进行身份验证。
  • 共享令牌缓存 - 如果通过Visual Studio进行身份验证,DefaultAzureCredential则尝试使用该帐户进行身份验证。
  • IntelliJ - 如果通过 Azure Toolkit for IntelliJ 进行身份验证,DefaultAzureCredential则尝试使用该帐户进行身份验证。
  • Azure CLI - 如果通过 Azure CLI az login 命令对帐户进行身份验证,DefaultAzureCredential则尝试使用该帐户进行身份验证。
  • Azure PowerShell - 如果通过Azure PowerShell进行身份验证,DefaultAzureCredential则尝试使用该帐户进行身份验证。
  • Azure开发人员 CLI - 如果通过 Azure 开发人员 CLI 进行身份验证,DefaultAzureCredential则尝试使用该帐户进行身份验证。

提示

确保安全主体有足够的权限访问 Azure 资源。 有关详细信息,请参阅 使用 Microsoft Entra ID授权访问。

注意

自 Spring Cloud Azure AutoConfigure 4.1.0 起,您必须注册一个名为 springCloudAzureCredentialTaskExecutor 的 ThreadPoolTaskExecutor Bean,以管理 Azure Identity 创建的所有线程。 此线程池管理的每个线程的名称以 az-identity-为前缀。 这个 ThreadPoolTaskExecutor Bean 独立于 Spring Boot 提供的 Executor Bean。

托管身份

常见的挑战是管理用于保护构成解决方案的不同组件之间的通信的机密和凭据。 托管标识免去了管理凭据的需要。 托管标识为应用程序提供可在连接到支持 Microsoft Entra 身份验证的资源时使用的身份。 应用程序可以使用托管标识来获取Microsoft Entra令牌。 例如,应用程序可以使用托管标识访问Azure 密钥保管库等资源,可以在其中以安全方式存储凭据或访问存储帐户。

使用托管标识,而不是在应用程序中使用连接字符串或密钥,因为它更安全,还能省去管理机密和凭据的麻烦。 在这种情况下,DefaultAzureCredential最好使用本地存储的帐户信息在本地开发,然后将应用程序部署到 Azure Cloud 并使用托管标识进行开发。

托管标识类型

托管标识有两种类型:

  • 系统分配 - 某些 Azure 服务允许直接在服务实例上启用托管标识。 启用系统分配托管标识时,会在 Microsoft Entra 中创建一个标识,该标识与该服务实例的生命周期绑定。 因此,当你删除资源时,Azure 会自动删除标识。 按照设计,只有该 Azure 资源才能使用此标识向 Microsoft Entra ID 请求令牌。
  • 用户分配 - 还可以将托管标识创建为独立的Azure资源。 可以创建用户分配的托管标识,并将其分配给 Azure 服务的一个或多个实例。 使用用户分配的托管标识,可以独立于使用该标识的资源管理该标识。

注意

使用用户分配的托管标识时,请通过 spring.cloud.azure.credential.client-id 或 spring.cloud.azure.<azure-service>.credential.client-id 指定客户端 ID。 如果使用系统分配的托管标识,则不需要凭据配置。

提示

若要访问Azure资源,请确保安全主体具有足够的权限。 有关详细信息,请参阅 使用 Microsoft Entra ID授权访问。

有关托管标识的详细信息,请参阅 什么是 Azure 资源的托管标识?。

其他凭据类型

如果你需要比 DefaultAzureCredential 提供的更多控制,或者默认设置不支持你的使用场景,请使用其他凭据类型。

使用 Microsoft Entra ID 进行身份验证

若要将应用程序连接到支持Microsoft Entra身份验证的资源,请使用前缀spring.cloud.azure.credential或spring.cloud.azure.<azure-service>.credential设置以下配置。

下表列出了身份验证属性:

财产 描述
client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。
client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。
client-certificate-path 使用 Azure 执行服务主体身份验证时要使用的 PEM 证书文件的路径。
client-certificate-password 证书文件的密码。
username 在 Azure 中执行用户名/密码身份验证时要使用的用户名。
password 在 Azure 中执行用户名/密码身份验证时要使用的密码。
managed-identity-enabled 是否启用托管身份。
token-credential-bean-name 在 Azure 中执行身份验证时要使用的 TokenCredential 类型的 bean 名称。

提示

有关所有 Spring Cloud Azure 配置属性的列表,请参阅 Spring Cloud Azure 配置属性。

应用程序在多个位置查找可用的凭据。 如果指定了属性token-credential-bean-name,每个 Azure SDK 客户端生成器工厂都会优先采用类型为TokenCredential的自定义 bean;如果未配置凭据属性,则回退为使用DefaultAzureCredential。

使用自定义 TokenCredential bean 进行身份验证

以下示例演示如何定义要执行身份验证的自定义 TokenCredential bean:

@Bean
TokenCredential myTokenCredential() {
    // Your concrete TokenCredential instance
}
spring.cloud.azure:
  credential:
    token-credential-bean-name: myTokenCredential

使用系统分配的托管标识进行身份验证

以下示例演示如何使用系统分配的托管标识进行身份验证:

spring.cloud.azure:
  credential:
    managed-identity-enabled: true

使用用户分配的托管标识进行身份验证

以下示例演示如何使用用户分配的托管标识进行身份验证:

spring.cloud.azure:
  credential:
    managed-identity-enabled: true
    client-id: ${AZURE_CLIENT_ID}

使用带客户端机密的服务主体进行身份验证

以下示例演示如何使用带有客户端密码的服务主体进行身份验证:

spring.cloud.azure:
  credential:
    client-id: ${AZURE_CLIENT_ID}
    client-secret: ${AZURE_CLIENT_SECRET}
  profile:
    tenant-id: <tenant>

注意

允许 tenant-id 的值包括:common、organizations、consumers或租户 ID。 有关这些值的更多信息,请参阅 错误 AADSTS50020 - 来自标识提供者的用户帐户在租户中不存在 中的 使用了错误的终结点(个人和组织帐户) 部分。 有关转换单租户应用的信息,请参阅 在 Microsoft Entra ID上将单租户应用转换为多租户。

使用客户端证书通过服务主体进行身份验证

以下示例演示如何使用带有客户端 PFX 证书的服务主体进行身份验证:

spring.cloud.azure:
  credential:
    client-id: ${AZURE_CLIENT_ID}
    client-certificate-path: ${AZURE_CLIENT_CERTIFICATE_PATH}
    client-certificate-password: ${AZURE_CLIENT_CERTIFICATE_PASSWORD}
  profile:
    tenant-id: <tenant>

注意

允许 tenant-id 的值包括:common、organizations、consumers或租户 ID。 有关这些值的详细信息,请参阅 错误 AADSTS50020 - 来自标识提供者的用户帐户在租户中不存在中的 使用了错误的终结点(个人和组织帐户)部分。 有关转换单租户应用的信息,请参阅 在 Microsoft Entra ID上将单租户应用转换为多租户。

以下示例说明如何使用带有客户端 PEM 证书的服务主体进行身份验证:

spring.cloud.azure:
  credential:
    client-id: ${AZURE_CLIENT_ID}
    client-certificate-path: ${AZURE_CLIENT_CERTIFICATE_PATH}
  profile:
    tenant-id: <tenant>

注意

允许 tenant-id 的值包括:common、organizations、consumers或租户 ID。 有关这些值的更多信息,请参阅 错误 AADSTS50020 - 来自标识提供者的用户帐户在租户中不存在 中的 使用了错误的终结点(个人和组织帐户) 部分。 有关转换单租户应用的信息,请参阅 在 Microsoft Entra ID上将单租户应用转换为多租户。

使用用户凭据进行身份验证

以下示例演示如何使用用户凭据进行身份验证:

spring.cloud.azure:
  credential:
    client-id: ${AZURE_CLIENT_ID}
    username: ${AZURE_USER_USERNAME}
    password: ${AZURE_USER_PASSWORD}

使用其他凭据对服务进行身份验证

以下示例演示如何使用不同的服务主体对密钥保管库进行身份验证。 此示例使用两个凭据配置应用程序:一个系统分配的托管标识和一个服务主体。 密钥保管库 的机密客户端使用服务主体,而其他任何组件则改用托管标识。

spring.cloud.azure:
  credential:
    managed-identity-enabled: true
  keyvault.secret:
    credential:
      client-id: ${AZURE_CLIENT_ID}
      client-secret: ${AZURE_CLIENT_SECRET}
    profile:
      tenant-id: <tenant>

注意

允许 tenant-id 的值包括:common、organizations、consumers或租户 ID。 有关这些值的更多信息,请参阅 错误 AADSTS50020 - 来自标识提供者的用户帐户在租户中不存在 中的 使用了错误的终结点(个人和组织帐户) 部分。 有关转换单租户应用的信息,请参阅 在 Microsoft Entra ID上将单租户应用转换为多租户。

使用 Microsoft Entra ID 授予访问权限

授权步骤需要向安全主体分配一个或多个Azure角色。 分配给安全主体的角色决定了主体拥有的权限。

提示

有关所有 Azure 内置角色的列表,请参阅 Azure 内置角色。

下表列出了用于授权访问 Spring Cloud Azure 中支持的 Azure 服务的 Azure 内置角色:

角色 描述
应用配置数据所有者 允许完全访问应用配置数据。
应用配置数据读取器 允许读取应用配置数据。
Azure 事件中心数据所有者 允许完全访问 Azure 事件中心资源。
Azure 事件中心数据接收器 允许接收对 Azure 事件中心资源的访问。
Azure 事件中心数据发送方 允许发送对 Azure 事件中心资源的访问。
Azure 服务总线数据所有者 允许完全访问 Azure 服务总线资源。
Azure 服务总线数据接收器 允许接收对 Azure 服务总线资源的访问。
Azure 服务总线数据发送器 允许发送对 Azure 服务总线资源的访问。
存储 Blob 数据所有者 提供对 Azure 存储 Blob 容器和数据的完整访问权限,包括分配 POSIX 访问控制。
存储 Blob 数据读者 读取并列出 Azure 存储容器和 Blob 对象。
存储队列数据读取器 读取和列出 Azure 存储队列和队列消息。
Redis 缓存参与者 管理 Redis 缓存。

注意

当你使用 Spring Cloud Azure 资源管理器 获取事件中心、服务总线 和存储队列的连接字符串,或获取 Redis 缓存的属性时,请分配 Azure 内置角色 Contributor。 Azure Redis 缓存很特别,还可以分配 Redis Cache Contributor 角色来获取 Redis 属性。

注意

密钥保管库访问策略确定给定的安全主体(即用户、应用程序或用户组)是否可以对密钥保管库机密、密钥和证书执行不同的操作。 可以使用Azure门户、Azure CLI或Azure PowerShell来分配访问策略。 有关详细信息,请参阅 分配 密钥保管库 访问策略。

重要

Azure Cosmos DB 公开两个内置角色定义:Cosmos DB Built-in Data Reader 和 Cosmos DB Built-in Data Contributor。 但是,Azure 门户尚不支持角色管理。 有关权限模型、角色定义和角色分配的详细信息,请参阅 使用 Azure Cosmos DB 帐户的 Microsoft Entra ID 配置基于角色的访问控制。

使用 SAS 令牌进行身份验证

还可以使用共享访问签名(SAS)配置服务以进行身份验证。 使用 spring.cloud.azure.<azure-service>.sas-token 属性配置此身份验证。 例如,使用 spring.cloud.azure.storage.blob.sas-token 对 Blob 存储服务进行身份验证。

使用连接字符串进行身份验证

某些Azure服务支持连接字符串来提供连接信息和凭据。 若要使用连接字符串连接到这些Azure服务,请配置spring.cloud.azure.<azure-service>.connection-string。 例如,将 spring.cloud.azure.eventhubs.connection-string 配置为连接到事件中心服务。