Spring Cloud Azure 参考文档

本文提供了 Spring Cloud Azure 4.4.0 的参考文档。

本文档仅适用于 Spring Cloud Azure: 4.4.0。 请参阅 Spring Versions Mapping 以获取有关受支持版本的详细信息。

Spring 是 VMware 开发的开源应用程序框架,它提供简化的模块化方法来创建 Java 应用程序。 Spring Cloud Azure 是一个开源项目,可提供与 Azure 的无缝 Spring 集成。

获取帮助

如果对此文档有任何疑问,请在以下 GitHub 存储库之一中创建 GitHub 问题。 也欢迎提交拉取请求。

GitHub 存储库 说明
Azure/azure-sdk-for-java 此存储库包含源代码。
MicrosoftDocs/azure-dev-docs 此存储库包含文档。

自 3.10.x 起的 4.0 中的新增功能

本文档介绍自 3.10 年以来 4.0 中所做的更改。 此主要版本带来了更好的安全性、更精简的依赖项、对生产就绪情况的支持等。

提示

有关迁移到 4.0 的详细信息,请参阅 4.0 的迁移指南

以下列表汇总了 Spring Cloud Azure 4.0 提供的一些更改:

  • 具有统一项目名称、项目 ID 和属性的统一开发体验。
  • 使用单个 spring-cloud-azure-dependencies BOM 简化了依赖项管理。
  • Spring Initializr 上展开Azure 支持,涵盖 Kafka、事件中心、Azure Cache for Redis和Azure 应用程序配置。
  • 重新构造 Spring 模块依赖项以删除多余的层和纠缠。
  • 托管标识支持Azure 应用程序配置、事件中心、服务总线、Cosmos DB、密钥保管库、存储 Blob 和存储队列。
  • 我们 Spring 库中的基础 Azure SDK 中继续支持身份验证方法,例如使用服务总线和事件中心进行 SAS 令牌和令牌凭据身份验证。
  • 凭据链 现已默认启用,使应用程序能够从应用程序属性、环境变量、托管标识、IDE 等获取凭据。
  • 在资源级别 ((例如服务总线队列) )进行精细访问控制,以便更好地管理安全并遵守 IT 策略。
  • 通过显著改进 Azure SDK 客户端的自动配置覆盖,实现同步和异步方案,以 Spring-idiomatic 方式公开更多选项。
  • 为 Azure 应用程序配置、事件中心、Cosmos DB、密钥保管库、存储 Blob、存储队列和存储文件添加了运行状况指示器。
  • Spring Cloud Sleuth 支持所有基于 HTTP 的 Azure SDK。

4.0 迁移指南

有关迁移到 4.0 的详细信息,请参阅 4.0 的迁移指南

入门

设置依赖项

材料清单 (BOM)

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-dependencies</artifactId>
      <version>${spring.cloud.azure.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

spring-cloud-azure-dependencies 的版本为 4.4.0。

初学者依赖项

Spring Cloud Azure Starters 是一组方便的依赖项描述符,用于包含在应用程序中。 每个初学者都包含开始使用其相应的 Spring Cloud Azure 模块所需的所有依赖项和可传递依赖项。 这些初学者通过 Azure 服务提升 Spring Boot 应用程序开发。

例如,如果要开始使用 Spring 和 Azure Cosmos DB 进行数据暂留,请在 spring-cloud-azure-starter-cosmos 项目中包括依赖项。

下表列出了 Spring Cloud Azure 在组下 com.azure.spring 提供的应用程序初学者:

名称 说明
spring-cloud-azure-starter 核心初学者,包括自动配置支持。
spring-cloud-azure-starter-active-directory 将 Azure Active Directory 与 Spring Security 配合使用的入门。
spring-cloud-azure-starter-active-directory-b2c 将 Azure Active Directory B2C 与 Spring Security 配合使用的入门。
spring-cloud-azure-starter-appconfiguration 使用 Azure 应用程序配置 的初学者。
spring-cloud-azure-starter-cosmos 开始使用 Azure Cosmos DB 的入门方法。
spring-cloud-azure-starter-eventhubs 用于使用 Azure 事件中心 的初学者。
spring-cloud-azure-starter-keyvault 使用 Azure 密钥保管库的初学者。
spring-cloud-azure-starter-keyvault-secrets 使用 Azure 密钥保管库 机密的入门方法。
spring-cloud-azure-starter-keyvault-certificates 开始使用 Azure 密钥保管库 证书。
spring-cloud-azure-starter-servicebus Azure 服务总线入门。
spring-cloud-azure-starter-servicebus-jms 使用 Azure 服务总线 和 JMS 的初学者。
spring-cloud-azure-starter-storage 使用 Azure 存储的入门方法。
spring-cloud-azure-starter-storage-blob 使用 Azure 存储 Blob 的入门方法。
spring-cloud-azure-starter-storage-file-share 使用 Azure 存储文件共享的入门方法。
spring-cloud-azure-starter-storage-queue 使用 Azure 存储队列的入门方法。
spring-cloud-azure-starter-initialize 使用 Spring Boot 的执行器入门,它提供了生产就绪的功能。

下表列出了 Spring Data 支持的初学者:

名称 说明
spring-cloud-azure-starter-data-cosmos 开始使用 Azure Cosmos DB 和 Spring Data Cosmos DB 的入门方法。

下表列出了 Spring Integration 支持的初学者:

名称 说明
spring-cloud-azure-starter-integration-eventhubs 使用 Azure 事件中心 和 Spring Integration 的初学者。
spring-cloud-azure-starter-integration-servicebus 使用 Azure 服务总线 和 Spring Integration 的初学者。
spring-cloud-azure-starter-integration-storage-queue 使用 Azure 存储队列和 Spring Integration 的入门方法。

下表列出了 Spring Cloud Stream 支持的初学者:

名称 说明
spring-cloud-azure-starter-stream-eventhubs 使用 Azure 事件中心 和 Spring Cloud Stream Binder 的入门。
spring-cloud-azure-starter-stream-servicebus 使用 Azure 服务总线 和 Spring Cloud Stream Binder 的初学者。

Learning Spring Cloud Azure

我们准备了示例的完整列表以显示使用情况。 可以在 Spring Cloud Azure 示例中找到这些示例。

Spring Cloud Azure 配置

大多数 Azure 服务 SDK 可以按传输类型划分为两个类别:基于 HTTP 或基于 AMQP。 所有 SDK(例如身份验证主体和 Azure 环境设置)都有通用的属性,或基于 HTTP 的客户端的常见属性,例如记录 HTTP 请求和响应的日志记录级别。 在 Spring Cloud Azure 4.0 中,我们添加了可以为每个 Azure 服务指定的五个常见配置属性类别。

下表列出了多个服务通用的属性:

properties 说明
spring.cloud.azure.azure-service.client 在一个 Azure 服务 SDK 下配置传输客户端。
spring.cloud.azure.azure-service.credential 为一个 Azure 服务 SDK 配置 Azure Active Directory 身份验证。
spring.cloud.azure.azure-service.profile 为一个 Azure 服务 SDK 配置 Azure 云环境。
spring.cloud.azure.azure-service.proxy 为一个 Azure 服务 SDK 配置代理选项。
spring.cloud.azure.azure-service.retry 配置适用于一个 Azure 服务 SDK 的重试选项。 重试选项支持 SDK 的一部分,没有 spring.cloud.azure.cosmos.retry。

可以在不同的 Azure 服务之间共享一些属性,例如,使用相同的服务主体访问 Azure Cosmos DB 和Azure 事件中心。 Spring Cloud Azure 4.0 使你能够定义应用于命名空间 spring.cloud.azure中所有 Azure SDK 的属性。

下表列出了全局属性:

properties 说明
spring.cloud.azure.client 配置传输客户端;默认情况下适用于所有 Azure SDK。
spring.cloud.azure.credential 默认情况下,为所有 Azure SDK 配置 Azure Active Directory 身份验证。
spring.cloud.azure.profile 默认情况下,为所有 Azure SDK 配置 Azure 云环境。
spring.cloud.azure.proxy 默认情况下,配置适用于所有 Azure SDK 客户端的代理选项。
spring.cloud.azure.retry 默认情况下,配置适用于所有 Azure SDK 客户端的重试选项。

注意

在每个 Azure 服务下配置的属性将覆盖全局配置。

自 Spring Cloud Azure 4.0 以来,配置属性的前缀已统一到 spring.cloud.azure 命名空间,使配置属性更加一致且更直观。 下表提供了对受支持的 Azure 服务的前缀的快速评审:

Azure 服务 配置属性前缀 配置属性链接
Azure 应用程序配置 spring.cloud.azure.appconfiguration 应用程序配置属性
Azure Cosmos DB spring.cloud.azure.cosmos Cosmos DB 属性
Azure 事件中心 spring.cloud.azure.eventhubs 事件中心属性
Azure 密钥保管库 证书 spring.cloud.azure.keyvault.certificate 密钥保管库证书属性
Azure 密钥保管库机密 spring.cloud.azure.keyvault.secret 密钥保管库机密属性
Azure 服务总线 spring.cloud.azure.servicebus 服务总线属性
Azure 存储 Blob spring.cloud.azure.storage.blob 存储 Blob 属性
Azure 存储文件共享 spring.cloud.azure.storage.fileshare 存储文件共享属性
Azure 存储队列 spring.cloud.azure.storage.queue 存储队列属性

Spring Cloud Azure 身份验证

DefaultAzureCredential

适用于 DefaultAzureCredential 在 Azure 云中运行应用程序的大多数方案。 这是因为在 DefaultAzureCredential 部署时通常用于在开发环境中进行身份验证的凭据组合在一起。

注意

DefaultAzureCredential 旨在通过使用合理的默认行为处理常见方案来简化 SDK 入门。 如果想要更多控制或方案未由默认设置提供,则应使用其他凭据类型。

DefaultAzureCredential 将依次尝试通过以下机制进行身份验证:

显示“DefaultAzureCredential”身份验证机制的关系图。

  • 环境 - DefaultAzureCredential 将通过环境变量读取指定的帐户信息,并使用它进行身份验证。
  • 托管标识 - 如果将应用程序部署到了启用了托管标识的 Azure 主机,则 DefaultAzureCredential 将使用该帐户进行身份验证。
  • IntelliJ - 如果已通过 Azure Toolkit for IntelliJ 进行了身份验证,DefaultAzureCredential 将使用该帐户进行身份验证。
  • Visual Studio Code - 如果已通过 Visual Studio Code Azure 帐户插件进行身份验证,DefaultAzureCredential 将使用该帐户进行身份验证。
  • Azure CLI - 如果已通过 Azure CLI az login 命令对帐户进行身份验证,DefaultAzureCredential 将使用该帐户进行身份验证。

提示

确保安全主体已授予足够的权限来访问 Azure 资源。 有关详细信息,请参阅 使用 Azure Active Directory 授权访问

注意

由于 Spring Cloud Azure AutoConfigure 4.1.0, ThreadPoolTaskExecutor 因此默认情况下会自动注册名为 springCloudAzureCredentialTaskExecutor bean 的 bean,并将管理 Azure 标识创建的所有线程。 此线程池管理的每个线程的名称都带有 az-identity-前缀。 这种 ThreadPoolTaskExecutor 豆独立于 Executor Spring Boot 提供的豆。

托管标识

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

我们建议在应用程序中使用托管标识,而不是在应用程序中使用连接字符串或密钥,因为它更安全,并且会节省管理机密和凭据的麻烦。 在这种情况下, DefaultAzureCredential 可以更好地使用本地存储的帐户信息在本地开发方案,然后将应用程序部署到 Azure 云并使用托管标识。

托管标识类型

托管标识分为两种类型:

  • 系统分配 - 某些 Azure 服务允许直接在服务实例上启用托管标识。 当你启用系统分配的托管标识时,Azure AD 中便会创建一个与相应服务实例的生命周期相关联的标识。 因此,资源被删除时,Azure 会自动删除标识。 按照设计,只有该 Azure 资源可以使用此标识从 Azure AD 请求令牌。
  • 用户分配 - 还可以创建托管标识作为独立的 Azure 资源。 你可以创建用户分配的托管标识,并将其分配给一个或多个 Azure 服务实例。 使用用户分配的托管标识时,标识与使用它的资源分开管理。

注意

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

提示

确保已向安全主体授予访问 Azure 资源所需的足够权限。 有关详细信息,请参阅 使用 Azure Active Directory 授权访问

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

其他凭据类型

如果需要更多控制,或者方案未由 DefaultAzureCredential 默认设置提供,则应使用其他凭据类型。

使用 Azure Active Directory 进行身份验证和授权

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

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

若要将应用程序连接到支持 Azure Active Directory (Azure AD) 身份验证的资源,可以使用前缀 spring.cloud.azure.credentialspring.cloud.azure.<azure-service>.credential

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

properties 说明
client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。
client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。
client-certificate-path 使用 Azure 执行服务主体身份验证时要使用的 PEM 证书文件的路径。
client-certificate-password 证书文件的密码。
username 在 Azure 中执行用户名/密码身份验证时要使用的用户名。
password 在 Azure 中执行用户名/密码身份验证时要使用的密码。
已启用 managed-identity-enabled 是否启用托管标识。

提示

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

应用程序将在多个位置查找可用凭据,如果未配置凭据属性,则使用 DefaultAzureCredential 。 若要使用特定凭据,请参阅以下示例获取指导。

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

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: ${AZURE_TENANT_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: ${AZURE_TENANT_ID}

以下示例演示如何在客户端 PEM 证书中使用服务主体进行身份验证:

spring.cloud.azure:
  credential:
    client-id: ${AZURE_CLIENT_ID}
    client-certificate-path: ${AZURE_CLIENT_CERTIFICATE_PATH}
  profile:
    tenant-id: ${AZURE_TENANT_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: ${AZURE_TENANT_ID}
使用 Azure Active Directory 授予访问权限

授权步骤要求将一个或多个 Azure 角色分配给安全主体。 分配给安全主体的角色确定了该主体拥有的权限。

提示

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

下表列出了 Azure 内置角色,用于授权访问 Spring Cloud 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 Cache for Redis很特殊,还可以分配Redis Cache Contributor角色以获取 Redis 属性。

注意

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

重要

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

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 连接到事件中心服务。

生产就绪

我们为应用程序配置、事件中心、Cosmos DB、密钥保管库、存储 Blob、存储队列和存储文件以及 Spring Cloud Sleuth 支持所有基于 HTTP 的 Azure SDK 添加了运行状况指示器。 例如,现在可以探测以确定存储 blob 是通过 Spring Boot 执行器终结点启动还是关闭,以及跟踪从应用程序到密钥保管库的依赖项和延迟。

启用运行状况指示器

若要启用运行状况指示器,请将 Spring Cloud Azure 执行器初学者依赖项添加到 pom.xml 文件中。 此依赖项还将包括 .spring-boot-starter-actuator

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-actuator</artifactId>
</dependency>

下表列出了用于启用或禁用每个 Azure 服务的运行状况指示器的可配置属性:

Azure 服务 properties
应用程序配置 management.health.azure-appconfiguration.enabled
Cosmos DB management.health.azure-cosmos.enabled
事件中心 management.health.azure-eventhubs.enabled
密钥保管库证书 management.health.azure-keyvault-certificate.enabled
密钥保管库机密 management.health.azure-keyvault-secret.enabled
存储 Blob management.health.azure-storage-blob.enabled
存储文件共享 management.health.azure-storage-fileshare.enabled
存储队列 management.health.azure-storage-queue.enabled

重要

调用 Azure 服务的运行状况终结点可能会导致额外费用。 例如,如果调用 http://HOST_NAME:{port}/actuator/health/cosmos 获取 Cosmos DB 运行状况信息,它将计算请求单位 (RU) 。 有关详细信息,请参阅 Azure Cosmos DB 中的请求单位

注意

若要调用运行状况终结点 Cosmos,应配置该选项 spring.cloud.azure.cosmos.database ;否则,将返回其运行状况 unknown

若要调用运行状况终结点Storage Queue,需要使用Azure AD角色Storage Account Contributor进行授权。

启用 sleuth

若要使用 Spring Cloud Sleuth 跟踪 Azure SDK 活动,请将以下 Spring Cloud Azure Trace Sleuth 依赖项添加到 pom.xml 文件中:

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-trace-sleuth</artifactId>
</dependency>

注意

目前仅支持基于 HTTP 的 Azure SDK 客户端。 例如,目前不支持使用 AMQP 传输的事件中心和服务总线。 对于这些要求,建议使用 Azure 应用程序 Insight

自动配置 Azure SDK 客户端

Spring Boot 简化了 Spring Cloud Azure 开发体验。 Spring Cloud Azure 初学者是一组方便的依赖项描述符,用于包含在应用程序中。 初学者处理对象实例化和配置逻辑,因此无需这样做。 每个初学者都依赖于 spring-cloud-azure-starter 提供关键位的配置,例如 Azure 云环境和身份验证信息。 可以将这些文件配置为属性,例如 YAML 文件,如以下示例所示:

spring:
  cloud:
    azure:
      profile:
        tenant-id: ${AZURE_TENANT_ID}
        cloud-type: Azure
      credential:
        client-id: ${AZURE_CLIENT_ID}

注意

cloud 属性为可选。

这些属性是可选的,如果未指定,Spring Boot 将尝试自动查找它们。 有关 Spring Boot 如何查找这些属性的详细信息,请参阅文档。

依赖项设置

有两种方法可以使用 Spring Cloud Azure 初学者。 第一种方法是将 Azure SDK 与依赖项配合使用 spring-cloud-azure-starter ,如以下示例所示:

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-cosmos</artifactId>
</dependency>
<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter</artifactId>
</dependency>

第二种方法是避免添加 Azure SDK 依赖项,而是直接为每个服务添加 Spring Cloud Azure Starter。 例如,使用 Cosmos DB,可以添加以下依赖项:

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-cosmos</artifactId>
</dependency>

提示

有关受支持的初学者列表,请参阅 Starter 依赖项

配置

注意

如果使用安全主体通过 Azure Active Directory 进行身份验证和授权来访问 Azure 资源,请确保已授予安全主体访问 Azure 资源的足够权限。 有关详细信息,请参阅 使用 Azure Active Directory 授权访问

每个 Azure 服务的配置属性都位于前缀 spring.cloud.azure.<azure-service>下。

提示

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

基本用法

将以下属性添加到 application.yaml 文件会自动配置 Cosmos DB 客户端。

spring:
  cloud:
    azure:
      cosmos:
        database: ${AZURE_COSMOS_DATABASE_NAME}
        endpoint: ${AZURE_COSMOS_ENDPOINT}
        consistency-level: eventual
        connection-mode: direct

然后,这两CosmosClientCosmosAsyncClient者都可以在上下文中使用,并且可以自动连接,如以下示例所示:

class Demo {
@Autowired
private CosmosClient cosmosClient;

    @Override
    public void run() {
        User item = User.randomUser();
        CosmosContainer container = cosmosClient.getDatabase(databaseName).getContainer(containerName);
        container.createItem(item);
    }
}

示例

请参阅 GitHub 上的 azure-spring-boot-samples

资源移交

Spring 项目提供一个 Spring Resources 抽象来访问一些低级别资源。 项目提供接口,如 ResourceResourceLoaderResourcePatternResolver。 Spring Cloud Azure 为 Azure 存储服务实现这些接口,使你能够使用 Spring 编程模型与 Azure 存储 Blob 和文件共享进行交互。 Spring Cloud Azure 提供 spring-cloud-azure-starter-storage-blobspring-cloud-azure-starter-storage-file-share 自动配置 Azure 存储 Blob 和 Azure 存储文件共享。

下表列出了 Azure 存储相关库:

初学者 服务 说明
spring-cloud-azure-starter-storage-blob Azure 存储 Blob 允许在块 blob 中大规模存储和访问非结构化数据。
spring-cloud-azure-starter-storage-file-share Azure 存储文件共享 提供完全托管的云文件共享,让你能从任何位置通过行业标准服务器消息块 (SMB) 协议进行访问。

依赖项设置

<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-storage-blob</artifactId>
    </dependency>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-storage-file-share</artifactId>
    </dependency>
</dependencies>

spring-cloud-azure-starter-storage-blob仅当使用 Azure 存储 Blob 时,才需要依赖项。

spring-cloud-azure-starter-storage-file-share仅当使用 Azure 存储文件共享时,才需要依赖项。

提示

我们还提供 spring-cloud-azure-starter-storage 支持存储的所有功能。 如果选择使用它, spring.cloud.azure.storage.enable 则为要配置的属性,默认值为 true。 然后 spring.cloud.azure.storage.<storage-service>.enable ,可以使用此选项禁用不需要的服务。

配置

注意

如果使用安全主体通过 Azure Active Directory 进行身份验证和授权来访问 Azure 资源,请确保已授予安全主体访问 Azure 资源的足够权限。 有关详细信息,请参阅 使用 Azure Active Directory 授权访问

下表列出了可配置 spring-cloud-azure-starter-storage-blob的属性:

properties 默认 说明
spring.cloud.azure.storage.blob.enabled 一个值,该值指示是否启用了Azure Blob 存储服务。
spring.cloud.azure.storage.blob.endpoint 要连接到Azure Blob 存储的 URI。
spring.cloud.azure.storage.blob.account-key 要连接到Azure Blob 存储的私钥。
spring.cloud.azure.storage.blob.account-name Azure 存储帐户名称。

下表列出了可配置 spring-cloud-azure-starter-storage-file-share的属性:

properties 默认 说明
spring.cloud.azure.storage.fileshare.enabled 一个值,该值指示是否启用 Azure 文件存储服务。
spring.cloud.azure.storage.fileshare.endpoint 连接到 Azure 文件存储的 URI。
spring.cloud.azure.storage.fileshare.account-key 用于连接到 Azure 文件存储的私钥。
spring.cloud.azure.storage.fileshare.account-name Azure 存储文件共享帐户名称。

基本用法

将以下属性添加到 application.yml 文件:

spring:
  cloud:
    azure:
      storage:
        blob:
          account-name: ${STORAGE_ACCOUNT_NAME}
          account-key: ${STORAGE_ACCOUNT_KEY}
          endpoint: ${STORAGE_BLOB_ENDPOINT}
        fileshare:
          account-name: ${STORAGE_ACCOUNT_NAME}
          account-key: ${STORAGE_ACCOUNT_KEY}
          endpoint:  ${STORAGE_FILESHARE_ENDPOINT}

获取资源

获取资源 @Value

可以使用批注 @Value("azure-blob://[your-container-name]/[your-blob-name]") 来自动连接 Blob 资源,如以下示例所示:

@Value("azure-blob://[your-container-name]/[your-blob-name]")
private Resource storageBlobResource;

可以使用批注 @Value("azure-file://[your-fileshare-name]/[your-file-name]") 自动连接文件资源,如以下示例所示:

@Value("azure-file://[your-fileshare-name]/[your-file-name]")
private Resource storageFileResource;
使用 ResourceLoader 获取资源
@Autowired
private ResourceLoader resourceLoader;
...
// Get a BlobResource.
Resource storageBlobResource = resourceLoader.getResource("azure-blob://[your-container-name]/[your-blob-name]");

// Get a FileResource.
Resource storageFileResource = resourceLoader.getResource("azure-file://[your-fileshare-name]/[your-file-name]");
通过搜索模式获取资源

可以使用实现类 ResourcePatternResolver 搜索资源。 用于 AzureStorageBlobProtocolResolver 搜索 blob 资源和 AzureStorageFileProtocolResolver 搜索 file 资源。

  • 对于模式搜索, searchPattern 应从 azure-blob://azure-file://开始。 例如, azure-blob://**/** 表示列出所有容器中的所有 Blob,以及 azure-blob://demo-container/** 列出容器中的所有 demo-container Blob,包括任何子文件夹。

  • 对于位置搜索,searchLocation应以或azure-file://剩余文件路径开头azure-blob://,否则将引发异常。

@Autowired
private AzureStorageBlobProtocolResolver azureStorageBlobProtocolResolver;

@Autowired
private AzureStorageFileProtocolResolver azureStorageFileProtocolResolver;

// Get all text blobs.
Resource[] blobTextResources = azureStorageBlobProtocolResolver.getResources("azure-blob://[container-pattern]/*.txt");

// Get all text files.
Resource[] fileTextResources = azureStorageFileProtocolResolver.getResources("azure-file://[fileshare-pattern]/*.txt");

使用资源进行处理

从特定资源下载数据

可以使用以下Resource方法从 Azure 存储 Blob 或文件共享getInputStream()下载资源。

@Value("azure-blob://[your-container-name]/[your-blob-name]")
private Resource storageBlobResource;

@Value("azure-file://[your-fileshare-name]/[your-file-name]")
private Resource storageFileResource;

//...

// Download data as a stream from a blob resource.
InputStream inputblobStream = storageBlobResource.getInputStream();

// Download data as a stream from a file resource.
InputStream inputfileStream = storageFileResource.getInputStream();
将数据上传到特定资源

可以通过将 Spring Resource 强制转换为 WritableResourceAzure Blob 或文件存储,将资源上传到 Azure Blob 或文件存储,如以下示例所示:

@Value("azure-blob://[your-container-name]/[your-blob-name]")
private Resource storageBlobResource;

@Value("azure-file://[your-fileshare-name]/[your-file-name]")
private Resource storageFileResource;

String data = "sampledata";

// Upload string data to a blob.
try (OutputStream blobos = ((WritableResource) this.storageBlobResource).getOutputStream()) {
    blobos.write(data.getBytes());
}

// Upload string data to a file.
try (OutputStream fileos = ((WritableResource) this.storageFileResource).getOutputStream()) {
    fileos.write(data.getBytes());
}

多部分上传

大于 4 MiB 的文件将并行上传到 Azure 存储。

示例

请参阅 GitHub 上的 storage-blob-samplestorage-file-sample

机密管理

Spring Cloud Azure 构造PropertySource,用于保存存储在 Azure 密钥保管库 机密中的机密。

依赖项设置

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-keyvault-secrets</artifactId>
</dependency>

提示

我们还提供支持spring-cloud-azure-starter-keyvault密钥保管库的所有功能。 如果选择使用它, spring.cloud.azure.keyvault.enable 则为要配置的属性,默认值为 true。 然后 spring.cloud.azure.keyvault.<keyvault-service>.enable ,可以使用此选项禁用不需要的服务。

基本用法

如果要通过 client-id 以下 client-secret属性进行身份验证,则需要以下属性:

Configuration Properties

spring:
  cloud:
    azure:
      keyvault:
        secret:
          property-sources:
            - name: key-vault-property-souece-1
              endpoint: ${ENDPOINT_1}
            - name: key-vault-property-souece-2
              endpoint: ${ENDPOINT_2}

Java 代码

@SpringBootApplication
public class SampleApplication implements CommandLineRunner {

    @Value("${sampleProperty1}")
    private String sampleProperty1;
    @Value("${sampleProperty2}")
    private String sampleProperty2;
    @Value("${samplePropertyInMultipleKeyVault}")
    private String samplePropertyInMultipleKeyVault;

    public static void main(String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }

    public void run(String[] args) {
        System.out.println("sampleProperty1: " + sampleProperty1);
        System.out.println("sampleProperty2: " + sampleProperty2);
        System.out.println("samplePropertyInMultipleKeyVault: " + samplePropertyInMultipleKeyVault);
    }
}

高级用法

属性名称中的特殊字符

密钥保管库机密名称仅支持 中的[0-9a-zA-Z-]字符。 有关详细信息,请参阅 Azure 密钥保管库密钥、机密和证书Vault 名称和对象名称部分。 如果属性名称包含其他字符,可以使用以下各节中所述的解决方法。

- 机密名称中使用而不是 . 在机密名称中使用

. 机密名称不支持。 如果应用程序具有包含.的属性名称,例如spring.datasource.url,请在 Azure 密钥保管库中保存机密时替换为.-该名称。 例如,保存在 spring-datasource-url Azure 密钥保管库中。 在应用程序中,仍可用于 spring.datasource.url 检索属性值。

注意

此方法不能满足如下 spring.datasource-url要求。 保存spring-datasource-url密钥保管库时,仅spring.datasource.url支持检索spring-datasource-url属性值,但spring.datasource-url不受支持。 若要处理这种情况,请参阅 “使用属性占位符” 部分。

使用属性占位符

例如,假设在 application.properties 文件中设置此属性:

property.with.special.character__=${propertyWithoutSpecialCharacter}

应用程序将获取 propertyWithoutSpecialCharacter 密钥名称并将其值分配给 property.with.special.character__

区分大小写

若要启用区分大小写模式,可以设置以下属性:

spring.cloud.azure.keyvault.secret.property-sources[].case-sensitive=true

不检索密钥保管库中的所有机密

如果在密钥保管库中存储了 1000 个机密,并且只想使用其中 3 个机密。 可以按以下方式 spring.cloud.azure.keyvault.secret.property-sources[].secret-keys列出 3 个机密名称。

设置刷新间隔

默认情况下,机密 KeyVaultPropertySource 将每隔 30 分钟刷新一次。 可以按 spring.cloud.azure.keyvault.secret.property-sources[].refresh-interval. 配置时间。 例如: spring.cloud.azure.keyvault.secret.property-sources[].refresh-interval=60m 表示每隔 60 分钟刷新一次。 设置为 0 禁用自动刷新。

PropertySource 优先级

如果多个 PropertySources 中存在键,则优先级将生效。

  • 如果 PropertySource 列表中没有 SystemEnvironmentPropertySource ,则 KeyVaultPropertySource 采用最高优先级。
  • 如果 PropertySource 列表中存在 SystemEnvironmentPropertySource ,则 SystemEnvironmentPropertySource 优先级高于 KeyVaultPropertySource。 这意味着可以使用环境变量替代应用程序中的密钥保管库机密值。
  • 如果 PropertySource 列表中有多个 KeyVaultPropertySource,则定义顺序为优先级顺序。 以以上示例为例, key-vault-property-souece-1 优先级高于 key-vault-property-souece-2

所有可配置属性

properties 默认值 说明
spring.cloud.azure.keyvault.secret.property-enabled 是否启用密钥保管库属性源。
spring.cloud.azure.keyvault.secret.property-sources[].name 此属性源的名称。
spring.cloud.azure.keyvault.secret.property-sources[].endpoint Azure 密钥保管库终结点。
spring.cloud.azure.keyvault.secret.property-sources[].case-sensitive false 密钥是否区分大小写。
spring.cloud.azure.keyvault.secret.property-sources[].secret-keys 此属性源支持的密钥。 如果缺少此属性,则检索所有键。
spring.cloud.azure.keyvault.secret.property-sources[].refresh-interval 30m 刷新所有密钥保管库机密的时间间隔。
spring.cloud.azure.keyvault.secret.property-sources[].service-version 发出 API 请求时使用的机密服务版本。
spring.cloud.azure.keyvault.secret.property-sources[].client 客户端相关属性。
spring.cloud.azure.keyvault.secret.property-sources[].credential 凭据相关属性。
spring.cloud.azure.keyvault.secret.property-sources[].profile 配置文件相关属性。
spring.cloud.azure.keyvault.secret.property-sources[].proxy 代理相关属性。
spring.cloud.azure.keyvault.secret.property-sources[].retry 重试相关属性。
  • 请参阅使用 Azure Active Directory 授权访问,确保已向安全主体授予访问 Azure 密钥保管库机密所需的足够权限。
  • 如果未在中spring.cloud.azure.keyvault.secret.property-sources[].xxxspring.cloud.azure.xxx配置公共属性(例如clientcredentialprofile、)proxyretry将使用该属性。 请参阅 Spring Cloud Azure 配置 ,获取有关这些常见属性的详细信息。
  • 请参阅 配置属性列表 ,获取有关嵌套属性的详细信息。

示例

请参阅 GitHub 上的 spring-cloud-azure-starter-keyvault-secrets 示例

Spring Data 支持

Spring Data Cosmos DB 支持

Azure Cosmos DB 是一种全球分布式数据库服务,可让开发人员使用各种标准 API(例如 SQL、MongoDB、Graph 和 Azure 表存储)处理数据。

依赖项设置

<dependency>
   <groupId>com.azure.spring</groupId>
   <artifactId>spring-cloud-azure-starter-data-cosmos</artifactId>
</dependency>

配置

注意

如果使用安全主体通过 Azure Active Directory 进行身份验证和授权来访问 Azure 资源,请确保已授予安全主体访问 Azure 资源的足够权限。 有关详细信息,请参阅 使用 Azure Active Directory 授权访问

下表列出了可配置 spring-cloud-azure-starter-data-cosmos的属性:

properties 说明
spring.cloud.azure.cosmos.enabled 一个值,该值指示是否启用了 Azure Cosmos 服务。 默认值为 true
spring.cloud.azure.cosmos.database Cosmos DB 数据库 ID。
spring.cloud.azure.cosmos.endpoint 用于连接 Cosmos DB 的 URI。
spring.cloud.azure.cosmos.key 用于连接 Cosmos DB 的 PrivateKey。
spring.cloud.azure.cosmos.credential.client-certificate-password 证书文件的密码。
spring.cloud.azure.cosmos.credential.client-certificate-path 使用 Azure 执行服务主体身份验证时要使用的 PEM 证书文件的路径。
spring.cloud.azure.cosmos.credential.client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。
spring.cloud.azure.cosmos.credential.client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。
spring.cloud.azure.cosmos.credential.managed-identity-enabled 是否启用托管标识。 默认值是 false秒。
spring.cloud.azure.cosmos.credential.password 在 Azure 中执行用户名/密码身份验证时要使用的密码。
spring.cloud.azure.cosmos.credential.username 在 Azure 中执行用户名/密码身份验证时要使用的用户名。
spring.cloud.azure.cosmos.populate-query-metrics 一个值,该值指示是否填充诊断字符串和查询指标。 默认值是 false秒。
spring.cloud.azure.cosmos.consistency-level Azure Cosmos DB 的 一致性级别

关键概念

以下列表显示了 Spring Data 支持的关键概念:

  • Spring Data CrudRepository ,并提供 ReactiveCrudRepository以下基本 CRUD 功能:

    • 保存
    • findAll
    • findOne by ID
    • deleteAll
    • delete by ID
    • delete entity
  • Spring Data @Id 批注。 可通过两种方法将域类中的字段映射到 id Azure Cosmos DB 文档:

    • 使用 . 对域类中的字段进行 @Id批注。 此字段将映射到 Cosmos DB 中的文档 id
    • 将此字段的名称设置为 id。 此字段将映射到 Cosmos DB 中的文档 id

    注意

    如果应用这两种方式,批 @Id 注的优先级更高。

  • 自定义集合名称。 默认情况下,集合名称将是用户域类的类名。 若要对其进行自定义,请将批注 @Document(collection="myCustomCollectionName") 添加到域类,即全部。

  • 支持 Azure Cosmos DB 分区。 若要将域类的字段指定为分区键字段,请使用它 @PartitionKey进行批注。 执行 CRUD 操作时,请指定分区值。 有关更多示例,请参阅 GitHub 上的 AddressRepositoryIT.java

  • 支持 Spring Data 自定义查询 查找操作。

  • 支持 spring-boot-starter-data-rest

  • 支持域类中的列表和嵌套类型。

基本用法

使用私钥访问 Cosmos DB

使用主键连接 Cosmos DB spring-cloud-azure-starter-data-cosmos 的最简单方法。 添加以下属性:

spring:
  cloud:
    azure:
      cosmos:
        key: ${AZURE_COSMOS_KEY}
        endpoint: ${AZURE_COSMOS_ENDPOINT}
        database: ${AZURE_COSMOS_DATABASE}
定义实体

将实体定义为 Cosmos DB 中的文档,如以下示例所示:

@Container(containerName = "mycollection")
public class User {
    @Id
    private String id;
    private String firstName;
    @PartitionKey
    private String lastName;
    private String address;

    public User() {
    }

    public User(String id, String firstName, String lastName, String address) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = address;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return String.format("%s %s, %s", firstName, lastName, address);
    }
}

id 字段将用作 Azure Cosmos DB 中的文档 id 。 或者,可以批注任何字段 @Id 以将其映射到文档 id

批注 @Container(containerName = "mycollection") 用于在 Azure Cosmos DB 中指定文档的集合名称。

创建存储库

若要创建存储库,请 ReactiveCosmosRepository 扩展提供 Spring Data 存储库支持的接口。

@Repository
public interface UserRepository extends ReactiveCosmosRepository<User, String> {
    Flux<User> findByFirstName(String firstName);
}

目前,该 ReactiveCosmosRepository 接口提供基本保存、删除和查找操作。 稍后将支持更多操作。

创建应用程序类

以下示例创建包含所有组件的应用程序类:

@SpringBootApplication
public class CosmosSampleApplication implements CommandLineRunner {

private static final Logger LOGGER = LoggerFactory.getLogger(CosmosSampleApplication.class);

    @Autowired
    private UserRepository repository;

    @Autowired
    private CosmosProperties properties;

    public static void main(String[] args) {
        SpringApplication.run(CosmosSampleApplication.class, args);
    }

    public void run(String... var1) {
        final User testUser = new User("testId", "testFirstName",
                "testLastName", "test address line one");

        // Save the User class to Azure Cosmos DB database.
        final Mono<User> saveUserMono = repository.save(testUser);

        final Flux<User> firstNameUserFlux = repository.findByFirstName("testFirstName");

        //  Nothing happens until we subscribe to these Monos.
        //  findById will not return the user as user isn't present.
        final Mono<User> findByIdMono = repository.findById(testUser.getId());
        final User findByIdUser = findByIdMono.block();
        Assert.isNull(findByIdUser, "User must be null");

        final User savedUser = saveUserMono.block();
        Assert.state(savedUser != null, "Saved user must not be null");
        Assert.state(savedUser.getFirstName().equals(testUser.getFirstName()),
                "Saved user first name doesn't match");

        firstNameUserFlux.collectList().block();

        final Optional<User> optionalUserResult = repository.findById(testUser.getId()).blockOptional();
        Assert.isTrue(optionalUserResult.isPresent(), "Cannot find user.");

        final User result = optionalUserResult.get();
        Assert.state(result.getFirstName().equals(testUser.getFirstName()),
                "query result firstName doesn't match!");
        Assert.state(result.getLastName().equals(testUser.getLastName()),
                "query result lastName doesn't match!");
        LOGGER.info("findOne in User collection get result: {}", result.toString());

    }

    @PostConstruct
    public void setup() {
        // For this example, remove all of the existing records.
        this.repository.deleteAll().block();
    }
}

此示例包含自动连接 UserRepository 接口,以支持保存、删除和查找操作。

示例

请参阅 GitHub 上的 azure-spring-boot-samples

除了使用 spring-cloud-azure-starter-data-cosmos 库,还可以直接将库用于 azure-spring-data-cosmos 更复杂的方案。 有关详细信息,请参阅 适用于 Azure Cosmos DB 的 Spring Data

Spring Security 支持

使用 Azure Active Directory 的 Spring Security

生成 Web 应用程序时,标识和访问管理始终是基础部分。

Azure 提供了一个用于实现应用程序开发旅程民主化的绝佳平台,因为它不仅提供云基础标识服务,而且还与 Azure 生态系统的其余部分进行深度集成。

通过强大的抽象和可扩展接口,Spring Security 可以轻松保护基于 Spring 的应用程序。 但是,与 Spring 框架一样强大,它不是针对特定标识提供者定制的。

提供 spring-cloud-azure-starter-active-directory 将 Web 应用程序连接到 Azure Active Directory (Azure AD) 租户,并使用 Azure AD 保护资源服务器的最佳方法。 它使用 Oauth 2.0 协议来保护 Web 应用程序和资源服务器。

访问 Web 应用程序

此方案使用 OAuth 2.0 授权代码授予 流以使用 Microsoft 帐户登录用户。

系统关系图

独立 Web 应用程序的系统关系图。

在 Azure 中创建所需的资源
  1. 阅读有关向Microsoft 标识平台注册应用程序的 MS 文档

  2. 创建应用注册。 获取 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET

  3. 设置为 redirect URIAPPLICATION_BASE_URI/login/oauth2/code/,例如 http://localhost:8080/login/oauth2/code/。 尾部 / 是必需的。

添加必需的依赖项
<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
</dependencies>
添加所需属性
spring:
  cloud:
    azure:
      active-directory:
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-secret: ${AZURE_CLIENT_SECRET}

现在,通过浏览器启动应用程序并访问应用程序,然后会重定向到 Microsoft 登录页。

高级用法
添加额外的安全配置
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class AadOAuth2LoginSecurityConfig extends AadWebSecurityConfigurerAdapter {

        /**
         * Add configuration logic as needed.
         */
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            super.configure(http);
            http.authorizeRequests()
                    .anyRequest().authenticated();
            // Do some custom configuration
        }
    }
按应用角色授权访问
  1. 在 Azure 中创建所需的资源

注意

如果要使用基于应用角色的访问控制,则不能在 role 声明中放置组名称。 参考:[配置组可选声明] (/azure/active-directory/develop/active-directory-optional-claims#configuring-groups-optional-claims) 。

  1. 保护特定方法。

    class Demo {
        @GetMapping("Admin")
        @ResponseBody
        @PreAuthorize("hasAuthority('APPROLE_Admin')")
        public String admin() {
            return "Admin message";
        }
    }
按组名称或组 ID 授权访问
  1. 添加相关的配置属性。

        spring:
          cloud:
            azure:
              active-directory:
                user-group:
                  allowed-group-names: group1_name_1, group2_name_2
                  # 1. If allowed-group-ids == all, then all group ID will take effect.
                  # 2. If "all" is used, we should not configure other group ids.
                  # 3. "all" is only supported for allowed-group-ids, not supported for allowed-group-names.
                  allowed-group-ids: group_id_1, group_id_2
    
  2. 保护特定方法。

        @Controller
        public class RoleController {
            @GetMapping("group1")
            @ResponseBody
            @PreAuthorize("hasRole('ROLE_group1')")
            public String group1() {
                return "group1 message";
            }
    
            @GetMapping("group2")
            @ResponseBody
            @PreAuthorize("hasRole('ROLE_group2')")
            public String group2() {
                return "group2 message";
            }
    
            @GetMapping("group1Id")
            @ResponseBody
            @PreAuthorize("hasRole('ROLE_<group1-id>')")
            public String group1Id() {
                return "group1Id message";
            }
    
            @GetMapping("group2Id")
            @ResponseBody
            @PreAuthorize("hasRole('ROLE_<group2-id>')")
            public String group2Id() {
                return "group2Id message";
            }
        }
    
使用国家 Azure 而不是全局 Azure

除了全局 Azure 云之外,Azure Active Directory 现在部署在以下国家云中:

  • Azure Government

  • Azure 中国世纪互联

  • Azure 德国

下面是想要使用 Azure 中国世纪互联的示例。

spring:
  cloud:
    azure:
      active-directory:
        base-uri: https://login.partner.microsoftonline.cn
        graph-base-uri: https://microsoftgraph.chinacloudapi.cn

可以参考这些 MS 文档,从 有关国家云部署的 MS 文档获取详细信息。

配置重定向 URI 模板

开发人员可以自定义重定向 URI。

重定向 URI 的系统关系图。

  1. 在 application.yml 中添加 redirect-uri-template 属性。

        spring:
          cloud:
            azure:
              active-directory:
                redirect-uri-template: ${REDIRECT-URI-TEMPLATE}
    
  2. 更新Azure 门户中的重定向 URI。

    配置重定向 URI 模板。

  3. 更新 WebSecurityConfigurerAdapter

设置 redirect-uri-template 后,需要更新 WebSecurityConfigurerAdapter

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2LoginSecurityConfig extends AadWebSecurityConfigurerAdapter {
    /**
     * Add configuration logic as needed.
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.oauth2Login()
                .loginProcessingUrl("${REDIRECT-URI-TEMPLATE}")
                .and()
            .authorizeRequests()
                .anyRequest().authenticated();
    }
}
通过代理连接到 Azure AD

若要通过代理连接 Azure AD,请提供类似于 RestTemplateCustomizer 以下示例所示的豆类:

@Configuration
class DemoConfiguration {
    @Bean
    public RestTemplateCustomizer proxyRestTemplateCustomizer() {
        return (RestTemplate restTemplate) -> {
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_SERVER_HOST, PROXY_SERVER_PORT));
            SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
            requestFactory.setProxy(proxy);
            restTemplate.setRequestFactory(requestFactory);
        };
    }
}
示例

示例项目: aad-web-application

访问资源服务器的 Web 应用程序

系统关系图

用于访问资源服务器的 Web 应用程序的系统关系图。

在 Azure 中创建所需的资源
  1. 阅读有关向Microsoft 标识平台注册应用程序的 MS 文档

  2. 创建应用注册。 获取 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET

  3. 设置为 redirect URIAPPLICATION_BASE_URI/login/oauth2/code/,例如 http://localhost:8080/login/oauth2/code/。 尾部 / 是必需的。

添加必需的依赖项
<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
</dependencies>
添加所需属性
spring:
  cloud:
    azure:
      active-directory:
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-secret: ${AZURE_CLIENT_SECRET}
        authorization-clients:
          graph:
            scopes: https://graph.microsoft.com/Analytics.Read, email

此处为 graph 名称 OAuth2AuthorizedClientscopes 表示登录时需要同意的范围。

在应用程序中使用 OAuth2AuthorizedClient
public class Demo {
    @GetMapping("/graph")
    @ResponseBody
    public String graph(
    @RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graphClient) {
        // toJsonString() is just a demo.
        // oAuth2AuthorizedClient contains access_token. We can use this access_token to access resource server.
        return toJsonString(graphClient);
    }
}

现在,通过浏览器启动应用程序并访问应用程序,然后会重定向到 Microsoft 登录页。

高级用法
客户端凭据流

默认 流是授权代码流,如果要使用 客户端凭据流,可以按如下所示进行配置:

spring:
  cloud:
    azure:
      active-directory:
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-secret: ${AZURE_CLIENT_SECRET}
        authorization-clients:
          graph:
            authorization-grant-type: client_credentials # Change type to client_credentials
            scopes: https://graph.microsoft.com/Analytics.Read, email
访问多个资源服务器

在一个 Web 应用程序中,可以通过配置如下所示来访问多个资源服务器:

spring:
  cloud:
    azure:
      active-directory:
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-secret: ${AZURE_CLIENT_SECRET}
        authorization-clients:
          resource-server-1:
            scopes: # Scopes for resource-server-1
          resource-server-2:
            scopes: # Scopes for resource-server-2

然后,可以在如下所示的应用程序中使用 OAuth2AuthorizedClient

public class Demo {
    @GetMapping("/resource-server-1")
    @ResponseBody
    public String graph(
    @RegisteredOAuth2AuthorizedClient("resource-server-1") OAuth2AuthorizedClient client) {
        return callResourceServer1(client);
    }

    @GetMapping("/resource-server-2")
    @ResponseBody
    public String graph(
    @RegisteredOAuth2AuthorizedClient("resource-server-2") OAuth2AuthorizedClient client) {
        return callResourceServer2(client);
    }
}

在前面的示例中,无论属于 resource-server-1 或 resource-server-2,客户首次登录时,都会同意所有范围。 如果不想让客户同意所有范围,可以执行以下操作:

spring:
  cloud:
    azure:
      active-directory:
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-secret: ${AZURE_CLIENT_SECRET}
        authorization-clients:
          resource-server-1:
            scopes: # Scopes for resource-server-1
          resource-server-2:
            on-demand: true  # means incremental consent
            scopes: # Scopes for resource-server-2
示例

示例项目: aad-web-application

访问资源服务器

此方案不支持登录,只需通过验证访问令牌来保护服务器。 如果访问令牌有效,则服务器将为请求提供服务。

系统关系图

独立资源服务器使用情况的系统关系图。

在 Azure 中创建所需的资源
  1. 阅读有关向Microsoft 标识平台注册应用程序的 MS 文档

  2. 创建应用注册。 获取 AZURE_CLIENT_ID

  3. 阅读 有关配置应用程序以公开 Web API 的 MS 文档

  4. Expose a web API with a scope named Scope-1.

添加必需的依赖项
<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
</dependencies>
添加所需属性
spring:
  cloud:
    azure:
      active-directory:
        credential:
          client-id: ${AZURE_CLIENT_ID}

现在启动应用程序并访问应用程序的 Web API。

  1. 你将获得 401,而无需访问令牌。

  2. 使用访问令牌访问应用程序,将验证访问令牌中的以下声明:

    • iss:访问令牌必须由 Azure AD 颁发。

    • nbf:当前时间不能之前 nbf

    • exp:当前时间不能之后 exp

    • aud:如果 spring.cloud.azure.active-directory.credential.client-idspring.cloud.azure.active-directory.credential.app-id-uri 已配置,则受众必须等于配置的 client-idapp-id-uri。 如果未配置 2 个属性,则不会验证此声明。

有关Microsoft 标识平台访问令牌的 MS 文档,获取有关访问令牌的详细信息。

高级用法
添加额外的安全配置
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadOAuth2ResourceServerSecurityConfig extends AadResourceServerWebSecurityConfigurerAdapter {
    /**
     * Add configuration logic as needed.
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests((requests) -> requests.anyRequest().authenticated());
    }
}
按范围验证权限
  1. 在 Azure 中创建所需的资源

  2. 保护特定方法。

    class Demo {
        @GetMapping("scope1")
        @ResponseBody
        @PreAuthorize("hasAuthority('SCOPE_Scope1')")
        public String scope1() {
            return "Congratulations, you can access `scope1` endpoint.";
        }
    }

通过执行此操作,访问终结点时,将验证访问 /scope1 令牌中的以下声明:

  • scp:该值必须包含 Scope1
按应用角色验证权限
  1. 在 Azure 中创建所需的资源

  2. 保护特定方法。

    class Demo {
        @GetMapping("app-role1")
        @ResponseBody
        @PreAuthorize("hasAuthority('APPROLE_AppRole1')")
        public String appRole1() {
            return "Congratulations, you can access `app-role1` endpoint.";
        }
    }

通过执行此操作,访问终结点时,将验证访问 /app-role1 令牌中的以下声明:

  • roles:该值必须包含 AppRole1
使用 JWT 客户端身份验证

若要使用 JSON Web 令牌 (JWT) 进行客户端身份验证,请执行以下步骤:

  1. 请参阅Microsoft 标识平台应用程序身份验证证书凭据的Microsoft 标识平台部分注册证书
  2. .pem 证书上传到Azure 门户中注册的应用程序。
  3. 配置证书路径和密码 。PFX.P12 证书。
  4. 将属性 spring.cloud.azure.active-directory.authorization-clients.azure.client-authentication-method=private_key_jwt 配置添加到要通过 JWT 客户端身份验证进行身份验证的客户端。

以下示例配置文件适用于 Web 应用程序方案。 证书信息在全局属性中配置。

spring:
  cloud:
    azure:
      credential:
        client-id: ${AZURE_CLIENT_ID}
        client-certificate-path: ${AZURE_CERTIFICATE_PATH}
        client-certificate-password: ${AZURE_CERTIFICATE_PASSWORD}
      profile:
        tenant-id: ${AZURE_TENANT_ID}
      active-directory:
        enabled: true
        user-group:
          allowed-group-names: group1,group2
          allowed-group-ids: <group1-id>,<group2-id>
        post-logout-redirect-uri: http://localhost:8080
        authorization-clients:
          azure:
            client-authentication-method: private_key_jwt
          arm:
            client-authentication-method: private_key_jwt
            on-demand: true
            scopes: https://management.core.windows.net/user_impersonation
          graph:
            client-authentication-method: private_key_jwt
            scopes:
              - https://graph.microsoft.com/User.Read
              - https://graph.microsoft.com/Directory.Read.All
          webapiA:
            client-authentication-method: private_key_jwt
            scopes:
              - ${WEB_API_A_APP_ID_URL}/Obo.WebApiA.ExampleScope
          webapiB:
            client-authentication-method: private_key_jwt
            scopes:
              - ${WEB_API_B_APP_ID_URL}/.default
            authorization-grant-type: client_credentials

还可以在服务属性中 active-directory 配置证书信息,如以下示例所示:

spring:
  cloud:
    azure:
      active-directory:
        enabled: true
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-certificate-path: ${AZURE_CERTIFICATE_PATH}
          client-certificate-password: ${AZURE_CERTIFICATE_PASSWORD}
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        user-group:
          allowed-group-names: group1,group2
          allowed-group-ids: <group1-id>,<group2-id>
        post-logout-redirect-uri: http://localhost:8080
        authorization-clients:
          azure:
            client-authentication-method: private_key_jwt
          arm:
            client-authentication-method: private_key_jwt
            on-demand: true
            scopes: https://management.core.windows.net/user_impersonation
          graph:
            client-authentication-method: private_key_jwt
            scopes:
              - https://graph.microsoft.com/User.Read
              - https://graph.microsoft.com/Directory.Read.All
          webapiA:
            client-authentication-method: private_key_jwt
            scopes:
              - ${WEB_API_A_APP_ID_URL}/Obo.WebApiA.ExampleScope
          webapiB:
            client-authentication-method: private_key_jwt
            scopes:
              - ${WEB_API_B_APP_ID_URL}/.default
            authorization-grant-type: client_credentials
通过代理连接到 Azure AD

若要通过代理连接 Azure AD,请提供 RestTemplateCustomizer bean。 有关详细信息,请参阅 “通过代理连接到 Azure AD ”部分。

示例

示例项目: aad-resource-server

访问其他资源服务器的资源服务器

系统关系图

访问其他资源服务器的资源服务器的系统关系图。

在 Azure 中创建所需的资源
  1. 阅读有关向Microsoft 标识平台注册应用程序的 MS 文档

  2. 创建应用注册。 获取 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET

添加必需的依赖项
<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
</dependencies>
添加所需属性
spring:
  cloud:
    azure:
      active-directory:
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-secret: ${AZURE_CLIENT_SECRET}
        authorization-clients:
          graph:
            scopes:
              - https://graph.microsoft.com/User.Read
在应用程序中使用 OAuth2AuthorizedClient
public class SampleController {
    @GetMapping("call-graph")
    public String callGraph(@RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graph) {
        return callMicrosoftGraphMeEndpoint(graph);
    }
}
示例

示例项目: aad-resource-server-obo

在一个应用程序中的 Web 应用程序和资源服务器

在 Azure 中创建所需的资源
  1. 阅读有关向Microsoft 标识平台注册应用程序的 MS 文档

  2. 创建应用注册。 获取 AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRET

添加必需的依赖项
<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-active-directory</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
</dependencies>
添加所需属性

将属性 spring.cloud.azure.active-directory.application-type 设置为 web_application_and_resource_server,并为每个授权客户端指定授权类型。

spring:
  cloud:
    azure:
      active-directory:
        profile:
          tenant-id: ${AZURE_TENANT_ID}
        credential:
          client-id: ${AZURE_CLIENT_ID}
          client-secret: ${AZURE_CLIENT_SECRET}
        app-id-uri: ${WEB_API_ID_URI}
        application-type: web_application_and_resource_server  # This is required.
        authorization-clients:
          graph:
            authorizationGrantType: authorization_code # This is required.
            scopes:
              - https://graph.microsoft.com/User.Read
              - https://graph.microsoft.com/Directory.Read.All
定义 securityConfigurationAdapter

配置多个 HttpSecurity 实例, AadWebApplicationAndResourceServerConfig 包含两个资源服务器和 Web 应用程序的安全配置。

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AadWebApplicationAndResourceServerConfig {

    @Order(1)
    @Configuration
    public static class ApiWebSecurityConfigurationAdapter extends AadResourceServerWebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            super.configure(http);
            // All the paths that match `/api/**`(configurable) work as `Resource Server`, other paths work as `Web application`.
            http.antMatcher("/api/**")
                .authorizeRequests().anyRequest().authenticated();
        }
    }

    @Configuration
    public static class HtmlWebSecurityConfigurerAdapter extends AadWebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            super.configure(http);
            // @formatter:off
            http.authorizeRequests()
                    .antMatchers("/login").permitAll()
                    .anyRequest().authenticated();
            // @formatter:on
        }
    }
}

配置

spring-cloud-azure-starter-active-directory 的可配置属性:

名称 说明
spring.cloud.azure.active-directory.app-id-uri 可在id_token的“aud”声明中使用的应用 ID URI。
spring.cloud.azure.active-directory.application-type Azure AD 应用程序的类型。
spring.cloud.azure.active-directory.authenticate-additional-parameters 将其他参数添加到授权 URL。
spring.cloud.azure.active-directory.authorization-clients OAuth2 授权客户端。
spring.cloud.azure.active-directory.credential.client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。
spring.cloud.azure.active-directory.credential.client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。
spring.cloud.azure.active-directory.jwk-set-cache-lifespan 缓存的 JWK 在过期之前设置的生命周期,默认值为 5 分钟。
spring.cloud.azure.active-directory.jwk-set-cache-refresh-time 缓存的 JWK 设置的刷新时间在过期之前,默认值为 5 分钟。
spring.cloud.azure.active-directory.jwt-connect-timeout JWKSet 远程 URL 调用的连接超时。
spring.cloud.azure.active-directory.jwt-read-timeout JWKSet 远程 URL 调用的读取超时。
spring.cloud.azure.active-directory.jwt-size-limit JWKSet 远程 URL 调用的字节大小限制。
spring.cloud.azure.active-directory.post-logout-redirect-uri 注销后的重定向 URI。
spring.cloud.azure.active-directory.profile.cloud-type 要连接到的 Azure 云的名称。 支持的类型包括:AZURE、AZURE_CHINA、AZURE_GERMANY、AZURE_US_GOVERNMENT、OTHER。
spring.cloud.azure.active-directory.profile.environment Azure Active Directory 终结点的属性。
spring.cloud.azure.active-directory.profile.tenant-id Azure 租户 ID。
spring.cloud.azure.active-directory.redirect-uri-template 重定向终结点:授权服务器用于通过资源所有者用户代理将包含授权凭据的响应返回到客户端。 默认值是 {baseUrl}/login/oauth2/code/
spring.cloud.azure.active-directory.resource-server.claim-to-authority-prefix-map 配置将用于生成 GrantedAuthority 的声明以及 GrantedAuthority 的字符串值的前缀。 默认值为:“scp”-> “SCOPE_”、“roles”-> “APPROLE_”。
spring.cloud.azure.active-directory.resource-server.principal-claim-name 在 AuthenticatedPrincipal#getName 中配置访问令牌中返回的声明。 默认值为“sub”。
spring.cloud.azure.active-directory.session-stateless 如果 true 激活无状态身份验证筛选器 AadAppRoleStatlessAuthenticationFilter。 默认值为 false,这会激活 AadAuthenticationFilter。
spring.cloud.azure.active-directory.user-group.allowed-group-ids 组 ID 可用于构造 GrantedAuthority。
spring.cloud.azure.active-directory.user-group.allowed-group-names 组名称可用于构造 GrantedAuthority。
spring.cloud.azure.active-directory.user-group.use-transitive-members 如果为“true”,请使用“v1.0/me/transitiveMemberOf”获取成员。 否则,请使用“v1.0/me/memberOf”。 默认值是 false
spring.cloud.azure.active-directory.user-name-attribute 确定要作为主体名称的声明。

下面是有关如何使用这些属性的一些示例:

应用程序类型

可以从依赖项推断 THe 应用程序类型:spring-security-oauth2-client 或 spring-security-oauth2-resource-server。 如果推断的值不是所需的值,则可以指定应用程序类型。 下面是有关有效值和推断值的表:

spring-cloud-azure-starter-active-directory 的应用程序类型:

具有依赖项:spring-security-oauth2-client 具有依赖项:spring-security-oauth2-resource-server 应用程序类型的有效值 推断值
web_application web_application
resource_server resource_server
web_application, resource_server, resource_server_with_obo, web_application_and_resource_server resource_server_with_obo

使用 Azure Active Directory B2C 的 Spring Security

Azure Active Directory (Azure AD) B2C 是一项标识管理服务,用于自定义和控制客户在使用应用程序时的注册、登录和管理配置文件的方式。 有了 Azure AD B2C,就可以在执行这些操作的同时保护客户的标识。

依赖项设置

<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-active-directory-b2c</artifactId>
    </dependency>
</dependencies>

配置

spring-cloud-azure-starter-active-directory-b2c 的可配置属性:

名称 说明
spring.cloud.azure.active-directory.b2c.app-id-uri 可在令牌的“aud”声明中使用的应用 ID URI。
spring.cloud.azure.active-directory.b2c.authenticate-additional-parameters 身份验证的其他参数。
spring.cloud.azure.active-directory.b2c.authorization-clients 指定客户端配置。
spring.cloud.azure.active-directory.b2c.base-uri Azure AD B2C 终结点基 URI。
spring.cloud.azure.active-directory.b2c.credential Azure AD B2C 凭据信息。
spring.cloud.azure.active-directory.b2c.jwt-connect-timeout JWKSet 远程 URL 调用的连接超时。
spring.cloud.azure.active-directory.b2c.jwt-read-timeout JWKSet 远程 URL 调用的读取超时。
spring.cloud.azure.active-directory.b2c.jwt-size-limit JWKSet 远程 URL 调用的字节大小限制。
spring.cloud.azure.active-directory.b2c.login-flow 指定主登录流密钥。 默认值是 sign-up-or-sign-in
spring.cloud.azure.active-directory.b2c.logout-success-url 注销后重定向 URL。 默认值是 http://localhost:8080/login
spring.cloud.azure.active-directory.b2c.profile Azure AD B2C 配置文件信息。
spring.cloud.azure.active-directory.b2c.reply-url 获取授权代码后回复 URL。 默认值是 {baseUrl}/login/oauth2/code/
spring.cloud.azure.active-directory.b2c.user-flow 用户流。
spring.cloud.azure.active-directory.b2c.user-name-attribute-name 用户名属性名称。

有关完整配置,请查看 “附录”页

基本用法

Web 应用程序是任何基于 Web 的应用程序 ,允许用户使用 Azure AD 登录,而 资源服务器 在验证从 Azure AD 获取access_token后将接受或拒绝访问。 本指南介绍 4 种方案:

  1. 访问 Web 应用程序。

  2. 访问资源服务器的 Web 应用程序。

  3. 访问资源服务器。

  4. 访问其他资源服务器的资源服务器。

Web 应用程序与 Azure AD 和资源服务器的交互的系统关系图。

用法 1:访问 Web 应用程序

此方案使用 OAuth 2.0 授权代码授予 流,以使用 Azure AD B2C 用户登录用户。

  1. 从门户菜单中选择“Azure AD B2C”,单击“应用程序”,然后单击“添加”。

  2. 指定应用程序名称,我们调用它webapp,添加http://localhost:8080/login/oauth2/code/回复 URL,将应用程序 ID 记录为你的WEB_APP_AZURE_CLIENT_ID,然后单击“保存”。

  3. 从应用程序中选择“密钥”,单击“生成密钥”以生成 WEB_APP_AZURE_CLIENT_SECRET,然后单击“保存”。

  4. 选择左侧 的用户流 ,然后单击“ 新建用户流”。

  5. 选择“注册或登录”、“配置文件编辑”和“密码重置”,分别创建用户流。 指定用户流的“名称”和“用户特性和声明”,然后单击“创建”。

  6. 选择 API 权限“添加 MicrosoftAPI 权限>>”,选择“Microsoft Graph”,选择“委派的权限”,选中“offline_access”和“开放权限”,选择“添加”权限以完成该过程。

  7. 授予管理员对 Graph 权限的同意。

    Azure 门户显示应用的 API 权限屏幕的屏幕截图,其中突出显示了图形权限。

  8. pom.xml中添加以下依赖项。

    <dependencies>
        <dependency>
            <groupId>com.azure.spring</groupId>
            <artifactId>azure-spring-boot-starter-active-directory-b2c</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
    </dependencies>
    
  9. 使用前面创建的值在 application.yml 中添加属性,例如:

    spring:
      cloud:
        azure:
          active-directory:
            b2c:
              authenticate-additional-parameters:
                domain_hint: xxxxxxxxx         # optional
                login_hint: xxxxxxxxx          # optional
                prompt: [login,none,consent]   # optional
              base-uri: ${BASE_URI}
              credential:
                client-id: ${WEBAPP_AZURE_CLIENT_ID}
                client-secret: ${WEBAPP_AZURE_CLIENT_SECRET}
              login-flow: ${LOGIN_USER_FLOW_KEY}               # default to sign-up-or-sign-in, will look up the user-flows map with provided key.
              logout-success-url: ${LOGOUT_SUCCESS_URL}
              user-flows:
                ${YOUR_USER_FLOW_KEY}: ${USER_FLOW_NAME}
              user-name-attribute-name: ${USER_NAME_ATTRIBUTE_NAME}
    
  10. 编写 Java 代码。

    控制器代码可以引用以下内容:

    @Controller
    public class WebController {
    
        private void initializeModel(Model model, OAuth2AuthenticationToken token) {
            if (token != null) {
                final OAuth2User user = token.getPrincipal();
                model.addAllAttributes(user.getAttributes());
                model.addAttribute("grant_type", user.getAuthorities());
                model.addAttribute("name", user.getName());
            }
        }
    
        @GetMapping(value = { "/", "/home" })
        public String index(Model model, OAuth2AuthenticationToken token) {
            initializeModel(model, token);
            return "home";
        }
    }
    

    安全配置代码可以参考以下内容:

    @EnableWebSecurity
    public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        private final AadB2cOidcLoginConfigurer configurer;
    
        public WebSecurityConfiguration(AadB2cOidcLoginConfigurer configurer) {
            this.configurer == configurer;
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                .apply(configurer);
            // @formatter:off
        }
    }
    

    aad-b2c-web-application 示例复制home.html,并分别替换PROFILE_EDIT_USER_FLOWPASSWORD_RESET_USER_FLOW之前完成的用户流名称。

  11. 生成并测试应用

    让我们 Webapp 在端口 8080 上运行。

  12. 在 Maven 生成并启动该应用程序之后,请在 Web 浏览器中打开 http://localhost:8080/;系统会将你重定向到登录页。

  13. 单击与登录用户流的链接,应重定向 Azure AD B2C 以启动身份验证过程。

  14. 成功登录后,应从浏览器看到示例 home page

用法 2:访问资源服务器的 Web 应用程序

此方案基于 访问 Web 应用程序 方案,以允许应用程序访问其他资源,即 OAuth 2.0 客户端凭据授予 流。

  1. 从门户菜单中选择“Azure AD B2C”,单击“应用程序”,然后单击“添加”。

  2. 指定应用程序 名称,我们将调用它 webApiA,将 应用程序 ID 记录为你的 WEB_API_A_AZURE_CLIENT_ID 应用程序 ID,然后单击“ 保存”。

  3. 从应用程序中选择“密钥”,单击“生成密钥”以生成 WEB_API_A_AZURE_CLIENT_SECRET,然后单击“保存”。

  4. 选择左侧 公开 API ,然后单击 “设置 ”链接,将 应用程序 ID URI 记录为你的 WEB_API_A_APP_ID_URL,然后 保存

  5. 选择左侧的清单,然后将以下 json 段粘贴到appRoles数组中,将应用程序 ID URI 记录为你的,将应用角色的值记录为你的WEB_API_A_APP_ID_URLWEB_API_A_ROLE_VALUE,然后保存

    {
      "allowedMemberTypes": [
        "Application"
      ],
      "description": "WebApiA.SampleScope",
      "displayName": "WebApiA.SampleScope",
      "id": "04989db0-3efe-4db6-b716-ae378517d2b7",
      "isEnabled": true,
      "value": "WebApiA.SampleScope"
    }
    

    Azure 门户屏幕截图,其中显示了应用程序清单屏幕,其中突出显示了“appRoles”JSON。

  6. 选择 API 权限>“添加权限>”我的 API,选择“WebApiA 应用程序名称”,选择“应用程序权限”,选择“WebApiA.SampleScope”权限,选择“添加”权限以完成该过程。

  7. 授予 对 WebApiA 权限的管理员同意。

    显示应用程序 API 权限屏幕的Azure 门户屏幕截图。

  8. 根据 访问 Web 应用程序 方案添加以下依赖项。

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    
  9. 根据 访问 Web 应用程序 方案添加以下配置。

        spring:
          cloud:
            azure:
              active-directory:
                b2c:
                  base-uri: ${BASE_URI}             # Such as: https://xxxxb2c.b2clogin.com
                  profile:
                    tenant-id: ${AZURE_TENANT_ID}
                  authorization-clients:
                    ${RESOURCE_SERVER_A_NAME}:
                      authorization-grant-type: client_credentials
                      scopes: ${WEB_API_A_APP_ID_URL}/.default
    
  10. Webapp编写 Java 代码。

    控制器代码可以引用以下内容:

    class Demo {
        /**
         * Access to protected data from Webapp to WebApiA through client credential flow. The access token is obtained by webclient, or
         * <p>@RegisteredOAuth2AuthorizedClient("webApiA")</p>. In the end, these two approaches will be executed to
         * DefaultOAuth2AuthorizedClientManager#authorize method, get the access token.
         *
         * @return Respond to protected data from WebApi A.
         */
        @GetMapping("/webapp/webApiA")
        public String callWebApiA() {
            String body = webClient
                .get()
                .uri(LOCAL_WEB_API_A_SAMPLE_ENDPOINT)
                .attributes(clientRegistrationId("webApiA"))
                .retrieve()
                .bodyToMono(String.class)
                .block();
            LOGGER.info("Call callWebApiA(), request '/webApiA/sample' returned: {}", body);
            return "Request '/webApiA/sample'(WebApi A) returned a " + (body != null ? "success." : "failure.");
        }
    }
    

    安全配置代码与 访问 Web 应用程序 方案相同,添加另一个 bean webClient ,如下所示:

    public class SampleConfiguration {
        @Bean
        public WebClient webClient(OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager) {
            ServletOAuth2AuthorizedClientExchangeFilterFunction function =
                new ServletOAuth2AuthorizedClientExchangeFilterFunction(oAuth2AuthorizedClientManager);
            return WebClient.builder()
                            .apply(function.oauth2Configuration())
                            .build();
        }
    }
    
  11. 请参阅 访问资源服务器 部分以编写 WebApiA Java 代码。

  12. 生成并测试应用

    WebApiA分别Webapp在端口 80808081 上运行。 成功日志记录后,启动 WebappWebApiA 应用程序返回到主页,可以访问 http://localhost:8080/webapp/webApiA 获取 WebApiA 资源响应。

用法 3:访问资源服务器

此方案不支持登录。 只需通过验证访问令牌(如果有效)来保护服务器即可处理请求。

  1. 请参阅 使用情况 2:访问资源服务器的 Web 应用程序 以生成 WebApiA 权限。

  2. 添加 WebApiA 权限并为 Web 应用程序授予管理员许可。

  3. pom.xml中添加以下依赖项。

    <dependencies>
        <dependency>
            <groupId>com.azure.spring</groupId>
            <artifactId>azure-spring-boot-starter-active-directory-b2c</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    
  4. 添加以下配置。

        spring:
          cloud:
            azure:
              active-directory:
                b2c:
                  base-uri: ${BASE_URI}             # Such as: https://xxxxb2c.b2clogin.com
                  profile:
                    tenant-id: ${AZURE_TENANT_ID}
                  app-id-uri: ${APP_ID_URI}         # If you're using v1.0 token, configure app-id-uri for `aud` verification
                  credential:
                    client-id: ${AZURE_CLIENT_ID}           # If you're using v2.0 token, configure client-id for `aud` verification
    
  5. 编写 Java 代码。

    控制器代码可以引用以下内容:

    class Demo {
        /**
         * webApiA resource api for web app
         * @return test content
         */
        @PreAuthorize("hasAuthority('APPROLE_WebApiA.SampleScope')")
        @GetMapping("/webApiA/sample")
        public String webApiASample() {
            LOGGER.info("Call webApiASample()");
            return "Request '/webApiA/sample'(WebApi A) returned successfully.";
        }
    }
    

    安全配置代码可以参考以下内容:

    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests((requests) -> requests.anyRequest().authenticated())
                .oauth2ResourceServer()
                .jwt()
                .jwtAuthenticationConverter(new AadJwtBearerTokenAuthenticationConverter());
        }
    }
    
  6. 生成并测试应用

    让我们 WebApiA 在端口 8081 上运行。 获取资源访问令牌 webApiA ,并作为持有者授权标头进行访问 http://localhost:8081/webApiA/sample

用法 4:访问其他资源服务器的资源服务器

此方案是 访问资源服务器的升级,支持基于 OAuth2 客户端凭据流访问其他应用程序资源。

  1. 引用前面的步骤,我们将创建一个 WebApiB 应用程序并公开应用程序权限 WebApiB.SampleScope

    {
        "allowedMemberTypes": [
            "Application"
        ],
        "description": "WebApiB.SampleScope",
        "displayName": "WebApiB.SampleScope",
        "id": "04989db0-3efe-4db6-b716-ae378517d2b7",
        "isEnabled": true,
        "lang": null,
        "origin": "Application",
        "value": "WebApiB.SampleScope"
    }
    

    Azure 门户屏幕截图,其中显示了应用程序 WebApiB 清单屏幕,其中突出显示了“appRoles”JSON。

  2. 授予 对 WebApiB 权限的管理员同意。

    显示应用程序 WebApiA API 权限屏幕的屏幕截图Azure 门户。

  3. 访问资源服务器的基础上,在 pom.xml中添加依赖项。

    <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    
  4. 根据 访问资源服务器 方案配置添加以下配置。

        spring:
          cloud:
            azure:
              active-directory:
                b2c:
                  credential:
                    client-secret: ${WEB_API_A_AZURE_CLIENT_SECRET}
                  authorization-clients:
                    ${RESOURCE_SERVER_B_NAME}:
                      authorization-grant-type: client_credentials
                      scopes: ${WEB_API_B_APP_ID_URL}/.default
    
  5. 编写 Java 代码。

    WebApiA 控制器代码可以引用以下内容:

    public class SampleController {
        /**
         * Access to protected data from WebApiA to WebApiB through client credential flow. The access token is obtained by webclient, or
         * <p>@RegisteredOAuth2AuthorizedClient("webApiA")</p>. In the end, these two approaches will be executed to
         * DefaultOAuth2AuthorizedClientManager#authorize method, get the access token.
         *
         * @return Respond to protected data from WebApi B.
         */
        @GetMapping("/webApiA/webApiB/sample")
        @PreAuthorize("hasAuthority('APPROLE_WebApiA.SampleScope')")
        public String callWebApiB() {
            String body = webClient
                .get()
                .uri(LOCAL_WEB_API_B_SAMPLE_ENDPOINT)
                .attributes(clientRegistrationId("webApiB"))
                .retrieve()
                .bodyToMono(String.class)
                .block();
            LOGGER.info("Call callWebApiB(), request '/webApiB/sample' returned: {}", body);
            return "Request 'webApiA/webApiB/sample'(WebApi A) returned a " + (body != null ? "success." : "failure.");
        }
    }
    

    WebApiB 控制器代码可以引用以下内容:

    public class SampleController {
        /**
         * webApiB resource api for other web application
         * @return test content
         */
        @PreAuthorize("hasAuthority('APPROLE_WebApiB.SampleScope')")
        @GetMapping("/webApiB/sample")
        public String webApiBSample() {
            LOGGER.info("Call webApiBSample()");
            return "Request '/webApiB/sample'(WebApi B) returned successfully.";
        }
    }
    

    安全配置代码与 访问资源服务器 方案相同,另一个 bean webClient 添加如下

    public class SampleConfiguration {
        @Bean
        public WebClient webClient(OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager) {
            ServletOAuth2AuthorizedClientExchangeFilterFunction function =
                new ServletOAuth2AuthorizedClientExchangeFilterFunction(oAuth2AuthorizedClientManager);
            return WebClient.builder()
                            .apply(function.oauth2Configuration())
                            .build();
        }
    }
    
  6. 生成并测试应用

    WebApiB分别WebApiA在端口 80818082 上运行。 启动WebApiAWebApiB应用程序,获取作为持有者授权标头的资源和访问权限的访问http://localhost:8081/webApiA/webApiB/sample令牌webApiA

示例

有关更多详细信息,请参阅 spring-cloud-azure-starter-active-directory-b2c 示例

Spring Integration 支持

适用于 Azure 的 Spring Integration 扩展为 适用于 Java 的 Azure SDK 提供的各种服务的 Spring Integration 适配器。 我们为这些 Azure 服务提供 Spring Integration 支持:事件中心、服务总线、存储队列。 下面是受支持的适配器列表:

Spring Integration 与 Azure 事件中心

关键概念

Azure 事件中心是大数据流式处理平台和事件引入服务。 它可以每秒接收和处理数百万个事件。 可以使用任何实时分析提供程序或批处理/存储适配器转换和存储发送到事件中心的数据。

Spring Integration 支持基于 Spring 的应用程序中的轻型消息传送,并支持通过声明性适配器与外部系统集成。 这些适配器通过 Spring 对远程处理、消息传送和计划的支持提供更高级别的抽象。 事件中心扩展项目的 Spring Integration 为Azure 事件中心提供入站和出站通道适配器和网关。

注意

RxJava 支持 API 从版本 4.0.0 中删除。 有关详细信息,请参阅 Javadoc。

使用者组

事件中心提供与 Apache Kafka 类似的使用者组支持,但逻辑略有不同。 虽然 Kafka 将所有提交的偏移量存储在中转站中,但必须存储正在手动处理的事件中心消息的偏移量。 事件中心 SDK 提供用于在 Azure 存储中存储此类偏移量的函数。

分区支持

事件中心提供与 Kafka 类似的物理分区概念。 但与 Kafka 在使用者和分区之间自动重新平衡不同,事件中心提供了一种抢占模式。 存储帐户充当租约,用于确定哪个使用者拥有哪个分区。 当新的使用者启动时,它将尝试从大多数重负载使用者中窃取某些分区,以实现工作负荷均衡。

若要指定负载均衡策略,开发人员可用于 EventHubsContainerProperties 配置。 有关如何配置EventHubsContainerProperties的示例,请参阅以下部分

Batch 使用者支持

支持 EventHubsInboundChannelAdapter 批处理使用模式。 若要启用它,用户可以在构造EventHubsInboundChannelAdapter实例时指定侦听器模式ListenerMode.BATCH。 启用后,将接收并传递给下游通道的批处理事件列表的有效负载 的消息 。 每个消息标头也转换为列表,其中内容是从每个事件分析的关联标头值。 对于分区 ID、检查点器和最后排队属性的公共标头,它们显示为整个事件批次共享同一个值。 有关更多详细信息 ,请参阅事件中心消息标头

注意

仅当使用 MANUAL 检查点模式时,检查点标头才存在。

批处理使用者的检查点支持两种模式: BATCHMANUALBATCH 模式是一种自动检查点模式,用于在收到事件后将整个一批事件一起检查点。 MANUAL 模式是检查用户的事件。 使用时, 检查点器 将传递到消息标头中,用户可以使用它执行检查点。

批处理使用策略可以由属性max-sizemax-wait-time指定,并且,这是max-size可选属性时max-wait-time所需的属性。 若要指定批处理使用策略,开发人员可以使用 EventHubsContainerProperties 该策略进行配置。 有关如何配置EventHubsContainerProperties的示例,请参阅以下部分

依赖项设置

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-integration-eventhubs</artifactId>
</dependency>

配置

此初学者提供以下 3 部分的配置选项:

连接配置属性

本部分包含用于连接到Azure 事件中心的配置选项。

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅使用 Azure AD 授权访问 ,以确保安全主体已授予访问 Azure 资源的足够权限。

spring-cloud-azure-starter-integration-eventhubs 的连接可配置属性:

properties 类型 说明
spring.cloud.azure.eventhubs.enabled boolean 是否启用Azure 事件中心。
spring.cloud.azure.eventhubs.connection-string 字符串 事件中心命名空间连接字符串值。
spring.cloud.azure.eventhubs.namespace 字符串 事件中心命名空间值,它是 FQDN 的前缀。 FQDN 应由 NamespaceName.DomainName 组成
spring.cloud.azure.eventhubs.domain-name 字符串 Azure 事件中心命名空间值的域名。
spring.cloud.azure.eventhubs.custom-endpoint-address 字符串 自定义终结点地址。
spring.cloud.azure.eventhubs.shared-connection 布尔 基础 EventProcessorClient 和 EventHubProducerAsyncClient 是否使用相同的连接。 默认情况下,会构造一个新连接,并用于为每个创建的事件中心客户端创建。
检查点配置属性

本部分包含存储 Blob 服务的配置选项,用于保存分区所有权和检查点信息。

注意

从版本 4.0.0 开始,如果未手动启用 spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists 的属性,则不会自动创建存储容器。

spring-cloud-azure-starter-integration-eventhubs 的检查点可配置属性:

properties 类型 说明
spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists 布尔 是否允许创建容器(如果不存在)。
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name 字符串 存储帐户的名称。
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-key 字符串 存储帐户访问密钥。
spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name 字符串 存储容器名称。

常见的 Azure 服务 SDK 配置选项也可用于存储 Blob 检查点存储。 支持的配置选项在 “配置”页中引入,可以使用统一前缀 spring.cloud.azure. 或前缀进行 spring.cloud.azure.eventhubs.processor.checkpoint-store配置。

事件中心处理器配置属性

使用该EventHubsInboundChannelAdapterEventProcessorClient事件中心的消息来配置整体属性EventProcessorClient,开发人员可以使用EventHubsContainerProperties该配置。 请参阅 以下部分 ,了解如何使用 EventHubsInboundChannelAdapter

基本用法

将消息发送到Azure 事件中心
  1. 填写凭据配置选项。

    • 对于凭据作为连接字符串,请在以下属性中 application.yml配置:
        spring:
          cloud:
            azure:
              eventhubs:
                connection-string: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
                processor:
                  checkpoint-store:
                    container-name: ${CHECKPOINT-CONTAINER}
                    account-name: ${CHECKPOINT-STORAGE-ACCOUNT}
                    account-key: ${CHECKPOINT-ACCESS-KEY}
    
    • 对于作为托管标识的凭据,请在以下属性中 application.yml配置:
        spring:
          cloud:
            azure:
              credential:
                managed-identity-enabled: true
                client-id: ${AZURE_CLIENT_ID}
              eventhubs:
                namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
                processor:
                  checkpoint-store:
                    container-name: ${CONTAINER_NAME}
                    account-name: ${ACCOUNT_NAME}
    
    • 对于凭据即服务主体,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              credential:
                client-id: ${AZURE_CLIENT_ID}
                client-secret: ${AZURE_CLIENT_SECRET}
              profile:
                tenant-id: ${AZURE_TENANT_ID}
              eventhubs:
                namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
                processor:
                  checkpoint-store:
                    container-name: ${CONTAINER_NAME}
                    account-name: ${ACCOUNT_NAME}
    
  2. 创建 DefaultMessageHandler 包含将 EventHubsTemplate 消息发送到事件中心的 bean。

    class Demo {
        private static final String OUTPUT_CHANNEL = "output";
        private static final String EVENTHUB_NAME = "eh1";
    
        @Bean
        @ServiceActivator(inputChannel = OUTPUT_CHANNEL)
        public MessageHandler messageSender(EventHubsTemplate eventHubsTemplate) {
            DefaultMessageHandler handler = new DefaultMessageHandler(EVENTHUB_NAME, eventHubsTemplate);
            handler.setSendCallback(new ListenableFutureCallback<Void>() {
                @Override
                public void onSuccess(Void result) {
                    LOGGER.info("Message was sent successfully.");
                }
                @Override
                public void onFailure(Throwable ex) {
                    LOGGER.error("There was an error sending the message.", ex);
                }
            });
            return handler;
        }
    }
    
  3. 通过消息通道使用上述消息处理程序创建消息网关绑定。

    class Demo {
        @Autowired
        EventHubOutboundGateway messagingGateway;
    
        @MessagingGateway(defaultRequestChannel = OUTPUT_CHANNEL)
        public interface EventHubOutboundGateway {
            void send(String text);
        }
    }
    
  4. 使用网关发送消息。

    class Demo {
        public void demo() {
            this.messagingGateway.send(message);
        }
    }
    
从Azure 事件中心接收消息
  1. 填写凭据配置选项。

  2. 创建消息通道作为输入通道的豆条。

    @Configuration
    class Demo {
        @Bean
        public MessageChannel input() {
            return new DirectChannel();
        }
    }
    
  3. 使用从事件中心接收消息的 beans EventHubsMessageListenerContainer 创建EventHubsInboundChannelAdapter

    @Configuration
    class Demo {
        private static final String INPUT_CHANNEL = "input";
        private static final String EVENTHUB_NAME = "eh1";
        private static final String CONSUMER_GROUP = "$Default";
    
        @Bean
        public EventHubsInboundChannelAdapter messageChannelAdapter(
                @Qualifier(INPUT_CHANNEL) MessageChannel inputChannel,
                EventHubsMessageListenerContainer listenerContainer) {
            EventHubsInboundChannelAdapter adapter = new EventHubsInboundChannelAdapter(processorContainer);
            adapter.setOutputChannel(inputChannel);
            return adapter;
        }
    
        @Bean
        public EventHubsMessageListenerContainer messageListenerContainer(EventHubsProcessorFactory processorFactory) {
            EventHubsContainerProperties containerProperties = new EventHubsContainerProperties();
            containerProperties.setEventHubName(EVENTHUB_NAME);
            containerProperties.setConsumerGroup(CONSUMER_GROUP);
            containerProperties.setCheckpointConfig(new CheckpointConfig(CheckpointMode.MANUAL));
            return new EventHubsMessageListenerContainer(processorFactory, containerProperties);
        }
    }
    
  4. 通过之前创建的消息通道,使用 EventHubsInboundChannelAdapter 创建消息接收器绑定。

    class Demo {
        @ServiceActivator(inputChannel = INPUT_CHANNEL)
        public void messageReceiver(byte[] payload, @Header(AzureHeaders.CHECKPOINTER) Checkpointer checkpointer) {
            String message = new String(payload);
            LOGGER.info("New message received: '{}'", message);
            checkpointer.success()
                    .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message))
                    .doOnError(e -> LOGGER.error("Error found", e))
                    .block();
        }
    }
    
配置 EventHubsMessageConverter 以自定义 objectMapper

EventHubsMessageConverter 作为可配置的豆形进行创建,允许用户自定义 ObjectMapper。

Batch 使用者支持

若要批量使用来自事件中心的消息与上面的示例类似,除了用户应设置 EventHubsInboundChannelAdapter批处理使用的相关配置选项之外。

创建 EventHubsInboundChannelAdapter时,侦听器模式应设置为 BATCH。 创建 bean of EventHubsMessageListenerContainer时,请将检查点模式设置为任一MANUALBATCH模式,并根据需要配置批处理选项。

@Configuration
class Demo {
    private static final String INPUT_CHANNEL = "input";
    private static final String EVENTHUB_NAME = "eh1";
    private static final String CONSUMER_GROUP = "$Default";

    @Bean
    public EventHubsInboundChannelAdapter messageChannelAdapter(
            @Qualifier(INPUT_CHANNEL) MessageChannel inputChannel,
            EventHubsMessageListenerContainer listenerContainer) {
        EventHubsInboundChannelAdapter adapter = new EventHubsInboundChannelAdapter(processorContainer, ListenerMode.BATCH);
        adapter.setOutputChannel(inputChannel);
        return adapter;
    }

    @Bean
    public EventHubsMessageListenerContainer messageListenerContainer(EventHubsProcessorFactory processorFactory) {
        EventHubsContainerProperties containerProperties = new EventHubsContainerProperties();
        containerProperties.setEventHubName(EVENTHUB_NAME);
        containerProperties.setConsumerGroup(CONSUMER_GROUP);
        containerProperties.getBatch().setMaxSize(100);
        containerProperties.setCheckpointConfig(new CheckpointConfig(CheckpointMode.MANUAL));
        return new EventHubsMessageListenerContainer(processorFactory, containerProperties);
    }
}
事件中心消息标头

下表说明了事件中心消息属性如何映射到 Spring 消息标头。 对于Azure 事件中心,消息称为 event

在记录侦听器模式下的事件中心消息/事件属性和 Spring Message 标头之间映射:

事件中心事件属性 Spring Message Header 常量 类型 说明
排队时间 EventHubsHeaders#ENQUEUED_TIME 即时 事件在事件中心分区中排队时的即时(UTC)。
Offset EventHubsHeaders#OFFSET Long 从关联的事件中心分区接收事件的偏移量。
分区键 AzureHeaders#PARTITION_KEY String 如果最初发布事件时设置了分区哈希键,则为分区哈希键。
分区 ID AzureHeaders#RAW_PARTITION_ID 字符串 事件中心的分区 ID。
序列号 EventHubsHeaders#SEQUENCE_NUMBER Long 在关联的事件中心分区中排队时分配给事件的序列号。
最后排队事件属性 EventHubsHeaders#LAST_ENQUEUED_EVENT_PROPERTIES LastEnqueuedEventProperties 此分区中最后一个排队事件的属性。
不可用 AzureHeaders#CHECKPOINTER 检查点器 特定消息的检查点的标头。

用户可以分析每个事件相关信息的消息标头。 若要为事件设置消息标头,所有自定义标头都将作为事件的应用程序属性,其中标头设置为属性键。 从事件中心接收事件时,所有应用程序属性都将转换为消息标头。

注意

不支持手动设置分区键、排队时间、偏移量和序列号的消息标头。

启用批处理使用者模式时,将列出以下各批消息的特定标头,其中包含每个事件中心事件中的值列表。

在 Batch 侦听器模式下的事件中心消息/事件属性和 Spring Message 标头之间进行映射:

事件中心事件属性 Spring Batch 消息标头常量 类型 说明
排队时间 EventHubsHeaders#ENQUEUED_TIME 即时列表 在事件中心分区中排队每个事件的即时列表(以 UTC 为单位)。
Offset EventHubsHeaders#OFFSET Long 列表 从关联的事件中心分区接收每个事件的偏移量列表。
分区键 AzureHeaders#PARTITION_KEY 字符串列表 如果最初发布每个事件时设置分区哈希键的列表。
序列号 EventHubsHeaders#SEQUENCE_NUMBER Long 列表 在关联事件中心分区中排队时分配给每个事件的序列号的列表。
系统属性 EventHubsHeaders#BATCH_CONVERTED_SYSTEM_PROPERTIES 地图列表 每个事件的系统属性的列表。
应用程序属性 EventHubsHeaders#BATCH_CONVERTED_APPLICATION_PROPERTIES 地图列表 每个事件的应用程序属性列表,其中放置了所有自定义消息头或事件属性。

注意

发布消息时,上述所有批处理标头都将从消息中删除(如果存在)。

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

Spring 与 Azure 服务总线的集成

关键概念

Spring Integration 支持基于 Spring 的应用程序中的轻型消息传送,并支持通过声明性适配器与外部系统集成。

适用于 Azure 服务总线 扩展项目的 Spring Integration 为Azure 服务总线提供入站和出站通道适配器。

注意

完成的Future 支持 API 已从版本 2.10.0 弃用,并且已由 4.0.0 版中的 Reactor Core 取代。 有关详细信息,请参阅 Javadoc。

依赖项设置

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-integration-servicebus</artifactId>
</dependency>

配置

此初学者提供以下 2 部分的配置选项:

连接配置属性

本部分包含用于连接到Azure 服务总线的配置选项。

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅使用 Azure AD 授权访问 ,以确保安全主体已获得访问 Azure 资源的足够权限。

spring-cloud-azure-starter-integration-servicebus 的连接可配置属性:

properties 类型 说明
spring.cloud.azure.servicebus.enabled boolean 是否启用Azure 服务总线。
spring.cloud.azure.servicebus.connection-string 字符串 服务总线命名空间连接字符串值。
spring.cloud.azure.servicebus.namespace String 服务总线命名空间值,它是 FQDN 的前缀。 FQDN 应由 NamespaceName.DomainName 组成
spring.cloud.azure.servicebus.domain-name String Azure 服务总线命名空间值的域名。
服务总线处理器配置属性

使用ServiceBusInboundChannelAdapterServiceBusProcessorClient消息来配置整体ServiceBusProcessorClient属性,开发人员可以使用ServiceBusContainerProperties该配置。 请参阅 以下部分 ,了解如何使用 ServiceBusInboundChannelAdapter

基本用法

将消息发送到Azure 服务总线
  1. 填写凭据配置选项。

    • 对于凭据作为连接字符串,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              servicebus:
                connection-string: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
    
    • 对于作为托管标识的凭据,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              credential:
                managed-identity-enabled: true
                client-id: ${AZURE_CLIENT_ID}
              profile:
                tenant-id: ${AZURE_TENANT_ID}
              servicebus:
                namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
    
    • 对于凭据即服务主体,请在 application.yml 中配置以下属性:

          spring:
            cloud:
              azure:
                credential:
                  client-id: ${AZURE_CLIENT_ID}
                  client-secret: ${AZURE_CLIENT_SECRET}
                profile:
                  tenant-id: ${AZURE_TENANT_ID}
                servicebus:
                  namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
      
  2. 使用 bean of ServiceBusTemplate to send messages to Service Bus 创建DefaultMessageHandler,设置 ServiceBusTemplate 的实体类型。 此示例以服务总线队列为例。

    class Demo {
        private static final String OUTPUT_CHANNEL = "queue.output";
    
        @Bean
        @ServiceActivator(inputChannel = OUTPUT_CHANNEL)
        public MessageHandler queueMessageSender(ServiceBusTemplate serviceBusTemplate) {
            serviceBusTemplate.setDefaultEntityType(ServiceBusEntityType.QUEUE);
            DefaultMessageHandler handler = new DefaultMessageHandler(QUEUE_NAME, serviceBusTemplate);
            handler.setSendCallback(new ListenableFutureCallback<Void>() {
                @Override
                public void onSuccess(Void result) {
                    LOGGER.info("Message was sent successfully.");
                }
    
                @Override
                public void onFailure(Throwable ex) {
                    LOGGER.info("There was an error sending the message.");
                }
            });
    
            return handler;
        }
    }
    
  3. 通过消息通道使用上述消息处理程序创建消息网关绑定。

    class Demo {
        @Autowired
        QueueOutboundGateway messagingGateway;
    
        @MessagingGateway(defaultRequestChannel = OUTPUT_CHANNEL)
        public interface QueueOutboundGateway {
            void send(String text);
        }
    }
    
  4. 使用网关发送消息。

    class Demo {
        public void demo() {
            this.messagingGateway.send(message);
        }
    }
    
从Azure 服务总线接收消息
  1. 填写凭据配置选项。

  2. 创建消息通道作为输入通道的 bean。

    @Configuration
    class Demo {
        private static final String INPUT_CHANNEL = "input";
    
        @Bean
        public MessageChannel input() {
            return new DirectChannel();
        }
    }
    
  3. 使用 bean of ServiceBusMessageListenerContainer 将消息发送到服务总线创建ServiceBusInboundChannelAdapter。 此示例以服务总线队列为例。

    @Configuration
    class Demo {
        private static final String QUEUE_NAME = "queue1";
    
        @Bean
        public ServiceBusMessageListenerContainer messageListenerContainer(ServiceBusProcessorFactory processorFactory) {
            ServiceBusContainerProperties containerProperties = new ServiceBusContainerProperties();
            containerProperties.setEntityName(QUEUE_NAME);
            containerProperties.setAutoComplete(false);
            return new ServiceBusMessageListenerContainer(processorFactory, containerProperties);
        }
    
        @Bean
        public ServiceBusInboundChannelAdapter queueMessageChannelAdapter(
            @Qualifier(INPUT_CHANNEL) MessageChannel inputChannel,
            ServiceBusMessageListenerContainer listenerContainer) {
            ServiceBusInboundChannelAdapter adapter = new ServiceBusInboundChannelAdapter(listenerContainer);
            adapter.setOutputChannel(inputChannel);
            return adapter;
        }
    }
    
  4. 通过之前创建的消息通道,使用 ServiceBusInboundChannelAdapter 创建消息接收器绑定。

    class Demo {
        @ServiceActivator(inputChannel = INPUT_CHANNEL)
        public void messageReceiver(byte[] payload, @Header(AzureHeaders.CHECKPOINTER) Checkpointer checkpointer) {
            String message = new String(payload);
            LOGGER.info("New message received: '{}'", message);
            checkpointer.success()
                    .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message))
                    .doOnError(e -> LOGGER.error("Error found", e))
                    .block();
        }
    }
    
配置 ServiceBusMessageConverter 以自定义 objectMapper

ServiceBusMessageConverter 被设置为可配置的豆,允许用户自定义 ObjectMapper。

服务总线消息标头

对于可映射到多个 Spring 标头常量的某些服务总线标头,列出了不同 Spring 标头的优先级。

服务总线标头和 Spring 标头之间的映射:

服务总线消息标头和属性 Spring Message 标头常量 类型 可配置性 说明
内容类型 MessageHeaders#CONTENT_TYPE 字符串 消息的 RFC2045 内容类型描述符。
相关性 ID ServiceBusMessageHeaders#CORRELATION_ID 字符串 消息的相关 ID
消息 ID ServiceBusMessageHeaders#MESSAGE_ID String 消息的消息 ID,此标头的优先级高于 MessageHeaders#ID
消息 ID MessageHeaders#ID UUID 消息的消息 ID,此标头的优先级低于 ServiceBusMessageHeaders#MESSAGE_ID
分区键 ServiceBusMessageHeaders#PARTITION_KEY 字符串 用于将消息发送到分区实体的分区键。
回复 MessageHeaders#REPLY_CHANNEL String 要向其发送答复的实体的地址。
回复会话 ID ServiceBusMessageHeaders#REPLY_TO_SESSION_ID String 消息的 ReplyToGroupId 属性值。
计划的排队时间 utc ServiceBusMessageHeaders#SCHEDULED_ENQUEUE_TIME OffsetDateTime 应在服务总线中排队消息的日期时间,此标头的优先级高于 AzureHeaders#SCHEDULED_ENQUEUE_MESSAGE
计划的排队时间 utc AzureHeaders#SCHEDULED_ENQUEUE_MESSAGE Integer 应在服务总线中排队消息的日期时间,此标头的优先级低于 ServiceBusMessageHeaders#SCHEDULED_ENQUEUE_TIME
会话 ID ServiceBusMessageHeaders#SESSION_ID 字符串 会话感知实体的会话 IDentifier。
生存时间 ServiceBusMessageHeaders#TIME_TO_LIVE 持续时间 此消息到期前的持续时间。
功能 ServiceBusMessageHeaders#TO 字符串 消息的“to”地址,保留供将来在路由方案中使用,并且当前被中转站本身忽略。
主题 ServiceBusMessageHeaders#SUBJECT String 邮件的主题。
死信错误说明 ServiceBusMessageHeaders#DEAD_LETTER_ERROR_DESCRIPTION String 已死信的消息的说明。
死信原因 ServiceBusMessageHeaders#DEAD_LETTER_REASON 字符串 消息死信的原因。
死信源 ServiceBusMessageHeaders#DEAD_LETTER_SOURCE 字符串 消息已死信的实体。
传递计数 ServiceBusMessageHeaders#DELIVERY_COUNT long 此消息传递到客户端的次数。
排队序列号 ServiceBusMessageHeaders#ENQUEUED_SEQUENCE_NUMBER long 按服务总线分配给消息的排队序列号。
排队时间 ServiceBusMessageHeaders#ENQUEUED_TIME OffsetDateTime 此消息在服务总线中排队的日期时间。
过期时间 ServiceBusMessageHeaders#EXPIRES_AT OffsetDateTime 此消息将过期的日期时间。
锁定令牌 ServiceBusMessageHeaders#LOCK_TOKEN 字符串 当前消息的锁令牌。
锁定到 ServiceBusMessageHeaders#LOCKED_UNTIL OffsetDateTime 此消息锁过期的日期时间。
序列号 ServiceBusMessageHeaders#SEQUENCE_NUMBER long 由服务总线分配给消息的唯一编号。
状态 ServiceBusMessageHeaders#STATE ServiceBusMessageState 消息的状态,可以是“活动”、“延迟”或“计划”。
分区键支持

此初学者通过允许在消息标头中设置分区键和会话 ID 来支持 服务总线分区 。 本部分介绍如何为消息设置分区键。

推荐: 用作 ServiceBusMessageHeaders.PARTITION_KEY 标头的键。

public class SampleController {
    @PostMapping("/messages")
    public ResponseEntity<String> sendMessage(@RequestParam String message) {
        LOGGER.info("Going to add message {} to Sinks.Many.", message);
        many.emitNext(MessageBuilder.withPayload(message)
                                    .setHeader(ServiceBusMessageHeaders.PARTITION_KEY, "Customize partition key")
                                    .build(), Sinks.EmitFailureHandler.FAIL_FAST);
        return ResponseEntity.ok("Sent!");
    }
}

不建议,但当前受支持:AzureHeaders.PARTITION_KEY 作为标头的键。

public class SampleController {
    @PostMapping("/messages")
    public ResponseEntity<String> sendMessage(@RequestParam String message) {
        LOGGER.info("Going to add message {} to Sinks.Many.", message);
        many.emitNext(MessageBuilder.withPayload(message)
                                    .setHeader(AzureHeaders.PARTITION_KEY, "Customize partition key")
                                    .build(), Sinks.EmitFailureHandler.FAIL_FAST);
        return ResponseEntity.ok("Sent!");
    }
}

注意

ServiceBusMessageHeaders.PARTITION_KEYAzureHeaders.PARTITION_KEY在消息标头中同时设置时,ServiceBusMessageHeaders.PARTITION_KEY首选。

会话支持

此示例演示如何在应用程序中手动设置消息的会话 ID。

public class SampleController {
    @PostMapping("/messages")
    public ResponseEntity<String> sendMessage(@RequestParam String message) {
        LOGGER.info("Going to add message {} to Sinks.Many.", message);
        many.emitNext(MessageBuilder.withPayload(message)
                                    .setHeader(ServiceBusMessageHeaders.SESSION_ID, "Customize session ID")
                                    .build(), Sinks.EmitFailureHandler.FAIL_FAST);
        return ResponseEntity.ok("Sent!");
    }
}

注意

在消息标头中设置会话 ServiceBusMessageHeaders.SESSION_ID ID 时,还会设置不同的 ServiceBusMessageHeaders.PARTITION_KEY (或 AzureHeaders.PARTITION_KEY) 标头,会话 ID 的值最终将用于覆盖分区键的值。

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

Spring 与 Azure 存储队列的集成

关键概念

Azure 队列存储是一项可存储大量消息的服务。 可以使用 HTTP 或 HTTPS 通过经验证的调用从世界任何位置访问消息。 队列消息大小最大可为 64 KB。 一个队列可以包含数百万条消息,直至达到存储帐户的总容量限值。 队列通常用于创建要异步处理的积压工作 (backlog)。

依赖项设置

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-integration-storage-queue</artifactId>
</dependency>

配置

此初学者提供以下配置选项:

连接配置属性

本部分包含用于连接到 Azure 存储队列的配置选项。

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅使用 Azure AD 授权访问 ,以确保安全主体已获得访问 Azure 资源的足够权限。

spring-cloud-azure-starter-integration-storage-queue 的连接可配置属性:

properties 类型 说明
spring.cloud.azure.storage.queue.enabled boolean 是否启用 Azure 存储队列。
spring.cloud.azure.storage.queue.connection-string String 存储队列命名空间连接字符串值。
spring.cloud.azure.storage.queue.accountName 字符串 存储帐户名称。
spring.cloud.azure.storage.queue.accountKey 字符串 存储帐户密钥。
spring.cloud.azure.storage.queue.endpoint 字符串 存储队列服务终结点。
spring.cloud.azure.storage.queue.sasToken 字符串 Sas 令牌凭据
spring.cloud.azure.storage.queue.serviceVersion QueueServiceVersion 发出 API 请求时使用的 QueueServiceVersion。
spring.cloud.azure.storage.queue.messageEncoding String 队列消息编码。

基本用法

将消息发送到 Azure 存储队列
  1. 填写凭据配置选项。

    • 对于凭据作为连接字符串,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              storage:
                queue:
                  connection-string: ${AZURE_SERVICE_BUS_CONNECTION_STRING}
    
    • 对于作为托管标识的凭据,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              credential:
                managed-identity-enabled: true
                client-id: ${AZURE_CLIENT_ID}
              profile:
                tenant-id: ${AZURE_TENANT_ID}
              storage:
                queue:
                  namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
    
    • 对于凭据即服务主体,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              credential:
                client-id: ${AZURE_CLIENT_ID}
                client-secret: ${AZURE_CLIENT_SECRET}
              profile:
                tenant-id: ${AZURE_TENANT_ID}
              storage:
                queue:
                  namespace: ${AZURE_SERVICE_BUS_NAMESPACE}
    
  2. 使用 bean of StorageQueueTemplate 将消息发送到存储队列创建DefaultMessageHandler

    class Demo {
        private static final String STORAGE_QUEUE_NAME = "example";
        private static final String OUTPUT_CHANNEL = "output";
    
        @Bean
        @ServiceActivator(inputChannel = OUTPUT_CHANNEL)
        public MessageHandler messageSender(StorageQueueTemplate storageQueueTemplate) {
            DefaultMessageHandler handler = new DefaultMessageHandler(STORAGE_QUEUE_NAME, storageQueueTemplate);
            handler.setSendCallback(new ListenableFutureCallback<Void>() {
                @Override
                public void onSuccess(Void result) {
                    LOGGER.info("Message was sent successfully.");
                }
    
                @Override
                public void onFailure(Throwable ex) {
                    LOGGER.info("There was an error sending the message.");
                }
            });
            return handler;
        }
    }
    
  3. 通过消息通道创建包含上述消息处理程序的消息网关绑定。

    class Demo {
        @Autowired
        StorageQueueOutboundGateway storageQueueOutboundGateway;
    
        @MessagingGateway(defaultRequestChannel = OUTPUT_CHANNEL)
        public interface StorageQueueOutboundGateway {
            void send(String text);
        }
    }
    
  4. 使用网关发送消息。

    class Demo {
        public void demo() {
            this.storageQueueOutboundGateway.send(message);
        }
    }
    
从 Azure 存储队列接收消息
  1. 填写凭据配置选项。

  2. 创建消息通道作为输入通道的 bean。

    class Demo {
        private static final String INPUT_CHANNEL = "input";
    
        @Bean
        public MessageChannel input() {
            return new DirectChannel();
        }
    }
    
  3. 使用 bean of StorageQueueTemplate 将消息接收到存储队列创建StorageQueueMessageSource

    class Demo {
        private static final String STORAGE_QUEUE_NAME = "example";
    
        @Bean
        @InboundChannelAdapter(channel = INPUT_CHANNEL, poller = @Poller(fixedDelay = "1000"))
        public StorageQueueMessageSource storageQueueMessageSource(StorageQueueTemplate storageQueueTemplate) {
            return new StorageQueueMessageSource(STORAGE_QUEUE_NAME, storageQueueTemplate);
        }
    }
    
  4. 使用在上一步中创建的 StorageQueueMessageSource 通过之前创建的消息通道创建消息接收器绑定。

    class Demo {
        @ServiceActivator(inputChannel = INPUT_CHANNEL)
        public void messageReceiver(byte[] payload, @Header(AzureHeaders.CHECKPOINTER) Checkpointer checkpointer) {
            String message = new String(payload);
            LOGGER.info("New message received: '{}'", message);
            checkpointer.success()
                .doOnError(Throwable::printStackTrace)
                .doOnSuccess(t -> LOGGER.info("Message '{}' successfully checkpointed", message))
                .block();
        }
    }
    

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

Spring Cloud Stream 支持

Spring Cloud Stream 是一个框架,用于构建与共享消息系统连接的高度可缩放事件驱动微服务。

该框架提供了一种灵活的编程模型,该模型基于已建立且熟悉的 Spring 语法和最佳做法,包括对持久性发布/子语义、使用者组和有状态分区的支持。

当前绑定器实现包括:

适用于 Azure 事件中心 的 Spring Cloud Stream Binder

关键概念

适用于 Azure 事件中心的 Spring Cloud Stream Binder 为 Spring Cloud Stream 框架提供绑定实现。 此实现在其基础上使用 Spring Integration 事件中心通道适配器。 从设计的角度来看,事件中心类似于 Kafka。 此外,可以通过 Kafka API 访问事件中心。 如果项目依赖于 Kafka API,则可以 使用 Kafka API 示例尝试事件中心

使用者组

事件中心提供与 Apache Kafka 类似的使用者组支持,但逻辑略有不同。 虽然 Kafka 将所有提交的偏移量存储在中转站中,但必须存储正在手动处理的事件中心消息的偏移量。 事件中心 SDK 提供用于在 Azure 存储中存储此类偏移量的函数。

分区支持

事件中心提供与 Kafka 类似的物理分区概念。 但与 Kafka 在使用者和分区之间自动重新平衡不同,事件中心提供了一种抢占模式。 存储帐户充当租约,用于确定哪个使用者拥有哪个分区。 当新的使用者启动时,它将尝试从大多数重负载使用者中窃取某些分区,以实现工作负荷均衡。

若要指定负载均衡策略,请提供其属性 spring.cloud.stream.eventhubs.bindings.<binding-name>.consumer.load-balancing.* 。 有关更多详细信息 ,请参阅使用者属性

Batch 使用者支持

Spring Cloud Azure Stream 事件中心绑定器支持 Spring Cloud Stream Batch 使用者功能

若要使用批处理使用者模式,应将属性 spring.cloud.stream.bindings.<binding-name>.consumer.batch-mode 设置为 true。 启用后,将接收有效负载是批处理事件列表的消息,并将其传递给Consumer函数。 每个消息标头也会转换为列表,其中内容是从每个事件分析的关联标头值。 对于分区 ID、检查点器和最后一个排队属性的公共标头,它们作为单个值呈现为整个事件批处理共享相同的值。 有关更多详细信息 ,请参阅事件中心消息标头

注意

仅当使用 MANUAL 检查点模式时,才存在检查点标头。

批处理使用者的检查点支持两种模式: BATCHMANUALBATCH 模式是一种自动检查点模式,用于检查绑定器接收整个事件批的事件。 MANUAL 模式是检查用户的事件。 使用时, 检查点器 将传递到消息标头中,用户可以使用它执行检查点。

批大小可由前缀spring.cloud.stream.eventhubs.bindings.<binding-name>.consumer.batch.的属性max-wait-timemax-size指定,这是可选的,这是max-size必要的属性max-wait-time。 有关更多详细信息 ,请参阅使用者属性

依赖项设置

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-stream-binder-eventhubs</artifactId>
</dependency>

或者,也可以使用 Spring Cloud Azure Stream 事件中心初学者,如以下示例中所示:Maven:

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-stream-eventhubs</artifactId>
</dependency>

配置

绑定器提供以下 3 部分的配置选项:

连接配置属性

本部分包含用于连接到Azure 事件中心的配置选项。

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅使用 Azure AD 授权访问 ,以确保安全主体已获得访问 Azure 资源的足够权限。

spring-cloud-azure-stream-binder-eventhubs 的连接可配置属性:

properties 类型 说明
spring.cloud.azure.eventhubs.enabled boolean 是否启用Azure 事件中心。
spring.cloud.azure.eventhubs.connection-string 字符串 事件中心命名空间连接字符串值。
spring.cloud.azure.eventhubs.namespace 字符串 事件中心命名空间值,它是 FQDN 的前缀。 FQDN 应由 NamespaceName.DomainName 组成
spring.cloud.azure.eventhubs.domain-name 字符串 Azure 事件中心命名空间值的域名。
spring.cloud.azure.eventhubs.custom-endpoint-address 字符串 自定义终结点地址。

提示

常见的 Azure 服务 SDK 配置选项也可用于 Spring Cloud Azure Stream 事件中心绑定器。 支持的配置选项在 “配置”页中引入,可以使用统一前缀或前缀 spring.cloud.azure. 进行 spring.cloud.azure.eventhubs.配置。

默认情况下,绑定器还支持 Spring Could Azure 资源管理器。 若要了解如何检索具有未授予 Data 相关角色的安全主体的连接字符串,请参阅 资源管理器示例 了解详细信息。

检查点配置属性

本部分包含存储 Blob 服务的配置选项,用于保存分区所有权和检查点信息。

注意

从版本 4.0.0 开始,如果 spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists 的属性未手动启用,则不会使用 spring.cloud.stream.bindings.bindings.binding-name.destination 的名称自动创建存储容器。

spring-cloud-azure-stream-binder-eventhubs 的检查点可配置属性:

properties 类型 说明
spring.cloud.azure.eventhubs.processor.checkpoint-store.create-container-if-not-exists 布尔 是否允许创建容器(如果不存在)。
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-name String 存储帐户的名称。
spring.cloud.azure.eventhubs.processor.checkpoint-store.account-key String 存储帐户访问密钥。
spring.cloud.azure.eventhubs.processor.checkpoint-store.container-name String 存储容器名称。

提示

常见的 Azure 服务 SDK 配置选项也可用于存储 Blob 检查点存储。 支持的配置选项在 “配置”页中引入,可以使用统一前缀或前缀 spring.cloud.azure. 进行 spring.cloud.azure.eventhubs.processor.checkpoint-store配置。

Azure 事件中心绑定配置属性

以下选项分为四个部分:使用者属性、高级使用者配置、生成者属性和高级生成者配置。

使用者属性

这些属性通过 EventHubsConsumerProperties.

spring-cloud-azure-stream-binder-eventhubs 的使用者可配置属性:

properties 类型 说明
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.checkpoint.mode CheckpointMode 使用者决定如何检查点消息时使用的检查点模式
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.checkpoint.count Integer 决定每个分区的消息量以执行一个检查点。 仅当使用检查点模式时 PARTITION_COUNT 才会生效。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.checkpoint.interval 持续时间 决定执行一个检查点的时间间隔。 仅当使用检查点模式时 TIME 才会生效。
spring.cloud.stream.eventhubs.bindings。<binding-name.consumer.batch.max-size Integer 批处理中的最大事件数。 批处理使用者模式是必需的。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.batch.max-wait-time 持续时间 批处理使用的最大持续时间。 只有在启用批处理使用者模式并且是可选的时才生效。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.load-balancing.update-interval 持续时间 更新的时间间隔持续时间。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.load-balancing.strategy LoadBalancingStrategy 负载均衡策略。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.load-balancing.partition-ownership-expiration-interval 持续时间 分区所有权过期的持续时间。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.track-last-enqueued-event-properties 布尔 事件处理程序是否应请求有关其关联分区上最后排队事件的信息,并跟踪接收事件时的信息。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.prefetch-count Integer 使用者用来控制事件中心使用者在本地主动接收和排队的事件数的计数。
spring.cloud.stream.eventhubs.bindings.binding-name.consumer.initial-partition-event-position 将键映射为分区 ID 和值 StartPositionProperties 如果检查点存储中不存在分区的检查点,则包含要用于每个分区的事件位置的映射。 此映射从分区 ID 中键取键。

注意

配置 initial-partition-event-position 接受一个 map 指定每个事件中心的初始位置。 因此,它的键是分区 ID,该值 StartPositionProperties 包括偏移量、序列号、排队日期时间以及是否包含的属性。 例如,可以将它设置为

spring:
  cloud:
    stream:
      eventhubs:
        bindings:
          <binding-name>:
            consumer:
              initial-partition-event-position:
                0:
                  offset: earliest
                1:
                  sequence-number: 100
                2:
                  enqueued-date-time: 2022-01-12T13:32:47.650005Z
                4:
                  inclusive: false
高级使用者配置

支持为每个绑定器使用者自定义上述 连接检查点常见的 Azure SDK 客户端 配置,这些使用者可以使用前缀 spring.cloud.stream.eventhubs.bindings.<binding-name>.consumer.进行配置。

生成者属性

这些属性通过 EventHubsProducerProperties.

spring-cloud-azure-stream-binder-eventhubs 的生成者可配置属性:

properties 类型 说明
spring.cloud.stream.eventhubs.bindings.binding-name.producer.sync boolean 生成者的同步的开关标志。 如果为 true,生成者将在发送操作后等待响应。
spring.cloud.stream.eventhubs.bindings.binding-name.producer.send-timeout long 发送操作后等待响应的时间量。 仅当启用同步生成者时才会生效。
高级生成者配置

支持上述 连接常见的 Azure SDK 客户端 配置,以便为每个绑定器生成者自定义,该生成者可以使用前缀 spring.cloud.stream.eventhubs.bindings.<binding-name>.producer.进行配置。

基本用法

发送和接收来自/向事件中心的消息
  1. 使用凭据信息填充配置选项。

    • 对于凭据作为连接字符串,请在 application.yml 中配置以下属性:
    spring:
      cloud:
        azure:
          eventhubs:
            connection-string: ${EVENTHUB_NAMESPACE_CONNECTION_STRING}
            processor:
              checkpoint-store:
                container-name: ${CHECKPOINT_CONTAINER}
                account-name: ${CHECKPOINT_STORAGE_ACCOUNT}
                account-key: ${CHECKPOINT_ACCESS_KEY}
        stream:
          function:
            definition: consume;supply
          bindings:
            consume-in-0:
              destination: ${EVENTHUB_NAME}
              group: ${CONSUMER_GROUP}
            supply-out-0:
              destination: ${THE_SAME_EVENTHUB_NAME_AS_ABOVE}
          eventhubs:
            bindings:
              consume-in-0:
                consumer:
                  checkpoint:
                    mode: MANUAL
    
    • 对于凭据即服务主体,请在 application.yml 中配置以下属性:
    spring:
      cloud:
        azure:
          credential:
            client-id: ${AZURE_CLIENT_ID}
            client-secret: ${AZURE_CLIENT_SECRET}
          profile:
            tenant-id: ${AZURE_TENANT_ID}
          eventhubs:
            namespace: ${EVENTHUB_NAMESPACE}
            processor:
              checkpoint-store:
                container-name: ${CONTAINER_NAME}
                account-name: ${ACCOUNT_NAME}
        stream:
          function:
            definition: consume;supply
          bindings:
            consume-in-0:
              destination: ${EVENTHUB_NAME}
              group: ${CONSUMER_GROUP}
            supply-out-0:
              destination: ${THE_SAME_EVENTHUB_NAME_AS_ABOVE}
          eventhubs:
            bindings:
              consume-in-0:
                consumer:
                  checkpoint:
                    mode: MANUAL
    
    • 对于作为托管标识的凭据,请在 application.yml 中配置以下属性:
    spring:
      cloud:
        azure:
          credential:
            managed-identity-enabled: true
            client-id: ${AZURE_MANAGED_IDENTITY_CLIENT_ID} # Only needed when using a user-assigned managed identity
          eventhubs:
            namespace: ${EVENTHUB_NAMESPACE}
            processor:
              checkpoint-store:
                container-name: ${CONTAINER_NAME}
                account-name: ${ACCOUNT_NAME}
        stream:
          function:
            definition: consume;supply
          bindings:
            consume-in-0:
              destination: ${EVENTHUB_NAME}
              group: ${CONSUMER_GROUP}
            supply-out-0:
              destination: ${THE_SAME_EVENTHUB_NAME_AS_ABOVE}
    
          eventhubs:
            bindings:
              consume-in-0:
                consumer:
                  checkpoint:
                    mode: MANUAL
    
  2. 定义供应商和使用者。

    @Bean
    public Consumer<Message<String>> consume() {
        return message -> {
            Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER);
            LOGGER.info("New message received: '{}', partition key: {}, sequence number: {}, offset: {}, enqueued time: {}",
                    message.getPayload(),
                    message.getHeaders().get(EventHubsHeaders.PARTITION_KEY),
                    message.getHeaders().get(EventHubsHeaders.SEQUENCE_NUMBER),
                    message.getHeaders().get(EventHubsHeaders.OFFSET),
                    message.getHeaders().get(EventHubsHeaders.ENQUEUED_TIME)
            );
    
            checkpointer.success()
                    .doOnSuccess(success -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload()))
                    .doOnError(error -> LOGGER.error("Exception found", error))
                    .block();
        };
    }
    
    @Bean
    public Supplier<Message<String>> supply() {
        return () -> {
            LOGGER.info("Sending message, sequence " + i);
            return MessageBuilder.withPayload("Hello world, " + i++).build();
        };
    }
    
分区支持

将创建一个 PartitionSupplier 具有用户提供的分区信息来配置要发送的消息的分区信息,以下是获取分区 ID 和键的不同优先级的过程:

显示分区支持过程的流程图。 )

Batch 使用者支持
  1. 填写批处理配置选项

    spring:
      cloud:
        stream:
          function:
            definition: consume
          bindings:
            consume-in-0:
              destination: ${AZURE_EVENTHUB_NAME}
              group: ${AZURE_EVENTHUB_CONSUMER_GROUP}
              consumer:
                batch-mode: true
          eventhubs:
            bindings:
              consume-in-0:
                consumer:
                  batch:
                    max-batch-size: 10 # Required for batch-consumer mode
                    max-wait-time: 1m # Optional, the default value is null
                  checkpoint:
                    mode: BATCH # or MANUAL as needed
    
  2. 定义供应商和使用者。

    对于检查点模式 BATCH,可以使用以下代码发送消息并在批处理中使用。

    @Bean
    public Consumer<Message<List<String>>> consume() {
        return message -> {
                for (int i = 0; i < message.getPayload().size(); i++) {
                    LOGGER.info("New message received: '{}', partition key: {}, sequence number: {}, offset: {}, enqueued time: {}",
                            message.getPayload().get(i),
                            ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_PARTITION_KEY)).get(i),
                            ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_SEQUENCE_NUMBER)).get(i),
                            ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_OFFSET)).get(i),
                            ((List<Object>) message.getHeaders().get(EventHubsHeaders.BATCH_CONVERTED_ENQUEUED_TIME)).get(i));
                }
    
            };
    }
    
    @Bean
    public Supplier<Message<String>> supply() {
        return () -> {
            LOGGER.info("Sending message, sequence " + i);
            return MessageBuilder.withPayload("\"test"+ i++ +"\"").build();
        };
    }
    

    对于检查点模式 MANUAL,可以使用以下代码在批处理中发送消息和使用/检查点。

    @Bean
    public Consumer<Message<List<String>>> consume() {
        return message -> {
            for (int i = 0; i < message.getPayload().size(); i++) {
                LOGGER.info("New message received: '{}', partition key: {}, sequence number: {}, offset: {}, enqueued time: {}",
                    message.getPayload().get(i),
                    ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_PARTITION_KEY)).get(i),
                    ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_SEQUENCE_NUMBER)).get(i),
                    ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_OFFSET)).get(i),
                    ((List<Object>) message.getHeaders().get(EventHubHeaders.BATCH_CONVERTED_ENQUEUED_TIME)).get(i));
            }
    
            Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER);
            checkpointer.success()
                        .doOnSuccess(success -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload()))
                        .doOnError(error -> LOGGER.error("Exception found", error))
                        .block();
        };
    }
    
    @Bean
    public Supplier<Message<String>> supply() {
        return () -> {
            LOGGER.info("Sending message, sequence " + i);
            return MessageBuilder.withPayload("\"test"+ i++ +"\"").build();
        };
    }
    

注意

在批处理使用模式下,Spring Cloud Stream 绑定器的默认内容类型是 application/json,因此请确保消息有效负载与内容类型保持一致。 例如,使用包含有效负载的默认内容类型 application/json 接收消息 String 时,有效负载应为 JSON 字符串,用原始字符串文本的双引号括起来。 text/plain对于内容类型,它可以是String直接的对象。 有关更多详细信息,请参阅 Spring Cloud Stream 内容类型协商的官方文档。

错误通道
  • 使用者错误通道

默认情况下,此通道处于打开状态,可以通过以下方式处理错误消息:

// Replace destination with spring.cloud.stream.bindings.input.destination
// Replace group with spring.cloud.stream.bindings.input.group
@ServiceActivator(inputChannel = "{destination}.{group}.errors")
public void consumerError(Message<?> message) {
    LOGGER.error("Handling customer ERROR: " + message);
}
  • 生成者错误通道

默认情况下,此通道未打开。 需要在 application.properties 中添加配置以启用它,如下所示:

spring.cloud.stream.default.producer.errorChannelEnabled=true

可以采用以下方式处理错误消息:

// Replace destination with spring.cloud.stream.bindings.output.destination
@ServiceActivator(inputChannel = "{destination}.errors")
public void producerError(Message<?> message) {
    LOGGER.error("Handling Producer ERROR: " + message);
}
  • 全局默认错误通道

默认情况下会创建一个名为“errorChannel”的全局错误通道,该通道允许用户订阅多个终结点。

@ServiceActivator(inputChannel = "errorChannel")
public void producerError(Message<?> message) {
    LOGGER.error("Handling ERROR: " + message);
}
事件中心消息标头

有关支持的基本 消息标头,请参阅事件中心消息 标头。

多个绑定器支持

使用多个绑定器也支持连接到多个事件中心命名空间。此示例采用连接字符串作为示例。 还支持服务主体和托管标识的凭据,用户可以在每个绑定程序的环境设置中设置相关属性。

  1. 若要使用 EventHubs 的多个绑定器,需要在 application.yml 中配置以下属性

    spring:
      cloud:
        stream:
          function:
            definition: consume1;supply1;consume2;supply2
          bindings:
            consume1-in-0:
              destination: ${EVENTHUB_NAME_01}
              group: ${CONSUMER_GROUP_01}
            supply1-out-0:
              destination: ${THE_SAME_EVENTHUB_NAME_01_AS_ABOVE}
            consume2-in-0:
              binder: eventhub-2
              destination: ${EVENTHUB_NAME_02}
              group: ${CONSUMER_GROUP_02}
            supply2-out-0:
              binder: eventhub-2
              destination: ${THE_SAME_EVENTHUB_NAME_02_AS_ABOVE}
          binders:
            eventhub-1:
              type: eventhubs
              default-candidate: true
              environment:
                spring:
                  cloud:
                    azure:
                      eventhubs:
                        connection-string: ${EVENTHUB_NAMESPACE_01_CONNECTION_STRING}
                        processor:
                          checkpoint-store:
                            container-name: ${CHECKPOINT_CONTAINER_01}
                            account-name: ${CHECKPOINT_STORAGE_ACCOUNT}
                            account-key: ${CHECKPOINT_ACCESS_KEY}
            eventhub-2:
              type: eventhubs
              default-candidate: false
              environment:
                spring:
                  cloud:
                    azure:
                      eventhubs:
                        connection-string: ${EVENTHUB_NAMESPACE_02_CONNECTION_STRING}
                        processor:
                          checkpoint-store:
                            container-name: ${CHECKPOINT_CONTAINER_02}
                            account-name: ${CHECKPOINT_STORAGE_ACCOUNT}
                            account-key: ${CHECKPOINT_ACCESS_KEY}
          eventhubs:
            bindings:
              consume1-in-0:
                consumer:
                  checkpoint:
                    mode: MANUAL
              consume2-in-0:
                consumer:
                  checkpoint:
                    mode: MANUAL
          poller:
            initial-delay: 0
            fixed-delay: 1000
    
  2. 我们需要定义两个供应商和两个使用者

    @Bean
    public Supplier<Message<String>> supply1() {
        return () -> {
            LOGGER.info("Sending message1, sequence1 " + i);
            return MessageBuilder.withPayload("Hello world1, " + i++).build();
        };
    }
    
    @Bean
    public Supplier<Message<String>> supply2() {
        return () -> {
            LOGGER.info("Sending message2, sequence2 " + j);
            return MessageBuilder.withPayload("Hello world2, " + j++).build();
        };
    }
    
    @Bean
    public Consumer<Message<String>> consume1() {
        return message -> {
            Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER);
            LOGGER.info("New message1 received: '{}'", message);
            checkpointer.success()
                    .doOnSuccess(success -> LOGGER.info("Message1 '{}' successfully checkpointed", message))
                    .doOnError(error -> LOGGER.error("Exception found", error))
                    .block();
        };
    }
    
    @Bean
    public Consumer<Message<String>> consume2() {
        return message -> {
            Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER);
            LOGGER.info("New message2 received: '{}'", message);
            checkpointer.success()
                    .doOnSuccess(success -> LOGGER.info("Message2 '{}' successfully checkpointed", message))
                    .doOnError(error -> LOGGER.error("Exception found", error))
                    .block();
        };
    }
    
资源预配

事件中心绑定器支持预配事件中心和使用者组,用户可以使用以下属性启用预配。

spring:
  cloud:
    azure:
      credential:
        tenant-id: ${AZURE_TENANT_ID}
      profile:
        subscription-id: ${AZURE_SUBSCRIPTION_ID}
      eventhubs:
        resource:
          resource-group: ${AZURE_EVENTHUBS_RESOURECE_GROUP}

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

适用于 Azure 服务总线的 Spring Cloud Stream Binder

关键概念

适用于 Azure 服务总线 的 Spring Cloud Stream Binder 为 Spring Cloud Stream Framework 提供绑定实现。 此实现在其基础上使用 Spring Integration Service 总线通道适配器。

计划消息

此绑定程序支持将消息提交到主题以供延迟处理。 用户可以发送带有标头 x-delay 的计划消息,以毫秒为单位发送消息的延迟时间。 消息将在毫秒后 x-delay 传递到相应的主题。

使用者组

服务总线主题提供与 Apache Kafka 类似的使用者组支持,但逻辑略有不同。 此绑定器依赖于 Subscription 主题充当使用者组。

依赖项设置

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-stream-binder-servicebus</artifactId>
</dependency>

或者,还可以使用 Spring Cloud Azure Stream 服务总线初学者,如以下示例中所示:Maven:

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-stream-servicebus</artifactId>
</dependency>

配置

绑定器提供以下 2 部分的配置选项:

连接配置属性

本部分包含用于连接到Azure 服务总线的配置选项。

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅使用 Azure AD 授权访问 ,以确保安全主体已获得访问 Azure 资源的足够权限。

spring-cloud-azure-stream-binder-servicebus 的连接可配置属性:

properties 类型 说明
spring.cloud.azure.servicebus.enabled boolean 是否启用Azure 服务总线。
spring.cloud.azure.servicebus.connection-string 字符串 服务总线命名空间连接字符串值。
spring.cloud.azure.servicebus.namespace 字符串 服务总线命名空间值,它是 FQDN 的前缀。 FQDN 应由 NamespaceName.DomainName 组成
spring.cloud.azure.servicebus.domain-name String Azure 服务总线命名空间值的域名。

注意

常见的 Azure 服务 SDK 配置选项也可用于 Spring Cloud Azure Stream 服务总线绑定器。 支持的配置选项在 “配置”页中引入,可以使用统一前缀或前缀 spring.cloud.azure. 进行 spring.cloud.azure.servicebus.配置。

默认情况下,绑定器还支持 Spring Could Azure 资源管理器。 若要了解如何检索具有未授予 Data 相关角色的安全主体的连接字符串,请参阅 资源管理器示例 了解详细信息。

Azure 服务总线绑定配置属性

以下选项分为四个部分:使用者属性、高级使用者配置、生成者属性和高级生成者配置。

使用者属性

这些属性通过 ServiceBusConsumerProperties.

spring-cloud-azure-stream-binder-servicebus 的使用者可配置属性:

properties 类型 默认 说明
spring.cloud.stream.servicebus.bindings.binding-name.consumer.requeue-rejected boolean false 如果失败的消息路由到 DLQ。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.max-concurrent-calls Integer 1 服务总线处理器客户端应处理的最大并发消息数。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.max-concurrent-sessions Integer Null 在任何给定时间处理的最大并发会话数。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.session-enabled 布尔 null 是否启用会话。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.prefetch-count Integer 0 服务总线处理器客户端的预提取计数。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.sub-queue SubQueue 要连接到的子队列的类型。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.max-auto-lock-renew-duration 持续时间 5m 继续自动续订锁的时间量。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.receive-mode ServiceBusReceiveMode peek_lock 服务总线处理器客户端的接收模式。
spring.cloud.stream.servicebus.bindings.binding-name.consumer.auto-complete 布尔 是否自动解决消息。 如果设置为 false,则会添加一个消息标头 Checkpointer ,使开发人员能够手动解决消息。
高级使用者配置

支持对每个绑定器使用者自定义上述 连接常见的 Azure SDK 客户端 配置,这些使用者可以使用前缀 spring.cloud.stream.servicebus.bindings.<binding-name>.consumer.进行配置。

生成者属性

这些属性通过 ServiceBusProducerProperties.

spring-cloud-azure-stream-binder-servicebus 的生成者可配置属性:

properties 类型 默认 说明
spring.cloud.stream.servicebus.bindings.binding-name.producer.sync boolean false 切换生成者的同步标志。
spring.cloud.stream.servicebus.bindings.binding-name.producer.send-timeout long 10000 发送生成者的超时值。
spring.cloud.stream.servicebus.bindings.binding-name.producer.entity-type ServiceBusEntityType Null 绑定生成者所需的服务总线实体类型。

重要

使用绑定生成器时,需要配置属性 spring.cloud.stream.servicebus.bindings.<binding-name>.producer.entity-type

高级生成者配置

对于每个绑定器生成者,支持上述 连接常见的 Azure SDK 客户端 配置,这些生成者可以使用前缀 spring.cloud.stream.servicebus.bindings.<binding-name>.producer.进行配置。

基本用法

从/到服务总线发送和接收消息
  1. 使用凭据信息填充配置选项。

    • 对于凭据作为连接字符串,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              servicebus:
                connection-string: ${SERVICEBUS_NAMESPACE_CONNECTION_STRING}
            stream:
              function:
                definition: consume;supply
              bindings:
                consume-in-0:
                  destination: ${SERVICEBUS_ENTITY_NAME}
                  # If you use Service Bus Topic, add the following configuration
                  # group: ${SUBSCRIPTION_NAME}
                supply-out-0:
                  destination: ${SERVICEBUS_ENTITY_NAME_SAME_AS_ABOVE}
              servicebus:
                bindings:
                  consume-in-0:
                    consumer:
                      auto-complete: false
                  supply-out-0:
                    producer:
                      entity-type: queue # set as "topic" if you use Service Bus Topic
    
    • 对于凭据即服务主体,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              credential:
                client-id: ${AZURE_CLIENT_ID}
                client-secret: ${AZURE_CLIENT_SECRET}
              profile:
                tenant-id: ${AZURE_TENANT_ID}
              servicebus:
                namespace: ${SERVICEBUS_NAMESPACE}
            stream:
              function:
                definition: consume;supply
              bindings:
                consume-in-0:
                  destination: ${SERVICEBUS_ENTITY_NAME}
                  # If you use Service Bus Topic, add the following configuration
                  # group: ${SUBSCRIPTION_NAME}
                supply-out-0:
                  destination: ${SERVICEBUS_ENTITY_NAME_SAME_AS_ABOVE}
              servicebus:
                bindings:
                  consume-in-0:
                    consumer:
                      auto-complete: false
                  supply-out-0:
                    producer:
                      entity-type: queue # set as "topic" if you use Service Bus Topic
    
    • 对于作为托管标识的凭据,请在 application.yml 中配置以下属性:
        spring:
          cloud:
            azure:
              credential:
                managed-identity-enabled: true
                client-id: ${MANAGED_IDENTITY_CLIENT_ID} # Only needed when using a user-assigned managed identity
              servicebus:
                namespace: ${SERVICEBUS_NAMESPACE}
            stream:
              function:
                definition: consume;supply
              bindings:
                consume-in-0:
                  destination: ${SERVICEBUS_ENTITY_NAME}
                  # If you use Service Bus Topic, add the following configuration
                  # group: ${SUBSCRIPTION_NAME}
                supply-out-0:
                  destination: ${SERVICEBUS_ENTITY_NAME_SAME_AS_ABOVE}
              servicebus:
                bindings:
                  consume-in-0:
                    consumer:
                      auto-complete: false
                  supply-out-0:
                    producer:
                      entity-type: queue # set as "topic" if you use Service Bus Topic
    
  2. 定义供应商和使用者。

    @Bean
    public Consumer<Message<String>> consume() {
        return message -> {
            Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER);
            LOGGER.info("New message received: '{}'", message.getPayload());
    
            checkpointer.success()
                    .doOnSuccess(success -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload()))
                    .doOnError(error -> LOGGER.error("Exception found", error))
                    .block();
        };
    }
    
    @Bean
    public Supplier<Message<String>> supply() {
        return () -> {
            LOGGER.info("Sending message, sequence " + i);
            return MessageBuilder.withPayload("Hello world, " + i++).build();
        };
    }
    
分区键支持

绑定器通过允许在消息标头中设置分区键和会话 ID 来支持 服务总线分区 。 本部分介绍如何设置消息的分区键。

Spring Cloud Stream 提供分区键 SpEL 表达式属性 spring.cloud.stream.bindings.<binding-name>.producer.partition-key-expression。 例如,将此属性设置为 "'partitionKey-' + headers[<message-header-key>]" 并添加一个名为 message-header-key 的标头。 在计算上述表达式以分配分区键时,Spring Cloud Stream 将使用此标头的值。 下面是一个示例生成者代码:

@Bean
public Supplier<Message<String>> generate() {
    return () -> {
        String value = "random payload";
        return MessageBuilder.withPayload(value)
            .setHeader("<message-header-key>", value.length() % 4)
            .build();
    };
}
会话支持

绑定器支持服务总线 的消息会话 。 可以通过消息标头设置消息的会话 ID。

@Bean
public Supplier<Message<String>> generate() {
    return () -> {
        String value = "random payload";
        return MessageBuilder.withPayload(value)
            .setHeader(ServiceBusMessageHeaders.SESSION_ID, "Customize session ID")
            .build();
    };
}

注意

根据 服务总线分区,会话 ID 的优先级高于分区键。 因此,当同时设置和ServiceBusMessageHeaders#PARTITION_KEY (或AzureHeaders#PARTITION_KEY) 标头时ServiceBusMessageHeaders#SESSION_ID,会话 ID 的值最终将用于覆盖分区键的值。

错误通道
  • 使用者错误通道

默认情况下,此通道处于打开状态,默认使用者错误通道处理程序用于在启用时 spring.cloud.stream.servicebus.bindings.<binding-name>.consumer.requeue-rejected 将失败的消息发送到死信队列,否则将放弃失败的消息。

若要自定义使用者错误通道处理程序,可以通过以下方式将自己的错误处理程序注册到相关的使用者错误通道:

// Replace destination with spring.cloud.stream.bindings.input.destination
// Replace group with spring.cloud.stream.bindings.input.group
@ServiceActivator(inputChannel = "{destination}.{group}.errors")
public void consumerError(Message<?> message) {
    LOGGER.error("Handling customer ERROR: " + message);
}
  • 生成者错误通道

默认情况下,此通道未打开。 需要在 application.properties 中添加配置才能启用它,如下所示:

spring.cloud.stream.default.producer.errorChannelEnabled=true

可以按以下方式处理错误消息:

// Replace destination with spring.cloud.stream.bindings.output.destination
@ServiceActivator(inputChannel = "{destination}.errors")
public void producerError(Message<?> message) {
    LOGGER.error("Handling Producer ERROR: " + message);
}
  • 全局默认错误通道

默认情况下,会创建一个名为“errorChannel”的全局错误通道,该通道允许用户订阅多个终结点。

@ServiceActivator(inputChannel = "errorChannel")
public void producerError(Message<?> message) {
    LOGGER.error("Handling ERROR: " + message);
}
服务总线消息标头

有关支持的基本 消息标头,请参阅服务总线消息标头

注意

设置分部键时,消息标头的优先级高于 Spring Cloud Stream 属性。 因此spring.cloud.stream.bindings.<binding-name>.producer.partition-key-expression,只有在未配置任何标头ServiceBusMessageHeaders#SESSION_IDServiceBusMessageHeaders#PARTITION_KEYAzureHeaders#PARTITION_KEY时才会生效。

多个绑定器支持

使用多个绑定器也支持连接到多个服务总线命名空间。 此示例采用连接字符串作为示例。 还支持服务主体和托管标识的凭据,用户可以在每个绑定器的环境设置中设置相关属性。

  1. 若要使用 ServiceBus 的多个绑定器,需要在 application.yml 中配置以下属性

    spring:
      cloud:
        stream:
          function:
            definition: consume1;supply1;consume2;supply2
          bindings:
            consume1-in-0:
              destination: ${SERVICEBUS_TOPIC_NAME}
              group: ${SUBSCRIPTION_NAME}
            supply1-out-0:
              destination: ${SERVICEBUS_TOPIC_NAME_SAME_AS_ABOVE}
            consume2-in-0:
              binder: servicebus-2
              destination: ${SERVICEBUS_QUEUE_NAME}
            supply2-out-0:
              binder: servicebus-2
              destination: ${SERVICEBUS_QUEUE_NAME_SAME_AS_ABOVE}
          binders:
            servicebus-1:
              type: servicebus
              default-candidate: true
              environment:
                spring:
                  cloud:
                    azure:
                      servicebus:
                        connection-string: ${SERVICEBUS_NAMESPACE_01_CONNECTION_STRING}
            servicebus-2:
              type: servicebus
              default-candidate: false
              environment:
                spring:
                  cloud:
                    azure:
                      servicebus:
                        connection-string: ${SERVICEBUS_NAMESPACE_02_CONNECTION_STRING}
          servicebus:
            bindings:
              consume1-in-0:
                consumer:
                  auto-complete: false
              supply1-out-0:
                producer:
                  entity-type: topic
              consume2-in-0:
                consumer:
                  auto-complete: false
              supply2-out-0:
                producer:
                  entity-type: queue
          poller:
            initial-delay: 0
            fixed-delay: 1000
    
  2. 我们需要定义两个供应商和两个消费者

    @Bean
    public Supplier<Message<String>> supply1() {
        return () -> {
            LOGGER.info("Sending message1, sequence1 " + i);
            return MessageBuilder.withPayload("Hello world1, " + i++).build();
        };
    }
    
    @Bean
    public Supplier<Message<String>> supply2() {
        return () -> {
            LOGGER.info("Sending message2, sequence2 " + j);
            return MessageBuilder.withPayload("Hello world2, " + j++).build();
        };
    }
    
    @Bean
    public Consumer<Message<String>> consume1() {
        return message -> {
            Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER);
            LOGGER.info("New message1 received: '{}'", message);
            checkpointer.success()
                    .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload()))
                    .doOnError(e -> LOGGER.error("Error found", e))
                    .block();
        };
    }
    
    @Bean
    public Consumer<Message<String>> consume2() {
        return message -> {
            Checkpointer checkpointer = (Checkpointer) message.getHeaders().get(CHECKPOINTER);
            LOGGER.info("New message2 received: '{}'", message);
            checkpointer.success()
                    .doOnSuccess(s -> LOGGER.info("Message '{}' successfully checkpointed", message.getPayload()))
                    .doOnError(e -> LOGGER.error("Error found", e))
                    .block();
        };
    
    }
    
资源预配

服务总线绑定器支持预配队列、主题和订阅,用户可以使用以下属性启用预配。

spring:
  cloud:
    azure:
      credential:
        tenant-id: ${AZURE_TENANT_ID}
      profile:
        subscription-id: ${AZURE_SUBSCRIPTION_ID}
      servicebus:
        resource:
          resource-group: ${AZURE_SERVICEBUS_RESOURECE_GROUP}
    stream:
      servicebus:
        bindings:
          <binding-name>:
            consumer:
              entity-type: ${SERVICEBUS_CONSUMER_ENTITY_TYPE}

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

Spring JMS 支持

若要使用集成到 Spring JMS 框架中的 JMS API Azure 服务总线。 必须提供Azure 服务总线连接字符串,该连接字符串将分析为 AMQP 代理的登录用户名、密码和远程 URI。

依赖项设置

如果要迁移 Spring JMS 应用程序以使用 Azure 服务总线,请添加以下依赖项。

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-servicebus-jms</artifactId>
</dependency>

配置

使用 Spring JMS 支持时可配置的属性:

properties 说明
spring.jms.servicebus.connection-string Azure 服务总线连接字符串。 如果想要直接提供连接字符串,则应提供。
spring.jms.servicebus.topic-client-id JMS 客户端 ID。 仅适用于 topicJmsListenerContainerFactory 的 bean。
spring.jms.servicebus.idle-timeout 空闲持续时间。
spring.jms.servicebus.pricing-tier Azure 服务总线价格层。
spring.jms.servicebus.listener.reply-pub-sub-domain 答复目标类型是否为主题。
spring.jms.servicebus.listener.phase 指定应启动和停止此容器的阶段。
spring.jms.servicebus.listener.reply-qos-settings 将 QosSettings 配置为在发送回复时使用。
spring.jms.servicebus.listener.subscription-durable 是否使订阅持久化。 仅适用于 topicJmsListenerContainerFactory 的 bean。
spring.jms.servicebus.listener.subscription-shared 是否共享订阅。 仅适用于 topicJmsListenerContainerFactory 的 bean。
spring.jms.servicebus.password AMQP 代理的登录密码
spring.jms.servicebus.pool.block-if-full 是否在请求连接且池已满时阻止。
spring.jms.servicebus.pool.block-if-full-timeout 如果池仍然已满,则引发异常前的阻塞期。
spring.jms.servicebus.pool.enabled 是否应创建 JmsPoolConnectionFactory,而不是 regularConnectionFactory。
spring.jms.servicebus.pool.idle-timeout 连接空闲超时。
spring.jms.servicebus.pool.max-connections 共用连接的最大数目。
spring.jms.servicebus.pool.max-sessions-per-connection 池中每个连接的最大共用会话数。
spring.jms.servicebus.pool.time-between-expiration-check 空闲连接逐出线程运行之间的睡眠时间。
spring.jms.servicebus.pool.use-anonymous-producers 是否仅使用一个匿名“MessageProducer”实例。
spring.jms.servicebus.prefetch-policy.all 此服务总线命名空间中预提取选项的回退值。
spring.jms.servicebus.prefetch-policy.durable-topic-prefetch 持久主题的预提取数。
spring.jms.servicebus.prefetch-policy.queue-browser-prefetch 队列浏览器的预提取数。
spring.jms.servicebus.prefetch-policy.queue-prefetch 队列的预提取数。
spring.jms.servicebus.prefetch-policy.topic-prefetch 主题的预提取数。
spring.jms.servicebus.remote-url AMQP 代理的 URL。
spring.jms.servicebus.username AMQP 代理的登录用户。

注意

短时间内省略 Spring JMS 常规配置。 有关详细信息,请参阅 Spring JMS 文档

基本用法

使用服务总线连接字符串

连接到 Spring JMS 应用程序服务总线的最简单方法是使用连接字符串。

添加以下属性,可以继续操作。

spring:
  jms:
    servicebus:
      connection-string: ${AZURE_SERVICEBUS_CONNECTION_STRING}
      pricing-tier: ${PRICING_TIER}

注意

默认启用 ConnectionFactory 的是 CachingConnectionFactory 添加会话缓存以及 MessageProducer 缓存。 如果要激活连接池功能为 JmsPoolConnectionFactory 之一,应指定true该属性spring.jms.servicebus.pool.enabled。 可以从上述“配置”部分找到具有前缀spring.jms.servicebus.pool.) 的其他池配置选项 (属性。

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

Spring Native 支持

Spring Native 支持使用 GraalVM本机映像 编译器将 Spring Boot 应用程序编译为本机可执行文件。 本机映像将带来许多优势,例如即时启动、即时峰值性能以及减少内存消耗。 某些 Spring Cloud Azure 功能还可以受益于 Spring Native 支持。 目标是,Spring Cloud Azure 应用程序可以生成为本机映像,而无需进行任何代码修改。 有关详细信息,请参阅 Spring Native 文档

支持

Spring Cloud Azure 已针对 GraalVM 和 Spring Native 进行验证,并提供 beta 版本支持。 如果项目正在使用这些受支持的依赖项,则可以在项目中尝试它,并在 Spring Cloud Azure 上出现问题时 引发 bug参与拉取请求 。 有关详细信息,请参阅 Spring Native 文档中的 “支持 ”部分。

Spring Native

Spring Cloud Azure 4.1.0-beta.1 已针对 Spring Native 0.11.4 和 GraalVM 22.0.0进行测试。

Spring Cloud Azure Native

注意

Spring Native 0.11.4 已针对 Spring Cloud Azure Native Configuration 4.0.0-beta.1进行测试。

Spring Cloud Azure 提供了一个依赖项 spring-cloud-azure-native-configuration ,它是 Spring Cloud Azure 库的 Spring Native 配置的扩展。 Spring Native AOT 插件将合并 spring-native-configuration 应用程序并将其 spring-cloud-azure-native-configuration 生成为本机可执行文件。 除了添加依赖项外,不需要对使用 Spring Cloud Azure 库的代码进行任何额外的修改,这些依赖项仅适用于 Spring Cloud Azure 库中的代码。

支持以下功能:

  • Azure 应用程序配置客户端自动配置
  • Azure 事件中心客户端自动配置
  • Azure 密钥保管库证书客户端自动配置
  • Azure 密钥保管库机密客户端自动配置
  • Azure 存储 Blob 客户端自动配置
  • Azure 存储文件共享客户端自动配置
  • Azure 存储队列客户端自动配置
  • spring Integration for Azure 事件中心
  • Azure 存储队列的 Spring Integration

限制

Spring Native 的 Spring Cloud Azure 支持仍处于早期阶段,并将继续更新。 尚不支持以下功能:

  • Azure Cosmos 客户端自动配置
  • Azure 服务总线客户端自动配置
  • 适用于 Azure Cache for Redis 的 Spring Data
  • 适用于 Azure Cosmos 的 Spring Data
  • 适用于Azure 事件中心的 Spring Cloud Stream
  • 适用于 Azure 服务总线 的 Spring Cloud Stream
  • Spring Kafka for Azure 事件中心
  • spring Integration for Azure 服务总线

注意

Spring Native 不支持所有本机映像选项。 有关详细信息,请参阅 Spring Native 文档的 “本机映像选项” 部分。

警告

未验证 Spring Cloud Azure 4.1.0-beta.1 是否基于 Gradle Kotlin 生成本机可执行文件。

项目设置

Spring Cloud Azure 应用程序可以按照 Spring Native 文档 的入门 部分的说明启用 Spring Native 支持。 唯一需要的其他处理是将以下依赖项添加到 POM 文件。

提示

依赖项 com.azure.spring:spring-cloud-azure-native-configuration 未在 . 中 com.azure.spring:spring-cloud-azure-dependencies管理。

<dependency>
  <groupId>com.azure.spring</groupId>
  <artifactId>spring-cloud-azure-native-configuration</artifactId>
  <version>4.0.0-beta.1</version>
</dependency>

生成本机应用程序

以下部分介绍了使用 Spring Cloud Azure 库构建 Spring Boot 本机应用程序的两种主要方法。

使用 Buildpack 进行生成

可以按如下所示生成本机应用程序:

mvn spring-boot:build-image

有关详细信息,请参阅 Spring Native 文档中的 Buildpacks 入门 部分。

使用本机生成工具进行生成

可以使用以下命令生成本机应用程序:

mvn -Pnative -DskipTests package

有关详细信息,请参阅 Spring Native 文档的 本机生成工具 入门部分。

运行本机应用程序

以下部分介绍了运行本机可执行文件的两种主要方法。

提示

假设项目项目 ID 为 spring-cloud-azure-sample 项目版本 0.0.1-SNAPSHOT,则可以通过以下方式之一指定自定义映像名称:

  • 如果使用的是 Cloud Native Buildpacks,请使用 imageSpring Boot 插件中的 ->name->custom-image-name 配置元素。
  • 如果使用 GraalVM Native Build Tools,请使用 imageNameSpring Boot 插件中的 ->custom-image-name 配置元素。

使用 Buildpacks 运行

若要运行应用程序,可以使用 docker 常规方法,如以下示例所示:

docker run --rm -p 8080:8080 spring-cloud-azure-sample:0.0.1-SNAPSHOT

使用本机生成工具运行

若要运行应用程序,请使用以下命令:

target\spring-cloud-azure-sample

示例

有关详细信息,请参阅 GitHub 上的 Spring Native 与 Spring Cloud Azure 存储 Blob 初学者配合使用

下面是支持 Spring Native 的其他已验证示例。 有关详细信息,请参阅 GitHub 上的基于 Spring Native 的运行示例

库项目 ID 支持的示例项目
spring-cloud-azure-starter-appconfiguration appconfiguration-client
spring-cloud-azure-starter-eventhubs eventhubs-client
spring-cloud-azure-starter-integration-eventhubs storage-queue-integrationstorage-queue-operation
spring-cloud-azure-starter-integration-storage-queue appconfiguration-client
spring-cloud-azure-starter-keyvault-secrets property-sourcesecret-client
spring-cloud-azure-starter-storage-blob storage-blob-sample
spring-cloud-azure-starter-storage-file-share storage-file-sample
spring-cloud-azure-starter-storage-queue storage-queue-client

MySQL 支持

Azure Database for MySQL是由 MySQL 社区版提供支持的关系数据库服务。 你可以在 Azure 中使用单一服务器或灵活服务器来托管 MySQL 数据库。 它是一种完全托管的数据库即服务产品/服务,可以处理具有可预测性能和动态可伸缩性的任务关键型工作负荷。

从版本4.5.0-beta.1开始,Spring Cloud Azure 支持各种类型的凭据,用于Azure Database for MySQL单台服务器进行身份验证。

支持的 MySQL 版本

初学者的当前版本应使用Azure Database for MySQL单一服务器版本5.78.0

核心功能

无密码连接

无密码连接使用 Azure Active Directory (Azure AD) 身份验证连接到 Azure 服务,而无需将任何凭据存储在应用程序、其配置文件或环境变量中。 Azure AD 身份验证是一种使用 Azure AD 中定义的标识连接到Azure Database for MySQL的机制。 通过 Azure AD 身份验证,可以在一个中心位置集中管理数据库用户标识和其他 Microsoft 服务,从而简化权限管理。

工作原理

Spring Cloud Azure 将首先根据应用程序身份验证配置生成以下类型的凭据之一:

  • ClientSecretCredential
  • ClientCertificateCredential
  • UsernamePasswordCredential
  • ManagedIdentityCredential
  • DefaultAzureCredential

如果未找到这些类型的凭据, DefaultAzureCredential 将从应用程序属性、环境变量、托管标识或 IDE 获取凭据。 有关详细信息,请参阅 Spring Cloud Azure 身份验证 部分。

以下高级关系图总结了如何使用具有 Azure Database for MySQL 的 OAuth 凭据身份验证进行身份验证。 箭头表示通信路径。

显示 MySQL 的 Azure Active Directory 身份验证的关系图。

配置

Spring Cloud Azure for MySQL 支持以下两个级别的配置选项:

  1. 全局身份验证配置选项 credential 以及 profile 前缀为 spring.cloud.azure.

  2. Spring Cloud Azure for MySQL 常见配置选项。

下表显示了 Spring Cloud Azure for MySQL 常见配置选项:

名称 说明
spring.datasource.azure.passwordless-enabled 是否启用支持 Azure 标识令牌凭据。 默认值是 false秒。
spring.datasource.azure.credential.client-certificate-password 证书文件的密码。
spring.datasource.azure.credential.client-certificate-path 使用 Azure 执行服务主体身份验证时要使用的 PEM 证书文件的路径。
spring.datasource.azure.credential.client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。 这是一个旧属性。
spring.datasource.azure.credential.client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。 这是一个旧属性。
spring.datasource.azure.credential.managed-identity-enabled 是否允许托管标识通过 Azure 进行身份验证。 如果 为 trueclient-id 已设置,将使用客户端 ID 作为用户分配的托管标识客户端 ID。 默认值是 false秒。
spring.datasource.azure.credential.password 在 Azure 中执行用户名/密码身份验证时要使用的密码。
spring.datasource.azure.credential.username 使用 Azure 执行用户名/密码身份验证时要使用的用户名。
spring.datasource.azure.profile.cloud 类型 要连接到的 Azure 云的名称。
spring.datasource.azure.profile.environment.active-directory-endpoint 要连接到的 Azure Active Directory 终结点。
spring.datasource.azure.profile.tenant-id Azure 资源的租户 ID。

依赖项设置

将以下依赖项添加到项目。 这将自动在项目中以可传递方式包含 spring-boot-starter 依赖项。

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-jdbc-mysql</artifactId>
</dependency>

注意

如果要使用无密码连接,则必须添加依赖项版本 4.5.0-beta.1

请记住添加 BOM spring-cloud-azure-dependencies 以及上述依赖项。 有关详细信息,请参阅 “入门 ”部分。

基本用法

以下部分显示了经典 Spring Boot 应用程序使用方案。

重要

无密码连接使用 Azure AD 身份验证。 若要使用 Azure AD 身份验证,应首先设置 Azure AD 管理员用户。 只有 Azure AD 管理员用户可以创建和启用基于 Azure AD 的身份验证的用户。 有关详细信息,请参阅 “创建 MySQL 服务器并设置管理员用户 ”部分。

在没有密码的情况下在本地连接到 Azure MySQL

  1. 若要创建用户并授予权限,请参阅 “创建 MySQL 非管理员用户并授予权限 ”部分。

  2. application.yml 文件中配置以下属性:

    spring:
      datasource:
        url: jdbc:mysql://${AZURE_MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/${AZURE_MYSQL_DATABASE_NAME}
        username: ${AZURE_MYSQL_AD_NON_ADMIN_USERNAME}@${AZURE_MYSQL_SERVER_NAME}
        azure:
          passwordless-enabled: true
    

使用服务主体连接到 Azure MySQL

  1. 为服务主体创建 Azure AD 用户并授予权限。

    1. 首先,使用以下命令设置一些环境变量。

      export AZURE_MYSQL_AZURE_AD_SP_USERID=$(az ad sp list --display-name <service_principal-name> --query '[0].appId' -otsv)
      export AZURE_MYSQL_AZURE_AD_SP_USERNAME=<YOUR_MYSQL_AZURE_AD_USERNAME>
      export AZURE_MYSQL_SERVER_NAME=<YOUR_MYSQL_SERVER_NAME>
      export AZURE_MYSQL_DATABASE_NAME=<YOUR_MYSQL_DATABASE_NAME>
      export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName -o tsv)
      
    2. 然后,创建名为 create_ad_user_sp.sql 的 SQL 脚本以创建非管理员用户。 添加以下内容并将其保存在本地:

      cat << EOF > create_ad_user_sp.sql
      SET aad_auth_validate_oids_in_tenant = OFF;
      CREATE AADUSER '$AZURE_MYSQL_AZURE_AD_SP_USERNAME' IDENTIFIED BY '$AZURE_MYSQL_AZURE_AD_SP_USERID';
      GRANT ALL PRIVILEGES ON $AZURE_MYSQL_DATABASE_NAME.* TO '$AZURE_MYSQL_AZURE_AD_SP_USERNAME'@'%';
      FLUSH privileges;
      EOF
      
    3. 使用以下命令运行 SQL 脚本以创建 Azure AD 非管理员用户:

      mysql -h $AZURE_MYSQL_SERVER_NAME.mysql.database.azure.com --user $CURRENT_USERNAME@$AZURE_MYSQL_SERVER_NAME --enable-cleartext-plugin --password=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken` < create_ad_user_sp.sql
      
    4. 现在,使用以下命令删除临时 SQL 脚本文件:

      rm create_ad_user_sp.sql
      
  2. application.yml 文件中配置以下属性:

    spring:
      cloud:
        azure:
          credential:
            client-id: ${AZURE_CLIENT_ID}
            client-secret: ${AZURE_CLIENT_SECRET}
          profile:
            tenant-id: ${AZURE_TENANT_ID}
      datasource:
        url: jdbc:mysql://${AZURE_MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/${AZURE_MYSQL_DATABASE_NAME}
        username: ${AZURE_MYSQL_AD_SP_USERNAME}@${AZURE_MYSQL_SERVER_NAME}
        azure:
          passwordless-enabled: true
    

在 Azure Spring Apps 中使用托管标识连接到 Azure MySQL

  1. 若要启用托管标识,请参阅使用Azure 门户部分创建托管标识

  2. 若要授予权限,请参阅“ 将角色分配到托管标识 ”部分。

  3. application.yml 文件中配置以下属性:

    spring:
      datasource:
        url: jdbc:mysql://${AZURE_MYSQL_SERVER_NAME}.mysql.database.azure.com:3306/${AZURE_MYSQL_DATABASE_NAME}
        username: ${AZURE_MYSQL_AD_MI_USERNAME}@${AZURE_MYSQL_SERVER_NAME}
        azure:
          passwordless-enabled: true
    

PostgreSQL 支持

Azure Database for PostgreSQL是基于开源 Postgres 数据库引擎的关系数据库服务。 它是完全托管的数据库即服务,能够处理任务关键型工作负荷,具有可预测的性能、安全性、高可用性和动态可伸缩性。

从版本4.5.0-beta.1开始,Spring Cloud Azure 支持各种类型的凭据,用于Azure Database for PostgreSQL单一服务器进行身份验证。

支持的 PostgreSQL 版本

初学者的当前版本应使用Azure Database for PostgreSQL单一服务器版本1011

核心功能

无密码连接

无密码连接使用 Azure Active Directory (Azure AD) 身份验证连接到 Azure 服务,而无需将任何凭据存储在应用程序、其配置文件或环境变量中。 Azure AD 身份验证是一种使用 Azure AD 中定义的标识连接到Azure Database for PostgreSQL的机制。 通过 Azure AD 身份验证,可以在一个中心位置集中管理数据库用户标识和其他 Microsoft 服务,从而简化权限管理。

工作原理

Spring Cloud Azure 将首先根据应用程序身份验证配置生成以下类型的凭据之一:

  • ClientSecretCredential
  • ClientCertificateCredential
  • UsernamePasswordCredential
  • ManagedIdentityCredential
  • DefaultAzureCredential

如果未找到这些类型的凭据, DefaultAzureCredential 将从应用程序属性、环境变量、托管标识或 IDE 获取凭据。 有关详细信息,请参阅 Spring Cloud Azure 身份验证 部分。

以下高级关系图总结了如何使用具有 Azure Database for PostgreSQL 的 OAuth 凭据身份验证进行身份验证。 箭头表示通信路径。

显示 PostgreSQL 的 Azure Active Directory 身份验证的关系图。

配置

Spring Cloud Azure for PostgreSQL 支持以下两个级别的配置选项:

  1. 全局身份验证配置选项 credential 以及 profile 前缀为 spring.cloud.azure.

  2. Spring Cloud Azure for PostgreSQL 常见配置选项。

下表显示了 Spring Cloud Azure for PostgreSQL 常见配置选项:

名称 说明
spring.datasource.azure.passwordless-enabled 是否启用支持 Azure 标识令牌凭据。 默认值是 false秒。
spring.datasource.azure.credential.client-certificate-password 证书文件的密码。
spring.datasource.azure.credential.client-certificate-path 使用 Azure 执行服务主体身份验证时要使用的 PEM 证书文件的路径。
spring.datasource.azure.credential.client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。 这是一个旧属性。
spring.datasource.azure.credential.client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。 这是一个旧属性。
spring.datasource.azure.credential.managed-identity-enabled 是否允许托管标识通过 Azure 进行身份验证。 如果 为 trueclient-id 已设置,将使用客户端 ID 作为用户分配的托管标识客户端 ID。 默认值是 false秒。
spring.datasource.azure.credential.password 在 Azure 中执行用户名/密码身份验证时要使用的密码。
spring.datasource.azure.credential.username 使用 Azure 执行用户名/密码身份验证时要使用的用户名。
spring.datasource.azure.profile.cloud 类型 要连接到的 Azure 云的名称。
spring.datasource.azure.profile.environment.active-directory-endpoint 要连接到的 Azure Active Directory 终结点。
spring.datasource.azure.profile.tenant-id Azure 资源的租户 ID。

依赖项设置

将以下依赖项添加到项目。 这将自动在项目中以可传递方式包含 spring-boot-starter 依赖项。

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-jdbc-postgresql</artifactId>
</dependency>

注意

如果要使用无密码连接,则必须添加依赖项版本 4.5.0-beta.1

请记住添加 BOM spring-cloud-azure-dependencies 以及上述依赖项。 有关详细信息,请参阅 “入门 ”部分。

基本用法

以下部分显示了经典 Spring Boot 应用程序使用方案。

重要

无密码连接使用 Azure AD 身份验证。 若要使用 Azure AD 身份验证,应首先设置 Azure AD 管理员用户。 只有 Azure AD 管理员用户可以创建和启用基于 Azure AD 的身份验证的用户。 有关详细信息,请参阅 “创建 PostgreSQL 服务器并设置管理员用户 ”部分。

在没有密码的情况下在本地连接到 Azure PostgreSQL

  1. 若要创建用户并授予权限,请参阅 “创建 PostgreSQL 非管理员用户并授予权限 ”部分。

  2. application.yml 文件中配置以下属性:

    spring:
      datasource:
        url: jdbc:postgresql://${AZ_DATABASE_NAME}.postgres.database.azure.com:5432/demo?sslmode=require
        username: ${AZ_POSTGRESQL_AD_NON_ADMIN_USERNAME}@${AZ_DATABASE_NAME}
        azure:
          passwordless-enabled: true
    

使用服务主体连接到 Azure PostgreSQL

  1. 将角色分配给服务主体:

    1. 创建名为 create_ad_user_sp.sql 的 SQL 脚本以创建非管理员用户。 添加以下内容并将其保存在本地:

      重要

      请确保 <service-principal-name> 已存在于 Azure AD 租户中,否则无法创建非管理员用户。

      export AZ_POSTGRESQL_AD_SP_USERNAME=<service-principal-name>
      
      cat << EOF > create_ad_user_mi.sql
      SET aad_validate_oids_in_tenant = off;
      CREATE ROLE "$AZ_POSTGRESQL_AD_SP_USERNAME" WITH LOGIN IN ROLE azure_ad_user;
      GRANT ALL PRIVILEGES ON DATABASE $AZ_DATABASE_NAME TO "$AZ_POSTGRESQL_AD_SP_USERNAME";
      EOF
      
    2. 使用以下命令运行 SQL 脚本以创建 Azure AD 非管理员用户:

      psql "host=$AZ_DATABASE_NAME.postgres.database.azure.com user=$CURRENT_USERNAME@$AZ_DATABASE_NAME dbname=demo port=5432 password=`az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken` sslmode=require" < create_ad_user_sp.sql
      
    3. 现在,使用以下命令删除临时 SQL 脚本文件:

      rm create_ad_user_sp.sql
      
  2. application.yml 文件中配置以下属性:

    spring:
      cloud:
        azure:
          credential:
            client-id: ${AZURE_CLIENT_ID}
            client-secret: ${AZURE_CLIENT_SECRET}
          profile:
            tenant-id: ${AZURE_TENANT_ID}
      datasource:
        url: jdbc:postgresql://${AZ_DATABASE_NAME}.postgres.database.azure.com:5432/demo?sslmode=require
        username: ${AZ_POSTGRESQL_AD_SP_USERNAME}@${AZ_DATABASE_NAME}
        azure:
          passwordless-enabled: true
    

在 Azure Spring Apps 中使用托管标识连接到 Azure PostgreSQL

  1. 若要启用托管标识,请参阅使用Azure 门户部分创建托管标识

  2. 若要授予权限,请参阅 “将角色分配给托管标识 ”部分。

  3. application.yml 文件中配置以下属性:

    spring:
      cloud:
        azure:
          credential:
            managed-identity-enabled: true
            client-id: ${AZURE_CLIENT_ID}
      datasource:
        url: jdbc:postgresql://${AZ_DATABASE_SERVER_NAME}.postgres.database.azure.com:5432/demo?sslmode=require
        username: ${AZ_POSTGRESQL_AD_MI_USERNAME}@${AZ_DATABASE_SERVER_NAME}
        azure:
          passwordless-enabled: true
    

Kafka 支持

从版本 4.3.0 开始,Spring Cloud Azure for Kafka 支持各种类型的凭据进行身份验证并连接到Azure 事件中心。

支持的 Kafka 版本

初学者的当前版本应与使用 Java 8 或更高版本的 Apache Kafka 客户端 2.0.0 兼容。

支持的身份验证类型

支持以下身份验证类型:

  • 纯连接字符串身份验证
    • 直接连接字符串身份验证
    • 基于 ARM 的连接字符串身份验证
  • OAuth 凭据身份验证
    • 托管标识身份验证
    • 用户名/密码身份验证
    • 服务主体身份验证
    • DefaultAzureCredential身份验证

工作原理

OAuth 凭据身份验证

本部分介绍 Spring Cloud Azure OAuth 身份验证的总体工作流。

Spring Cloud Azure 将首先根据应用程序身份验证配置生成以下类型的凭据之一:

  • ClientSecretCredential
  • ClientCertificateCredential
  • UsernamePasswordCredential
  • ManagedIdentityCredential

如果未找到这些类型的凭据,则凭据 DefaultAzureTokenCredential 链将用于从应用程序属性、环境变量、托管标识或 IDE 获取凭据。 有关详细信息,请参阅 Spring Cloud Azure 身份验证 部分。

纯连接字符串身份验证

对于连接字符串身份验证模式,可以直接使用连接字符串身份验证,也可以使用 Azure 资源管理器检索连接字符串。 有关用法的详细信息,请参阅 连接字符串身份验证的基本用法 部分。

注意

由于版本为 4.3.0,因此已弃用连接字符串身份验证,以支持 OAuth 身份验证。

配置

通过 OAuth 身份验证使用 Kafka 支持时可配置的属性

Spring Cloud Azure for Kafka 支持以下两个级别的配置选项:

  1. Spring Cloud Azure for Event Hubs Kafka 属性。
  2. 全局身份验证配置选项 credential 以及 profile 前缀为 spring.cloud.azure.
  3. 特定于 Kafka 的级别配置。 Kafka 级别配置也适用于 Spring Boot 和 Spring Cloud Stream 绑定器commonconsumerproduceradmin,这些配置具有不同前缀。

全局属性通过 com.azure.spring.cloud.autoconfigure.context.AzureGlobalProperties. 特定于 Kafka 的属性通过 org.springframework.boot.autoconfigure.kafka.KafkaProperties (Spring Boot) 公开, (org.springframework.cloud.stream.binder.kafka.properties.KafkaBinderConfigurationProperties Spring Cloud Stream 绑定器) 。

以下列表显示所有受支持的配置选项。

  • Spring Cloud Azure for Event Hubs Kafka 属性。

    • 财产: spring.cloud.azure.eventhubs.kafka.enabled
    • 说明:是否为 Kafka 启用与 Azure 事件中心 的无凭据连接,默认值为 true
  • Spring Cloud Azure 全局身份验证配置选项

    • 前缀: spring.cloud.azure
    • 支持的选项: spring.cloud.azure.credential.*spring.cloud.azure.profile.*

    有关全局配置选项的完整列表,请参阅 “全局属性 ”部分。

  • Spring Boot Kafka 通用配置

    • 前缀: spring.kafka.properties.azure
    • 示例: spring.kafka.properties.azure.credential.*
  • Spring Kafka 使用者配置选项

    • 前缀: spring.kafka.consumer.properties.azure
    • 示例: spring.kafka.consumer.properties.azure.credential.*
  • Spring Kafka 生成者配置选项

    • 前缀: spring.kafka.producer.properties.azure
    • 示例: spring.kafka.producer.properties.azure.credential.*
  • Spring Kafka 管理员配置选项

    • 前缀: spring.kafka.admin.properties.azure
    • 示例: spring.kafka.admin.properties.azure.credential.*
  • Spring Cloud Stream Kafka Binder 通用配置

    • 前缀: spring.cloud.stream.kafka.binder.configuration.azure
    • 示例: spring.cloud.stream.kafka.binder.configuration.azure.credential.*
  • Spring Cloud Stream Kafka Binder 使用者配置

    • 前缀: spring.cloud.stream.kafka.binder.consumer-properties.azure
    • 示例: spring.cloud.stream.kafka.binder.consumer-properties.azure.credential.*
  • Spring Cloud Stream Kafka Binder 生成者配置

    • 前缀: spring.cloud.stream.kafka.binder.producer-properties.azure
    • 示例: spring.cloud.stream.kafka.binder.producer-properties.azure.credential.*
  • Spring Cloud Stream Kafka Binder 管理员配置

    • 前缀:不支持,应使用 Spring Boot Kafka 常用或管理员配置。

下表显示了 Spring Boot Kafka 常见配置选项:

名称 说明
spring.kafka.properties.azure.credential.client-certificate-password 证书文件的密码。
spring.kafka.properties.azure.credential.client-certificate-path 使用 Azure 执行服务主体身份验证时要使用的 PEM 证书文件的路径。
spring.kafka.properties.azure.credential.client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。 这是一个旧属性。
spring.kafka.properties.azure.credential.client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。 这是一个旧属性。
spring.kafka.properties.azure.credential.managed-identity-enabled 是否允许托管标识通过 Azure 进行身份验证。 如果 为 trueclient-id 已设置,将使用客户端 ID 作为用户分配的托管标识客户端 ID。 默认值是 false秒。
spring.kafka.properties.azure.credential.password 在 Azure 中执行用户名/密码身份验证时要使用的密码。
spring.kafka.properties.azure.credential.username 使用 Azure 执行用户名/密码身份验证时要使用的用户名。
spring.kafka.properties.azure.profile.environment.active-directory-endpoint 要连接到的 Azure Active Directory 终结点。
spring.kafka.properties.azure.profile.tenant-id Azure 资源的租户 ID。

注意

不同级别的配置选项应用以下规则。 更具体的配置选项的优先级高于常见配置选项。 例如: 。

  • Spring Kafka 常见配置选项取代全局选项。
  • Spring Kafka 使用者配置选项取代了常见选项。
  • Spring Kafka 生成者配置选项取代了常见选项。
  • Spring Kafka 管理员配置选项取代了常用选项。
  • Spring Cloud Stream Kafka Binder 选项与上述选项类似。

将 Kafka 支持用于纯连接字符串身份验证时可配置的属性

下表显示了适用于 Kafka 的 Spring Boot 事件中心常见配置选项:

properties 说明
spring.cloud.azure.eventhubs.kafka.enabled 是否启用 Azure 事件中心 Kafka 支持。 默认值为 true
spring.cloud.azure.eventhubs.connection-string Azure 事件中心连接字符串。 如果要直接提供连接字符串,请提供此值。
spring.cloud.azure.eventhubs.namespace Azure 事件中心命名空间。 若要通过 Azure 资源管理器检索连接信息,请提供此值。
spring.cloud.azure.eventhubs.resource.resource-group Azure 事件中心命名空间的资源组。 若要通过 Azure 资源管理器检索连接信息,请提供此值。
spring.cloud.azure.profile.subscription-id 订阅的 ID。 若要通过 Azure 资源管理器检索连接信息,请提供此值。

依赖项设置

将以下依赖项添加到项目。 这会自动在项目中以可传递方式包含 spring-boot-starter 依赖项。

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter</artifactId>
</dependency>

注意

请记住将 BOM spring-cloud-azure-dependencies 与上述依赖项一起添加。 有关详细信息,请参阅 “入门” 部分。

基本用法

以下部分显示了经典 Spring Boot 应用程序使用方案。

使用 OAuth 身份验证

使用 Spring Cloud Azure for Kafka 提供的 OAuth 身份验证时,可以使用上述配置配置配置特定凭据。 或者,可以选择配置任何凭据,在这种情况下,Spring Cloud Azure 将从环境中加载凭据。 本部分介绍从 Azure CLI 环境或 Azure Spring Apps 托管环境加载凭据的用法。

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅“ 使用 Azure Active Directory 授权访问 ”部分,确保安全主体已获得访问 Azure 资源的足够权限。

以下部分介绍了将不同的 Spring 生态系统库与 OAuth 身份验证配合使用的方案。

Spring Kafka 应用程序支持

本部分介绍使用 Spring Kafka 或 Spring Integration Kafka 库的 Spring Boot 应用程序的使用方案。

依赖项设置
<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
<!-- Using Spring Kafka library only-->
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
    <version>{version}</version><!--Need to be set, for example:2.8.6-->
</dependency>
<!-- Using Spring Integration library only -->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-kafka</artifactId>
    <version>{version}</version><!--Need to be set, for example:5.5.12-->
</dependency>

配置更新

若要使用 OAuth 身份验证,只需指定事件中心终结点,如以下示例所示:

spring.kafka.bootstrap-servers=<NAMESPACENAME>.servicebus.windows.net:9093
Spring Cloud Stream 绑定器 Kafka 应用程序支持

本部分介绍使用 Spring Cloud Stream 绑定器 Kafka 库的 Spring Boot 应用程序的使用方案。

依赖项设置
<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-kafka</artifactId>
    <version>{version}</version><!--Need to be set, for example:3.2.3-->
</dependency>
配置

若要使用 OAuth 身份验证,只需指定事件中心终结点,如以下示例所示:

spring.cloud.stream.kafka.binder.brokers=<NAMESPACENAME>.servicebus.windows.net:9093

注意

如果使用版本4.3.0,请不要忘记设置spring.cloud.stream.binders.<kafka-binder-name>.environment.spring.main.sources=com.azure.spring.cloud.autoconfigure.kafka.AzureKafkaSpringCloudStreamConfiguration属性以启用整个 OAuth 身份验证工作流,其中kafka-binder-namekafka默认位于单个 Kafka 绑定器应用程序中。 AzureKafkaSpringCloudStreamConfiguration配置指定用于启用 Azure 标识的 OAuth 安全参数KafkaBinderConfigurationPropertiesKafkaOAuth2AuthenticateCallbackHandler

对于之后 4.4.0的版本,此属性将自动为每个 Kafka 绑定器环境添加,因此无需手动添加此属性。

示例

请参阅 GitHub 上的 azure-spring-boot-samples 存储库。

使用连接字符串身份验证

可以直接使用连接字符串身份验证,也可以使用 Azure 资源管理器检索连接字符串。

注意

自版本 4.3.0 起,连接字符串身份验证已弃用,支持 OAuth 身份验证。

依赖项设置

如果要迁移 Apache Kafka 应用程序以使用 Kafka Azure 事件中心,请添加以下依赖项。

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter</artifactId>
</dependency>

若要使用 Azure 资源管理器检索连接字符串,请添加以下依赖项:

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-resourcemanager</artifactId>
</dependency>
配置
直接使用事件中心连接字符串

连接到 Kafka 事件中心的最简单方法是使用连接字符串。 只需添加以下属性即可。

spring.cloud.azure.eventhubs.connection-string=${AZURE_EVENTHUBS_CONNECTION_STRING}
使用 Azure 资源管理器检索连接字符串

如果不想在应用程序中配置连接字符串,可以使用 Azure 资源管理器检索连接字符串。 若要使用 Azure 资源管理器进行身份验证,还可以使用存储在 Azure CLI 或其他本地开发工具(如 Visual Studio Code 或 Intellij IDEA)中的凭据。 或者,如果应用程序部署到 Azure 云,则可以使用托管标识。 只需确保主体具有读取资源元数据的足够权限。

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅“ 使用 Azure Active Directory 授权访问 ”部分,确保已向安全主体授予访问 Azure 资源的足够权限。

若要使用 Azure 资源管理器检索连接字符串,只需添加以下属性即可。

spring:
  cloud:
    azure:
      profile:
        subscription-id: ${AZURE_SUBSCRIPTION_ID}
      eventhubs:
        namespace: ${AZURE_EVENTHUBS_NAMESPACE}
        resource:
          resource-group: ${AZURE_EVENTHUBS_RESOURCE_GROUP}

示例

请参阅 GitHub 上的 azure-spring-boot-samples 存储库。

Redis 支持

使用 Spring Redis 库连接到Azure Cache for Redis。 通过添加spring-cloud-azure-starterspring-cloud-azure-resourcemanager添加到应用程序,可以通过 Azure 资源管理器和自动配置 Redis 属性来读取Azure Cache for Redis连接信息。

依赖项设置

如果要使用 Spring Cloud Azure Redis 支持,请使用 Redis 将以下依赖项添加到 Spring Boot 应用程序。

<dependencies>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-resourcemanager</artifactId>
    </dependency>
</dependencies>

配置

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅使用 Azure AD 授权访问 ,以确保安全主体已获得访问 Azure 资源的足够权限。

使用 Redis 支持时可配置的属性:

properties 说明 默认值 必需
spring.cloud.azure.redis.enabled 是否启用Azure Cache for Redis。
spring.cloud.azure.redis.name Azure Cache for Redis实例名称。
spring.cloud.azure.redis.resource.resource-group Azure Cache for Redis的资源组。
spring.cloud.azure.profile.subscription-id 订阅的 ID。

注意

Azure 资源管理器身份验证还需要身份验证信息。 应在前缀spring.cloud.azure下配置资源管理器的凭据相关配置。 有关详细信息,请参阅 “身份验证 ”部分。

基本用法

添加以下属性,可以继续操作。

spring.cloud.azure.redis.name=${AZURE_CACHE_REDIS_NAME}
spring.cloud.azure.redis.resource.resource-group=${AZURE_CACHE_REDIS_RESOURCE_GROUP}

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

Azure 资源管理器

Azure 资源管理器 (ARM) 是适用于 Azure 的部署和管理服务。 它提供了一个管理层,用于在 Azure 帐户中创建、更新和删除资源。 Spring Cloud Azure 资源管理器可帮助预配资源或检索资源元数据。

依赖项设置

<dependency>
  <groupId>com.azure.spring</groupId>
  <artifactId>spring-cloud-azure-resourcemanager</artifactId>
</dependency>

配置

注意

如果选择使用安全主体对 Azure Active Directory 进行身份验证和授权以访问 Azure 资源,请参阅使用 Azure AD 授权访问 ,以确保安全主体已授予访问 Azure 资源的足够权限。

spring-cloud-azure-resourcemanager 的可配置属性:

properties 说明
spring.cloud.azure.resource-manager.enabled 是否启用资源管理器。 默认为 true。
spring.cloud.azure.credential.client-id 使用 Azure 执行服务主体身份验证时要使用的客户端 ID。
spring.cloud.azure.credential.client-secret 使用 Azure 执行服务主体身份验证时要使用的客户端密码。
spring.cloud.azure.credential.client-certificate-path 使用 Azure 执行服务主体身份验证时要使用的 PEM 证书文件的路径。
spring.cloud.azure.credential.client-certificate-password 证书文件的密码。
spring.cloud.azure.credential.username 使用 Azure 执行用户名/密码身份验证时要使用的用户名。
spring.cloud.azure.credential.password 执行用户名/密码身份验证时要使用的密码。
spring.cloud.azure.credential.managed-identity-enabled 是否启用托管标识。
spring.cloud.azure.profile.cloud-type 要连接到的 Azure 云的名称。
spring.cloud.azure.profile.environment.active-directory-endpoint 要连接到的 Azure Active Directory 终结点进行身份验证。
spring.cloud.azure.profile.subscription-id 连接到 Azure 资源时要使用的订阅 ID。
spring.cloud.azure.profile.tenant-id Azure 资源的租户 ID。
spring.cloud.azure.azure-service.namespace 用于预配资源的 Azure 服务的命名空间。
spring.cloud.azure.azure-service.resource.resource-group 包含 Azure 服务资源的资源组。

基本用法

Spring Cloud Azure 资源管理器可与特定的 Spring Cloud Azure 初学者协作,以检索连接信息(如连接字符串)以连接到 Azure 服务。 它还可与第三方库一起 spring-cloud-azure-starter 检索用户名/密码等元数据,并完成身份验证。 有关详细信息,请参阅 Kafka 支持Redis 支持 部分。

例如,若要检索 Azure 服务的连接字符串,开发人员可以使用服务主体作为凭据进行身份验证和检索连接字符串。 配置如下所示。 至少应为所提供的服务主体分配关联命名空间的角色 Contributor 。 请参阅 使用 Azure AD 授权访问 ,确保主体已授予访问 Azure 资源的足够权限。

spring:
  cloud:
    azure:
      credential:
        client-id: ${AZURE_CLIENT_ID}
        client-secret: ${AZURE_CLIENT_SECRET}
      profile:
        tenant-id: ${AZURE_TENANT_ID}
        subscription-id: ${AZURE_SUBSCRIPTION_ID}
      <azure-service>:
        namespace: ${SERVICEBUS_NAMESPACE}
        resource:
          resource-group: ${RESOURCE_GROUP}

示例

有关更多详细信息,请参阅 azure-spring-boot-samples

配置属性

若要查看所有 Spring Cloud Azure 相关配置属性的列表,请参阅 Spring Cloud Azure 参考附录

附录