该版本仍在开发中,尚未被视为稳定版本。如需获取最新的稳定版本,请使用Spring Vault 4.0.1spring-doc.cadn.net.cn

响应式基础设施

本节涵盖了使用Spring Vault进行响应式编程支持的基本信息。spring-doc.cadn.net.cn

什么是响应式编程?

<code> <p>简单来说,响应式编程是关于非阻塞性应用程序的,它们是异步的和事件驱动的,并且需要少量线程来在JVM内部进行垂直扩展(即,在JVM内),而不是水平扩展(即,通过集群)。</p> </code>spring-doc.cadn.net.cn

<p>响应式应用程序的一个关键方面是反压的概念,这是一种确保生产者不会淹没消费者的机制。例如,在从数据库到HTTP响应的响应式组件管道中,当HTTP连接太慢时,数据存储库也可以放慢速度或完全停止,直到网络容量释放。</p>spring-doc.cadn.net.cn

响应式金库客户端

Spring Vault的响应式客户端支持是建立在可组合的身份验证步骤和Spring Vault的功能性ReactiveVaultClient之上,该功能提供了一个完全非阻塞、事件驱动的HTTP客户端。spring-doc.cadn.net.cn

它公开了VaultTokenSupplier作为验证HTTP请求的提供商VaultToken, 和ReactiveVaultOperations作为主要入口点。 VaultEndpointClientOptionsSSL的核心配置在 各种客户端实现中被重用。spring-doc.cadn.net.cn

ReactiveVaultTemplate,位于包 org.springframework.vault.core 中,是 Spring 的响应式 Vault 支持的核心类,提供了与 Vault 交互的丰富功能集。该模板提供了读取、写入和删除 Vault 中数据的便捷操作,并在您的域对象和 Vault 数据之间提供映射。spring-doc.cadn.net.cn

Once configured, ReactiveVaultTemplate 是线程安全的,并且可以在多个实例中重复使用。

Vault 文档与领域类之间的映射是通过委托给 WebClient 及其编解码器来完成的。spring-doc.cadn.net.cn

ReactiveVaultTemplate 类实现了接口 ReactiveVaultOperations。 尽可能地,ReactiveVaultOperations 上的方法按照 Vault API 的方法命名,以便让熟悉 Vault API 和 CLI 的开发者感到亲切。例如,你会发现诸如 \"write\"、\"delete\" 和 \"read\" 等方法。 设计目标是尽可能简化在使用 Vault API 和 ReactiveVaultOperations 之间的过渡。两者之间的一个主要区别在于,ReactiveVaultOperations 可以传递领域对象,而不是 JSON 键值对。spring-doc.cadn.net.cn

ReactiveVaultTemplate 中使用的路径(以及可从其访问的接口)被认为是相对于 VaultEndpoint 的。完全限定的 URI 路径可以用于在认证上下文中访问 Vault 集群成员。为防止不必要的完整 URI 访问,请确保在将路径传递给 ReactiveVaultTemplate 之前对其进行清理。spring-doc.cadn.net.cn

引用ReactiveVaultTemplate实例上的操作的首选方法是通过其接口ReactiveVaultOperations

未由ReactiveVaultTemplate显式暴露的功能,您可以使用多个执行回调方法之一来访问底层API。执行回调将为您提供对WebClient对象的引用。 有关更多信息,请参见执行回调部分。spring-doc.cadn.net.cn

现在让我们看看如何在 Spring 容器的上下文中使用 Vault 的示例。spring-doc.cadn.net.cn

注册和配置 Spring Vault Bean

使用 Spring Vault 不需要 Spring 上下文。然而,注册在托管上下文中的 ReactiveVaultTemplateVaultTokenSupplier 实例将参与 生命周期事件 由 Spring IoC 容器提供。这在应用程序关闭时用于处理活动的 Vault 会话非常有用。您还可以受益于在整个应用程序中重用相同的 ReactiveVaultTemplate 实例。spring-doc.cadn.net.cn

Spring Vault 带有一个支持的配置类,该类提供了在 Spring 上下文中使用的 bean 定义。应用程序配置类通常从 AbstractVaultConfiguration 扩展而来,并且需要提供特定于环境的其他详细信息。spring-doc.cadn.net.cn

Extending from AbstractVaultConfiguration 需要实现 ` VaultEndpoint vaultEndpoint()` 和 ClientAuthentication clientAuthentication() 方法。spring-doc.cadn.net.cn

使用基于 Java 的 bean 元数据注册 Spring Vault 对象 示例 1
@Configuration
public class AppConfig extends AbstractReactiveVaultConfiguration {

    /**
     * Specify an endpoint for connecting to Vault.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return new VaultEndpoint();                            (1)
    }

    /**
     * Configure a client authentication.
     * Please consider a more secure authentication method
     * for production use.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("…");                   (2)
    }
}
1 创建一个新的VaultEndpoint,默认指向https://localhost:8200
2 本示例使用 TokenAuthentication 来快速上手。 详见 [vault.core.authentication] 以获取有关支持的认证方法的详细信息。

会话管理

Spring Vault 需要一个Tokens来验证 Vault 请求。
有关身份验证的详细信息,请参见 [vault.core.authentication]
响应式客户端需要一个非阻塞的Tokens提供者,其契约定义在 VaultTokenSupplier 中。Tokens可以是静态的,也可以通过 声明的身份验证流程 获得。
Vault 登录不应在每次经过身份验证的 Vault 交互时都发生,而应在一个会话中保持会话Tokens。
此方面由实现 ReactiveSessionManager 的会话管理器处理,例如 ReactiveLifecycleAwareSessionManagerspring-doc.cadn.net.cn

执行回调

所有 Spring 模板类的一个共同设计特点是,所有功能都被引导到模板的 execute 回调方法之一中。这有助于确保执行一致性地进行异常处理和任何可能需要的资源管理。虽然在 JDBC 和 JMS 的情况下这种需求更大,与 Vault 相比仍然提供了一个用于访问和记录的单一位置。因此,使用 execute 回调是访问 Vault API 以执行我们尚未作为 ReactiveVaultTemplate 方法公开的不常见操作的首选方式。spring-doc.cadn.net.cn

以下是执行回调方法的列表。spring-doc.cadn.net.cn

  • <T> T doWithVault (Function<WebClient, ? extends T> clientCallback) 构建一个响应式序列,给定的 WebClient,允许在没有会话上下文的情况下与 Vault 进行交互。spring-doc.cadn.net.cn

  • <T> T doWithSession (Function<WebClient, ? extends T> clientCallback) 组合成一个响应式序列,给定的 WebClient,允许在经过身份验证的会话中与 Vault 进行交互。spring-doc.cadn.net.cn

这是一个使用回调初始化 Vault 的示例:spring-doc.cadn.net.cn

reactiveVaultOperations.doWithVault(webClient -> {

    return webClient.put()
                    .uri("sys/init")
                    .syncBody(request)
                    .retrieve()
                    .toEntity(VaultInitializationResponse.class);
});