参考文档

7. 保险库支持

Vault 支持包含广泛的功能,总结如下。spring-doc.cadn.net.cn

  • 使用基于 Java 的 @Configuration 类的 Spring 配置支持spring-doc.cadn.net.cn

  • VaultTemplate辅助类,提高生产力执行常见 Vault作。包括 Vault 响应和 POJO 之间的集成对象映射。spring-doc.cadn.net.cn

对于大多数任务,您会发现自己使用VaultTemplate利用 丰富的通信功能。VaultTemplate是寻找的地方 访问功能,例如从 Vault 读取数据或 管理命令。VaultTemplate还提供了回调方法,方便您 获取低级 API 项目,例如RestTemplate沟通 直接与 Vault 一起使用。spring-doc.cadn.net.cn

7.1. 依赖项

如果您想在项目中使用 Spring Vault,请声明对spring-vault-core人工制品。spring-doc.cadn.net.cn

示例 1.声明对 Spring Vault 的依赖项
<dependencies>
    <dependency>
        <groupId>org.springframework.vault</groupId>
        <artifactId>spring-vault-core</artifactId>
    </dependency>
</dependencies>

查找兼容版本的 Spring Vault 依赖项的最简单方法是检查spring-vault-parent. 我们通常建议升级到 Jackson、HTTP 客户端和云提供商 SDK 的最新依赖项。spring-doc.cadn.net.cn

7.2. Spring框架

当前版本的 Spring Vault 需要 Spring Framework 的版本 6.0.11 或更高版本。 这些模块还可以与该次要版本的旧错误修复版本一起使用。 但是,强烈建议使用该代的最新版本。spring-doc.cadn.net.cn

8. 入门

Spring Vault 支持需要 Vault 0.6 或更高版本以及 Java SE 6 或更高版本。 引导设置工作环境的一种简单方法是创建一个 STS 中基于 Spring 的项目。spring-doc.cadn.net.cn

首先,您需要设置一个正在运行的 Vault 服务器。 有关如何启动 Vault 实例的说明,请参阅 Vaultspring-doc.cadn.net.cn

要在 STS 中创建 Spring 项目,请转到文件→新建→ Spring 模板项目→简单的 Spring 实用程序项目→ 出现提示时按是。然后输入一个项目和包名称,例如org.spring.vault.example.spring-doc.cadn.net.cn

然后将以下内容添加到pom.xmldependencies 部分。spring-doc.cadn.net.cn

示例 2.添加 Spring Vault 依赖项
<dependencies>

  <!-- other dependency elements omitted -->

  <dependency>
    <groupId>org.springframework.vault</groupId>
    <artifactId>spring-vault-core</artifactId>
    <version>3.0.4</version>
  </dependency>

</dependencies>

如果您使用的是里程碑或候选版本,则还需要添加 Spring 的位置 里程碑存储库到您的 Mavenpom.xml与您的同一级别<dependencies/>元素。spring-doc.cadn.net.cn

<repositories>
  <repository>
    <id>spring-milestone</id>
    <name>Spring Maven MILESTONE Repository</name>
    <url>https://repo.spring.io/libs-milestone</url>
  </repository>
</repositories>

如果您使用的是 SNAPSHOT,则还需要添加 Spring 的位置 快照存储库到您的 Mavenpom.xml与您的同一级别<dependencies/>元素。spring-doc.cadn.net.cn

<repositories>
  <repository>
    <id>spring-snapshot</id>
    <name>Spring Maven SNAPSHOT Repository</name>
    <url>https://repo.spring.io/snapshot</url>
  </repository>
</repositories>

创建一个简单的Secrets类以持久化:spring-doc.cadn.net.cn

示例 3.映射的数据对象
package org.spring.vault.example;

public class Secrets {

    String username;
    String password;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
}

以及要运行的主要应用程序spring-doc.cadn.net.cn

示例 4.使用 Spring Vault 的示例应用程序
package org.springframework.vault.example;

import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.support.VaultResponseSupport;

public class VaultApp {

    public static void main(String[] args) {

        VaultTemplate vaultTemplate = new VaultTemplate(new VaultEndpoint(),
                new TokenAuthentication("00000000-0000-0000-0000-000000000000"));

        Secrets secrets = new Secrets();
        secrets.username = "hello";
        secrets.password = "world";

        vaultTemplate.write("secret/myapp", secrets);

        VaultResponseSupport<Secrets> response = vaultTemplate.read("secret/myapp", Secrets.class);
        System.out.println(response.getData().getUsername());

        vaultTemplate.delete("secret/myapp");
    }
}

即使在这个简单的例子中,也没有什么需要注意的spring-doc.cadn.net.cn

  • 您可以实例化 Spring Vault 的中心类,VaultTemplate,使用org.springframework.vault.client.VaultEndpointobject 和ClientAuthentication. 您无需启动 Spring Context 即可使用 Spring Vault。spring-doc.cadn.net.cn

  • Vault 应配置为00000000-0000-0000-0000-000000000000以运行此应用程序。spring-doc.cadn.net.cn

  • 映射器适用于标准 POJO 对象,无需任何 其他元数据(尽管您可以选择提供该信息)。spring-doc.cadn.net.cn

  • 映射约定可以使用字段访问。请注意Secrets类只有 getters。spring-doc.cadn.net.cn

  • 如果构造函数参数名称与存储文档的字段名称匹配, 它们将用于实例化对象。spring-doc.cadn.net.cn

9. VaultTemplate简介

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

配置完成后,VaultTemplate是线程安全的,可以跨多个实例。

Vault 文档和域类之间的映射是通过委托给RestTemplate. Spring Web 支持提供了映射基础设施。spring-doc.cadn.net.cn

VaultTemplateclass 实现接口VaultOperations. 在尽可能多的方法中VaultOperations以方法在 Vault API 上可用,以使现有 Vault 开发人员熟悉该 API习惯了 API 和 CLI。例如,您会找到诸如“write”、“delete”、“read”和“revoke”之类的方法。设计目标是尽可能轻松地在Vault API 和VaultOperations. 之间的主要区别两个 API 是VaultOperations可以传递域对象,而不是JSON 键值对。spring-doc.cadn.net.cn

引用VaultTemplate实例 是通过其接口VaultOperations.

虽然有很多方便的方法VaultTemplate轻松帮助您 如果您需要直接访问 Vault API 才能访问,请执行常见任务 功能未由VaultTemplate您可以使用以下选项之一 多个执行回调方法来访问底层 API。执行回调 将为您提供对RestOperations对象。 有关更多信息,请参阅执行回调部分。spring-doc.cadn.net.cn

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

9.1. 注册和配置 Spring Vault Bean

使用 Spring Vault 不需要 Spring Context。但是,实例VaultTemplateSessionManager在托管上下文中注册将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在 应用程序关闭。您还可以从重复使用相同的VaultTemplate实例。spring-doc.cadn.net.cn

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

扩展自AbstractVaultConfiguration需要实现 ' VaultEndpoint vaultEndpoint()' 和ClientAuthentication clientAuthentication()方法。spring-doc.cadn.net.cn

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

    /**
     * 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快速入门。 有关支持的身份验证方法的详细信息,请参阅身份验证方法。
示例 6.注册 Spring Vault 应用注入的属性
@Configuration
public class AppConfig extends AbstractVaultConfiguration {

    @Value("${vault.uri}")
    URI vaultUri;

    /**
     * Specify an endpoint that was injected as URI.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return VaultEndpoint.from(vaultUri);                          (1)
    }

    /**
     * Configure a Client Certificate authentication.
     * {@link RestOperations} can be obtained from {@link #restOperations()}.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new ClientCertificateAuthentication(restOperations()); (2)
    }
}
1 VaultEndpoint可以使用各种工厂方法进行构造,例如from(URI uri)VaultEndpoint.create(String host, int port).
2 依赖项ClientAuthentication方法可以从AbstractVaultConfiguration或由您的配置提供。
在某些情况下,创建自定义配置类可能会很麻烦。 看看EnvironmentVaultConfiguration允许使用 来自现有属性源的属性和 Spring 的Environment.阅读更多 在EnvironmentVaultConfiguration.

9.2. 会话管理

Spring Vault 需要一个ClientAuthentication以登录并访问 Vault。 有关身份验证的详细信息,请参阅身份验证方法。 Vault 登录不应在每次经过身份验证的 Vault 交互时进行,但 必须在整个会话中重复使用。这方面由SessionManager实现。一个SessionManager决定它的频率 获取一个Tokens,关于撤销和续订。Spring Vault 带有两种实现:spring-doc.cadn.net.cn

  • SimpleSessionManager:仅从提供的ClientAuthentication无需刷新和吊销spring-doc.cadn.net.cn

  • LifecycleAwareSessionManager:这SessionManagerschedules Tokens renew,如果Tokens是可续订的,并在处置时撤销登录Tokens。 续订计划时使用AsyncTaskExecutor.LifecycleAwareSessionManager如果使用AbstractVaultConfiguration.spring-doc.cadn.net.cn

9.3. 使用EnvironmentVaultConfiguration

Spring Vault 包括EnvironmentVaultConfiguration从 Spring 的Environment和一组预定义的 属性键。EnvironmentVaultConfiguration支持经常应用的配置。其他配置通过派生自最合适的配置类来支持。包括EnvironmentVaultConfiguration@Import(EnvironmentVaultConfiguration.class)到现有 基于 Java 的配置类,并通过任何 Spring 的PropertySources.spring-doc.cadn.net.cn

示例 7.将 EnvironmentVaultConfiguration 与属性文件一起使用
基于 Java 的配置类
@PropertySource("vault.properties")
@Import(EnvironmentVaultConfiguration.class)
public class MyConfiguration{
}
vault.properties
vault.uri=https://localhost:8200
vault.token=00000000-0000-0000-0000-000000000000

特定于身份验证的属性键spring-doc.cadn.net.cn

没有配置选项。spring-doc.cadn.net.cn

9.4. 执行回调

所有 Spring 模板类的一个共同设计特征是所有功能都路由到模板执行回调方法之一。 这有助于确保执行异常和可能需要的任何资源管理的一致性。 虽然 JDBC 和 JMS 对此的需求比 Vault 大得多,但它仍然提供了一个访问和日志记录的位置。 因此,使用执行回调是访问 Vault API 的首选方式 执行我们未作为方法公开的不常见作VaultTemplate.spring-doc.cadn.net.cn

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

  • <T> T doWithVault (RestOperationsCallback<T> callback)执行给定的RestOperationsCallback,允许使用RestOperations无需会话。spring-doc.cadn.net.cn

  • <T> T doWith会话 (RestOperationsCallback<T> callback)执行给定的RestOperationsCallback,允许在经过身份验证的会话中与 Vault 进行交互。spring-doc.cadn.net.cn

下面是一个使用ClientCallback初始化 Vault:spring-doc.cadn.net.cn

vaultOperations.doWithVault(new RestOperationsCallback<VaultInitializationResponse>() {

  @Override
  public VaultInitializationResponse doWithRestOperations(RestOperations restOperations) {

    ResponseEntity<VaultInitializationResponse> exchange = restOperations
                       .exchange("/sys/init", HttpMethod.PUT,
                                 new HttpEntity<Object>(request),
                                 VaultInitializationResponse.class);

    return exchange.getBody();
    }
});

10. 支持 Vault 的秘密引擎

Spring Vault 附带了多个扩展来支持 Vault 的各种秘密引擎。spring-doc.cadn.net.cn

具体来说,Spring Vault 附带了以下扩展:spring-doc.cadn.net.cn

您可以通过以下方法使用所有其他后端VaultTemplate直接 (VaultTemplate.read(…),VaultTemplate.write(…)).spring-doc.cadn.net.cn

10.1. 键值版本 1(“未版本控制的密钥”)

kvsecrets 引擎用于在为 Vault 配置的物理存储中存储任意密钥。spring-doc.cadn.net.cn

运行kvsecrets 引擎,仅保留密钥的最新写入值。 非版本控制 kv 的好处是减小了每个键的存储大小,因为不会存储额外的元数据或历史记录。 此外,发送到以这种方式配置的后端的请求性能更高,因为存储调用更少,并且任何给定请求都没有锁定。spring-doc.cadn.net.cn

Spring Vault 附带一个专用的键值 API,用于封装各个键值 API 实现之间的差异。VaultKeyValueOperations遵循 Vault CLI 设计。 这是 Vault 的主要命令行工具,提供诸如vault kv get,vault kv put等等。spring-doc.cadn.net.cn

您可以通过指定版本和挂载路径,将此 API 与键值引擎版本一起使用。 以下示例使用键值版本 1:spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultKeyValueOperations keyValueOperations = operations.opsForKeyValue("secret",
							VaultKeyValueOperationsSupport.KeyValueBackend.KV_1);

keyValueOperations.put("elvis", Collections.singletonMap("password", "409-52-2002"));

VaultResponse read = keyValueOperations.get("elvis");
read.getRequiredData().get("social-security-number");

VaultKeyValueOperations支持所有键值作,例如put,get,delete,list.spring-doc.cadn.net.cn

或者,可以通过VaultTemplate由于其直接映射和简单使用,AS 键和响应直接映射到输入和输出键。 以下示例说明了在mykey. 这kvsecrets 引擎安装在secret:spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());

operations.write("secret/elvis", Collections.singletonMap("social-security-number", "409-52-2002"));

VaultResponse read = operations.read("secret/elvis");
read.getRequiredData().get("social-security-number");

您可以在 Vault 参考文档中找到有关 Vault 键值版本 1 API 的更多详细信息。spring-doc.cadn.net.cn

10.2. 键值版本 2(“版本化密钥”)

您可以运行kvsecrets 引擎中的两个版本之一。 本节介绍使用版本 2。当运行kv后端密钥可以保留可配置数量的版本。 您可以检索旧版本的元数据和数据。 此外,您可以使用检查和设置作来避免无意中覆盖数据。spring-doc.cadn.net.cn

键值版本 1(“未版本控制的密钥”)类似,Spring Vault 附带一个专用的键值 API,用于封装各个键值 API 实现之间的差异。 Spring Vault 附带一个专用的键值 API,用于封装各个键值 API 实现之间的差异。VaultKeyValueOperations遵循 Vault CLI 设计。 这是 Vault 的主要命令行工具,提供诸如vault kv get,vault kv put,依此类推。spring-doc.cadn.net.cn

您可以通过指定版本和挂载路径,将此 API 与键值引擎版本一起使用。 以下示例使用键值版本 2:spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultKeyValueOperations keyValueOperations = operations.opsForKeyValue("secret",
							VaultKeyValueOperationsSupport.KeyValueBackend.KV_2);

keyValueOperations.put("elvis", Collections.singletonMap("social-security-number", "409-52-2002"));

VaultResponse read = keyValueOperations.get("elvis");
read.getRequiredData().get("social-security-number");

VaultKeyValueOperations支持所有键值作,例如put,get,delete,list.spring-doc.cadn.net.cn

您还可以与版本化键值 API 的详细信息进行交互。如果您想获取特定密钥或需要访问元数据,这将非常有用。spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultVersionedKeyValueOperations versionedOperations = operations.opsForVersionedKeyValue("secret");

Versioned.Metadata metadata = versionedOperations.put("elvis",							(1)
					Collections.singletonMap("social-security-number", "409-52-2002"));

Version version = metadata.getVersion();												(2)

Versioned<Object> ssn = versionedOperations.get("elvis", Version.from(42));				(3)

Versioned<SocialSecurityNumber> mappedSsn = versionedOperations.get("elvis",			(4)
											Version.from(42), SocialSecurityNumber.class);

Versioned<Map<String,String>> versioned = Versioned.create(Collections					(5)
						.singletonMap("social-security-number", "409-52-2002"),
						Version.from(42));

versionedOperations.put("elvis", version);
1 将机密存储在elvissecret/安装。
2 将数据存储在版本控制的后端中会返回元数据,例如版本号。
3 版本化键值 API 允许检索由版本号标识的特定版本。
4 版本控制的键值密钥可以映射到值对象中。
5 使用 CAS 更新版本控制的密钥时,输入必须引用以前获取的版本。

使用kvv2 secrets 引擎通过VaultTemplate是可能的。 这不是最方便的方法,因为 API 提供了一种不同的上下文路径方法以及输入/输出的表示方式。 具体来说,与实际密钥的交互需要包装和解包数据部分,并引入一个data/挂载和密钥之间的路径段。spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());

operations.write("secret/data/elvis", Collections.singletonMap("data",
			Collections.singletonMap("social-security-number", "409-52-2002")));

VaultResponse read = operations.read("secret/data/ykey");
Map<String,String> data = (Map<String, String>) read.getRequiredData().get("data");
data.get("social-security-number");

您可以在 Vault 参考文档中找到有关 Vault 键值版本 2 API 的更多详细信息。spring-doc.cadn.net.cn

10.3. PKI(公钥基础设施)

pkisecrets 引擎通过实现证书颁发机构作来表示证书的后端。spring-doc.cadn.net.cn

PKI 机密引擎生成动态 X.509 证书。 使用此密钥引擎,服务可以获取证书,而无需经历通常的手动过程,即生成私钥和 CSR、提交给 CA 以及等待验证和签名过程完成。 Vault 的内置身份验证和授权机制提供了验证功能。spring-doc.cadn.net.cn

Spring Vault 支持通过VaultPkiOperations. 所有其他 PKI 功能都可以通过VaultOperations.spring-doc.cadn.net.cn

以下示例简要说明了如何颁发和吊销证书的用法:spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultPkiOperations pkiOperations = operations.opsForPki("pki");

VaultCertificateRequest request = VaultCertificateRequest.builder()								(1)
			.ttl(Duration.ofHours(48))
			.altNames(Arrays.asList("prod.dc-1.example.com", "prod.dc-2.example.com"))
			.withIpSubjectAltName("1.2.3.4")
			.commonName("hello.example.com")
			.build();

VaultCertificateResponse response = pkiOperations.issueCertificate("production", request); 		(2)
CertificateBundle certificateBundle = response.getRequiredData();

KeyStore keyStore = certificateBundle.createKeyStore("my-keystore");							(3)

KeySpec privateKey = certificateBundle.getPrivateKeySpec();										(4)
X509Certificate certificate = certificateBundle.getX509Certificate();
X509Certificate caCertificate = certificateBundle.getX509IssuerCertificate();

pkiOperations.revoke(certificateBundle.getSerialNumber());										(5)
1 使用VaultCertificateRequest架构工人。
2 向 Vault 申请证书。 Vault 充当证书颁发机构,并使用已签名的 X.509 证书进行响应。 实际响应是CertificateBundle.
3 您可以直接将生成的证书作为包含公钥和私钥以及颁发者证书的 Java 密钥库获取。KeyStore 具有广泛的用途,这使得此格式适合配置(例如 HTTP 客户端、数据库驱动程序或 SSL 保护的 HTTP 服务器)。
4 CertificateBundle允许直接通过 Java Cryptography Extension API 访问私钥以及公共证书和颁发者证书。
5 一旦证书不再使用(或被泄露),您可以通过其序列号吊销它。 Vault 将吊销的证书包含在其 CRL 中。

您可以在 Vault 参考文档中找到有关 Vault PKI 密钥 API 的更多详细信息。spring-doc.cadn.net.cn

10.4. Tokens身份验证后端

此后端是一个身份验证后端,不与实际密钥交互。相反,它允许访问Tokens管理。您可以在身份验证方法一章中阅读有关基于Tokens的身份验证的更多信息。spring-doc.cadn.net.cn

token身份验证方法是内置的,并在/auth/token. 它允许用户使用Tokens进行身份验证,以及创建新Tokens、按Tokens撤销机密等。spring-doc.cadn.net.cn

当任何其他身份验证方法返回身份时,Vault 核心会调用Tokens方法为该身份创建新的唯一Tokens。spring-doc.cadn.net.cn

您还可以使用Tokens存储绕过任何其他身份验证方法。您可以直接创建Tokens,也可以对Tokens执行各种其他作,例如续订和吊销。spring-doc.cadn.net.cn

Spring Vault 使用此后端来续订和撤销配置的身份验证方法提供的会话Tokens。spring-doc.cadn.net.cn

以下示例演示了如何从应用程序中请求、续订和撤销 Vault Tokens:spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultTokenOperations tokenOperations = operations.opsForToken();

VaultTokenResponse tokenResponse = tokenOperations.create();                          (1)
VaultToken justAToken = tokenResponse.getToken();

VaultTokenRequest tokenRequest = VaultTokenRequest.builder().withPolicy("policy-for-myapp")
									.displayName("Access tokens for myapp")
									.renewable()
									.ttl(Duration.ofHours(1))
									.build();

VaultTokenResponse appTokenResponse = tokenOperations.create(tokenRequest);          (2)
VaultToken appToken = appTokenResponse.getToken();

tokenOperations.renew(appToken);                                                     (3)

tokenOperations.revoke(appToken);                                                    (4)
1 通过应用角色默认值创建Tokens。
2 使用构建器 API,您可以为要请求的Tokens定义细粒度设置。 请求Tokens将返回一个VaultToken,用作 Vault Tokens的值对象。
3 您可以通过Tokens API 续订Tokens。通常,这是通过SessionManager以跟踪 Vault 会话Tokens。
4 如果需要,可以通过Tokens API 撤销Tokens。通常,这是通过SessionManager以跟踪 Vault 会话Tokens。

您可以在 Vault 参考文档中找到有关 Vault Tokens身份验证方法 API 的更多详细信息。spring-doc.cadn.net.cn

10.5. 传输后端

传输密钥引擎处理传输中数据的加密功能。 Vault 不存储发送到此密钥引擎的数据。 也可以看作是“密码即服务”或“加密即服务”。 传输机密引擎还可以对数据进行签名和验证,生成数据的哈希值和 HMAC,并充当随机字节源。spring-doc.cadn.net.cn

传输的主要用例是加密来自应用程序的数据,同时仍将加密数据存储在某些主数据存储中。 这减轻了应用程序开发人员正确加密和解密的负担,并将负担推给了 Vault 的运营商。spring-doc.cadn.net.cn

Spring Vault 支持广泛的 Transit作:spring-doc.cadn.net.cn

内部所有作transit以键为中心。 Transit 引擎支持键和各种键类型的版本控制。 请注意,键类型可能会对可以使用的作施加限制。spring-doc.cadn.net.cn

以下示例演示如何创建密钥以及如何加密和解密数据:spring-doc.cadn.net.cn

VaultOperations operations = new VaultTemplate(new VaultEndpoint());
VaultTransitOperations transitOperations = operations.opsForTransit("transit");

transitOperations.createKey("my-aes-key", VaultTransitKeyCreationRequest.ofKeyType("aes128-gcm96"));	(1)

String ciphertext = transitOperations.encrypt("my-aes-key", "plaintext to encrypt");					(2)

String plaintext = transitOperations.decrypt("my-aes-key", ciphertext);									(3)
1 首先,我们需要一把钥匙。 每个键都需要指定类型。aes128-gcm96支持加密、解密、密钥派生和收敛加密,本例需要加解密。
2 接下来,我们将String包含应加密的纯文本。 输入String使用默认的Charset将字符串编码为其二进制表示形式。 请求Tokens将返回一个VaultToken,用作 Vault Tokens的值对象。 这encrypt方法返回 Base64 编码的密文,通常以vault:.
3 要将密文解密为纯文本,请调用decrypt方法。 它解密密文并返回一个String使用默认字符集进行解码。

前面的示例使用简单的字符串进行加密作。虽然这是一种简单的方法,但它存在字符集配置错误的风险,并且不是二进制安全的。当纯文本对图像、压缩数据或二进制数据结构等数据使用二进制表示时,需要二进制安全。spring-doc.cadn.net.cn

要加密和解密二进制数据,请使用PlaintextCiphertextvalue 对象,可以保存二进制值:spring-doc.cadn.net.cn

byte [] plaintext = "plaintext to encrypt".getBytes();

Ciphertext ciphertext = transitOperations.encrypt("my-aes-key", Plaintext.of(plaintext));			(1)

Plaintext decrypttedPlaintext = transitOperations.decrypt("my-aes-key", ciphertext);				(2)
1 假设一个键my-aes-key已经到位,我们正在加密Plaintext对象。 作为回报,encrypt方法返回一个Ciphertext对象。
2 Ciphertextobject 可以直接用于解密,并返回一个Plaintext对象。

PlaintextCiphertext带有上下文对象,VaultTransitContext. 它用于为收敛加密提供随机数值,并为上下文值提供使用密钥派生。spring-doc.cadn.net.cn

Transit 允许对纯文本进行签名并验证给定纯文本的签名。签名作需要非对称密钥,通常使用椭圆曲线加密或 RSA。spring-doc.cadn.net.cn

签名使用公钥/私钥拆分来确保真实性。
签名者使用其私钥创建签名。否则,任何人都可以以您的名义签署消息。验证者使用公钥部分来验证签名。实际签名通常是一个哈希值。

在内部,使用私钥计算和加密哈希以创建最终签名。验证解密签名消息,计算自己的纯文本哈希值,并比较两个哈希值以检查签名是否有效。
byte [] plaintext = "plaintext to sign".getBytes();

transitOperations.createKey("my-ed25519-key", VaultTransitKeyCreationRequest.ofKeyType("ed25519"));	(1)

Signature signature = transitOperations.sign("my-ed25519-key", Plaintext.of(plaintext));			(2)

boolean valid = transitOperations.verify("my-ed25519-key", Plaintext.of(plaintext), signature);		(3)
1 签名需要非对称密钥。您可以使用任何椭圆曲线加密或 RSA 密钥类型。创建密钥后,您就具备了创建签名的所有前提条件。
2 为纯文本消息创建签名。返回的Signature包含使用 Base64 字符的 ASCII 安全字符串。
3 若要验证签名,验证需要 Signature 对象和纯文本消息。作为返回值,您可以获取签名是否有效。

您可以在 Vault 参考文档中找到有关 Vault Transit 后端的更多详细信息。spring-doc.cadn.net.cn

11. ReactiveVaultTemplate 简介

本节介绍有关使用 Spring Vault 的响应式编程支持的基本信息。spring-doc.cadn.net.cn

11.1. 什么是响应式编程?

简单来说,响应式编程是关于非阻塞应用程序,这些应用程序是 异步和事件驱动,需要少量线程才能垂直扩展 (即在 JVM 内)而不是水平(即通过聚类)。spring-doc.cadn.net.cn

响应式应用的一个关键方面是背压的概念,这是一种机制 以确保生产者不会压垮消费者。例如,在响应式管道中 当 HTTP 连接 太慢的数据存储库也会变慢或完全停止,直到网络容量释放。spring-doc.cadn.net.cn

11.2. 响应式 Vault 客户端

Spring Vault 的响应式客户端支持建立在可组合的身份验证步骤和 Spring 的功能之上WebClient通过 Reactor Netty 或 Jetty,它们都具有完全非阻塞、事件驱动的 HTTP 客户端。spring-doc.cadn.net.cn

它暴露了VaultTokenSupplier作为提供商VaultToken对 HTTP 请求进行身份验证 和ReactiveVaultOperations作为主要入口点。的核心配置VaultEndpoint,ClientOptionsSSL 在 各种客户端实现。spring-doc.cadn.net.cn

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

配置完成后,ReactiveVaultTemplate是线程安全的,可以跨多个实例。

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

ReactiveVaultTemplateclass 实现接口ReactiveVaultOperations. 在尽可能多的方法中ReactiveVaultOperations以方法命名 在 Vault API 上可用,以使现有 Vault 开发人员熟悉该 API 他们习惯了 API 和 CLI。例如,您会发现诸如 “写入”、“删除”和“读取”。 设计目标是尽可能轻松地在 Vault API 的使用和ReactiveVaultOperations. 之间的主要区别两个 API 是ReactiveVaultOperations可以传递域对象,而不是JSON 键值对。spring-doc.cadn.net.cn

引用ReactiveVaultTemplate实例 是通过其接口ReactiveVaultOperations.

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

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

11.3. 注册和配置 Spring Vault Bean

使用 Spring Vault 不需要 Spring Context。但是,实例ReactiveVaultTemplateVaultTokenSupplier在托管上下文中注册将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在 应用程序关闭。您还可以从重复使用相同的ReactiveVaultTemplate实例。spring-doc.cadn.net.cn

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

扩展自AbstractVaultConfiguration需要实现 ' VaultEndpoint vaultEndpoint()' 和ClientAuthentication clientAuthentication()方法。spring-doc.cadn.net.cn

示例 8.使用基于Java的bean元数据注册Spring Vault对象
@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快速入门。 有关支持的身份验证方法的详细信息,请参阅身份验证方法。

11.4. 会话管理

Spring Vault 需要Tokens来验证 Vault 请求。 有关身份验证的详细信息,请参阅身份验证方法。 响应式客户端需要一个非阻塞Tokens提供商,其合约已定义 在VaultTokenSupplier.Tokens可以是静态的,也可以是通过声明的身份验证流获取的。 Vault 登录不应在每次经过身份验证的 Vault 交互时进行,但 会话Tokens应在会话中保留。这方面由 会话管理器实现ReactiveSessionManagerReactiveLifecycleAwareSessionManager.spring-doc.cadn.net.cn

11.5. 执行回调

所有 Spring 模板类的一个共同设计特征是所有功能 路由到模板执行回调方法之一。这有助于确保 执行异常和可能需要的任何资源管理 一致性。虽然在 JDBC 和 JMS 的情况下,这更需要 与 Vault 相比,它仍然提供一个访问和日志记录的位置。 因此,使用执行回调是访问 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 doWith会话 (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);
});

12. Vault 属性源支持

Vault 可以以多种不同的方式使用。一个特定的用例是使用 Vault 以存储加密属性。Spring Vault 支持 Vault 作为属性 source 使用 Spring 的 PropertySource 抽象获取配置属性。spring-doc.cadn.net.cn

您可以在其他属性源中引用存储在 Vault 中的属性,也可以将值注入与@Value(…).引导需要存储在 Vault 内部的数据的 Bean 时需要特别注意。一个VaultPropertySource必须在该时初始化才能从 Vault 检索属性。
Spring Boot/Spring Cloud 用户可以从 Spring Cloud Vault 的 在应用程序启动期间初始化各种属性源的配置集成。

12.1. 注册VaultPropertySource

Spring Vault 提供了一个VaultPropertySource与 Vault 一起使用以获取 性能。它使用嵌套的data元素来公开存储的属性和 在 Vault 中加密。spring-doc.cadn.net.cn

ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new VaultPropertySource(vaultTemplate, "secret/my-application"));

在上面的代码中,VaultPropertySource已以最高优先级添加 在搜索中。如果它包含“foo”属性,则将检测并返回它 领先于任何foo属性PropertySource.MutablePropertySources公开了许多允许精确 对属性源集的作。spring-doc.cadn.net.cn

12.2. @VaultPropertySource

@VaultPropertySource注释提供了方便的声明性 添加PropertySource到 Spring 的Environment@Configuration类。spring-doc.cadn.net.cn

@VaultPropertySource采用 Vault 路径,例如secret/my-application并将存储在节点上的数据公开在PropertySource.@VaultPropertySource支持与租约关联的机密的租约续订 (即来自mysqlbackend)和终端上的凭证轮换 租约到期。默认情况下,租约续订处于禁用状态。spring-doc.cadn.net.cn

示例 9.存储在 Vault 中的属性
{
  // …

  "data": {
    "database": {
      "password": ...
    },
    "user.name": ...,
  }

  // …
}
示例 10.声明@VaultPropertySource
@Configuration
@VaultPropertySource("secret/my-application")
public class AppConfig {

    @Autowired Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setUser(env.getProperty("user.name"));
        testBean.setPassword(env.getProperty("database.password"));
        return testBean;
    }
}
示例 11.声明@VaultPropertySource使用凭据轮换和前缀
@Configuration
@VaultPropertySource(value = "aws/creds/s3-access",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
  // provides aws.access_key and aws.secret_key properties
}
从中获得的秘密generic秘密后端与 TTL (refresh_interval),但不是租约 Id。Spring Vault 的PropertySource在达到其 TTL 时轮换通用密钥。
您可以使用@VaultPropertySource从版本控制的键值后端获取最新的机密版本。确保不包含data/路径中的段。

任何${…​}占位符@VaultPropertySourcepath 是针对已针对环境注册的属性源集进行解析的,如以下示例所示:spring-doc.cadn.net.cn

示例 12.声明@VaultPropertySource使用占位符的路径
@Configuration
@VaultPropertySource(value = "aws/creds/${my.placeholder:fallback/value}",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
}

假设my.placeholder存在于已注册的属性源之一(例如,系统属性或环境变量)中,则占位符将解析为相应的值。 如果没有,那么fallback/value用作默认值。 如果未指定默认值并且无法解析属性,则IllegalArgumentException被抛出。spring-doc.cadn.net.cn

在某些情况下,严格控制可能是不可能的,也不切实际的 使用时的属性源排序@VaultPropertySource附注。 例如,如果@Configuration上述课程是通过 组件扫描,顺序难以预测。 在这种情况下,如果覆盖很重要,建议将 用户回退到使用编程 PropertySource API。 看ConfigurableEnvironmentMutablePropertySources了解详情。spring-doc.cadn.net.cn

13. Vault 存储库

使用VaultTemplate映射到 Java 类的响应允许读取、写入和删除等基本数据作。 Vault 存储库在 Vault 之上应用了 Spring Data 的存储库概念。 Vault 存储库公开了基本的 CRUD 功能,并支持使用约束标识符属性、分页和排序的谓词进行查询派生。 保管库存储库使用键/值机密引擎功能来保存和查询数据。 从版本 2.4 开始,Spring Vault 还可以使用键/值版本 2 密钥引擎,实际的密钥引擎版本是在运行时发现的。spring-doc.cadn.net.cn

版本控制的键/值密钥引擎中的删除使用DELETE操作。机密不会通过CrudRepository.delete(…).
Spring Data Commons 参考文档中阅读有关 Spring Data Repositories 的更多信息。 参考文档将向您介绍 Spring Data 存储库。

13.1. 用法

要访问存储在 Vault 中的域实体,您可以利用存储库支持来显着简化这些实体的实现。spring-doc.cadn.net.cn

示例 13.示例凭据实体
@Secret
class Credentials {

  @Id String id;
  String password;
  String socialSecurityNumber;
  Address address;
}

我们这里有一个非常简单的域对象。 请注意,它有一个名为id注释为org.springframework.data.annotation.Id@Secret注释。 这两个负责创建用于在 Vault 中将对象作为 JSON 持久化的实际密钥。spring-doc.cadn.net.cn

@Id以及那些被命名的id被视为标识符属性。 那些有注释的人比其他人更受青睐。

下一步是声明使用域对象的存储库接口。spring-doc.cadn.net.cn

示例 14.基本存储库界面Credentials实体
interface CredentialsRepository extends CrudRepository<Credentials, String> {

}

随着我们的存储库的扩展CrudRepository它提供了基本的 CRUD 和查询方法。 Vault 存储库需要 Spring Data 组件。 确保包括spring-data-commonsspring-data-keyvalue项目。spring-doc.cadn.net.cn

实现此目的的最简单方法是设置依赖项管理并将工件添加到pom.xml:spring-doc.cadn.net.cn

然后将以下内容添加到pom.xmldependencies 部分。spring-doc.cadn.net.cn

示例 15.使用 Spring Data BOM
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-bom</artifactId>
      <version>2022.0.8</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>

  <!-- other dependency elements omitted -->

  <dependency>
    <groupId>org.springframework.vault</groupId>
    <artifactId>spring-vault-core</artifactId>
    <version>3.0.4</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-keyvalue</artifactId>
    <!-- Version inherited from the BOM -->
  </dependency>

</dependencies>

我们将东西粘合在一起需要的是相应的 Spring 配置。spring-doc.cadn.net.cn

示例 16.用于 Vault 存储库的 JavaConfig
@Configuration
@EnableVaultRepositories
class ApplicationConfig {

  @Bean
  VaultTemplate vaultTemplate() {
    return new VaultTemplate(…);
  }
}

鉴于上述设置,我们可以继续注入CredentialsRepository进入我们的组件。spring-doc.cadn.net.cn

示例 17.访问个人实体
@Autowired CredentialsRepository repo;

void basicCrudOperations() {

  Credentials creds = new Credentials("heisenberg", "327215", "AAA-GG-SSSS");
  rand.setAddress(new Address("308 Negra Arroyo Lane", "Albuquerque", "New Mexico", "87104"));

  repo.save(creds);                                        (1)

  repo.findOne(creds.getId());                             (2)

  repo.count();                                            (3)

  repo.delete(creds);                                      (4)
}
1 存储属性Credentials在 Vault Hash 中,带有密钥模式keyspace/id,在本例中credentials/heisenberg,在键值机密机密引擎中。
2 使用提供的 id 检索存储在keyspace/id.
3 计算由@SecretCredentials.
4 从 Vault 中删除给定对象的键。

13.2. 对象到Vault JSON映射

Vault 存储库使用 JSON 作为交换格式将对象存储在 Vault 中。 JSON 和实体之间的对象映射由VaultConverter. 转换器读写SecretDocument包含来自VaultResponse.VaultResponses 从 Vault 中读取,并且 Jackson 将正文反序列化为MapStringObject. 默认值VaultConverter实现读取Map嵌套值,ListMap对象并将其转换为实体,反之亦然。spring-doc.cadn.net.cn

鉴于Credentials类型,默认映射如下:spring-doc.cadn.net.cn

{
  "_class": "org.example.Credentials",                 (1)
  "password": "327215",                                (2)
  "socialSecurityNumber": "AAA-GG-SSSS",
  "address": {                                         (3)
    "street": "308 Negra Arroyo Lane",
    "city": "Albuquerque",
    "state": "New Mexico",
    "zip": "87104"
  }
}
1 _class属性包含在根级别以及任何嵌套接口或抽象类型上。
2 简单属性值按路径映射。
3 复杂类型的属性映射为嵌套对象。
@Id属性必须映射到String.
表 1.默认映射规则
类型 样本 映射值

简单类型
(例如字符串)spring-doc.cadn.net.cn

字符串 firstname = “Walter”;spring-doc.cadn.net.cn

“firstname”: “沃尔特”spring-doc.cadn.net.cn

复杂类型
(例如地址)spring-doc.cadn.net.cn

地址地址 = 新地址(“308 Negra Arroyo Lane”);spring-doc.cadn.net.cn

“地址”: { “street”: “内格拉阿罗约巷 308 号” }spring-doc.cadn.net.cn

简单类型列表
spring-doc.cadn.net.cn

List<String>昵称 = asList(“walt”, “heisenberg”);spring-doc.cadn.net.cn

“昵称”: [“沃尔特”、“海森堡”]spring-doc.cadn.net.cn

简单类型的地图
spring-doc.cadn.net.cn

Map<String, Integer> atts = asMap(“age”, 51)spring-doc.cadn.net.cn

“atts” : {“年龄” : 51}spring-doc.cadn.net.cn

复杂类型列表
spring-doc.cadn.net.cn

List<Address> 地址 = asList(new Address(“308...spring-doc.cadn.net.cn

“地址”: [{ “street”: “308 Negra Arroyo Lane” }, ...]spring-doc.cadn.net.cn

您可以通过注册ConverterVaultCustomConversions. 这些转换器可以负责从/转换为类型,例如LocalDate以及SecretDocument而第一个适用于将简单属性转换为简单属性,最后一个则适合将复杂类型转换为其 JSON 表示形式。 第二个选项提供对结果的完全控制SecretDocument. 将对象写入Vault将删除内容并重新创建整个条目,因此未映射的数据将丢失。spring-doc.cadn.net.cn

13.3. 查询和查询方法

查询方法允许从方法名称自动派生简单查询。 Vault 没有查询引擎,但需要直接访问 HTTP 上下文路径。 Vault 查询方法将 Vault 的 API 可能性转换为查询。 查询方法执行在上下文路径下列出子项,对 Id 应用筛选,(可选)使用偏移量/限制限制 Id 流,并在提取结果后应用排序。spring-doc.cadn.net.cn

示例 18.示例存储库查询方法
interface CredentialsRepository extends CrudRepository<Credentials, String> {

  List<Credentials> findByIdStartsWith(String prefix);
}
Vault 存储库的查询方法仅支持对@Id财产。

以下是 Vault 支持的关键字的概述。spring-doc.cadn.net.cn

表 2.查询方法支持的关键字
关键词 样本

After,GreaterThanspring-doc.cadn.net.cn

findByIdGreaterThan(String id)spring-doc.cadn.net.cn

GreaterThanEqualspring-doc.cadn.net.cn

findByIdGreaterThanEqual(String id)spring-doc.cadn.net.cn

Before,LessThanspring-doc.cadn.net.cn

findByIdLessThan(String id)spring-doc.cadn.net.cn

LessThanEqualspring-doc.cadn.net.cn

findByIdLessThanEqual(String id)spring-doc.cadn.net.cn

Betweenspring-doc.cadn.net.cn

findByIdBetween(String from, String to)spring-doc.cadn.net.cn

Inspring-doc.cadn.net.cn

findByIdIn(Collection ids)spring-doc.cadn.net.cn

NotInspring-doc.cadn.net.cn

findByIdNotIn(Collection ids)spring-doc.cadn.net.cn

Like,StartingWith,EndingWithspring-doc.cadn.net.cn

findByIdLike(String id)spring-doc.cadn.net.cn

NotLike,IsNotLikespring-doc.cadn.net.cn

findByIdNotLike(String id)spring-doc.cadn.net.cn

Containingspring-doc.cadn.net.cn

findByFirstnameContaining(String id)spring-doc.cadn.net.cn

NotContainingspring-doc.cadn.net.cn

findByFirstnameNotContaining(String name)spring-doc.cadn.net.cn

Regexspring-doc.cadn.net.cn

findByIdRegex(String id)spring-doc.cadn.net.cn

(No keyword)spring-doc.cadn.net.cn

findById(String name)spring-doc.cadn.net.cn

Notspring-doc.cadn.net.cn

findByIdNot(String id)spring-doc.cadn.net.cn

Andspring-doc.cadn.net.cn

findByLastnameAndFirstnamespring-doc.cadn.net.cn

Orspring-doc.cadn.net.cn

findByLastnameOrFirstnamespring-doc.cadn.net.cn

Is,Equalsspring-doc.cadn.net.cn

findByFirstname,findByFirstnameIs,findByFirstnameEqualsspring-doc.cadn.net.cn

Top,Firstspring-doc.cadn.net.cn

findFirst10ByFirstname,findTop5ByFirstnamespring-doc.cadn.net.cn

13.3.1. 排序和分页

查询方法通过在内存中选择从 Vault 上下文路径检索的子列表(偏移量/限制)ID 来支持排序和分页。与查询方法谓词不同,排序不限于特定字段。在 ID 过滤后应用未分页排序,并且从 Vault 获取所有生成的密钥。这样,查询方法仅获取也作为结果的一部分返回的结果。spring-doc.cadn.net.cn

使用分页和排序需要在筛选 ID 之前进行机密提取,这会影响性能。 排序和分页保证返回相同的结果,即使 Vault 返回的 Id 的自然顺序发生变化也是如此。 因此,首先从 Vault 获取所有 ID,然后应用排序,然后进行过滤和偏移/限制。spring-doc.cadn.net.cn

实施例 19.分页和排序存储库
interface CredentialsRepository extends PagingAndSortingRepository<Credentials, String> {

  List<Credentials> findTop10ByIdStartsWithOrderBySocialSecurityNumberDesc(String prefix);

  List<Credentials> findByIdStarts(String prefix, Pageable pageRequest);
}

13.4. 乐观锁定

保管库密钥/值机密引擎版本 2 可以维护版本控制的机密。 Spring Vault 支持通过域模型中的版本属性进行版本控制,这些属性带有@Version. 使用乐观锁定可确保更新仅应用于具有匹配版本的机密。 因此,version 属性的实际值通过cas财产。 如果另一个作在此期间更改了机密,则会引发 OptimisticLockingFailureException,并且不会更新机密。spring-doc.cadn.net.cn

版本属性必须是数字属性,例如intlong并映射到cas属性。spring-doc.cadn.net.cn

示例 20.示例版本化实体
@Secret
class VersionedCredentials {

  @Id String id;
  @Version int version;
  String password;
  String socialSecurityNumber;
  Address address;
}

以下示例显示了这些功能:spring-doc.cadn.net.cn

示例 21.示例版本化实体
VersionedCredentialsRepository repo = …;

VersionedCredentials credentials = repo.findById("sample-credentials").get();    (1)

VersionedCredentials concurrent = repo.findById("sample-credentials").get();     (2)

credentials.setPassword("something-else");

repos.save(credentials);                                                         (3)


concurrent.setPassword("concurrent change");

repos.save(concurrent); // throws OptimisticLockingFailureException              (4)
1 通过 ID 获取密钥sample-credentials.
2 通过其 ID 获取密钥的第二个实例sample-credentials.
3 更新密钥并让 Vault 递增版本。
4 更新使用先前版本的第二个实例。 该作失败,并显示OptimisticLockingFailureException同时,该版本在 Vault 中递增。
删除版本化密钥时,按 Id 删除会删除最新的密钥。按实体删除 删除所提供版本的机密。

13.5. 访问版本控制的密钥

键/值版本 2 机密引擎维护可通过实现RevisionRepository在 Vault 存储库界面声明中。 修订存储库定义查找方法以获取特定标识符的修订。 标识符必须是String.spring-doc.cadn.net.cn

示例 22.实施RevisionRepository
interface RevisionCredentialsRepository extends CrudRepository<Credentials, String>,
                                        RevisionRepository<Credentials, String, Integer> (1)
{

}
1 第一个类型参数 (Credentials) 表示实体类型,第二个 (String) 表示 id 属性的类型,最后一个 (Integer) 是修订号的类型。Vault 仅支持Stringidentifiers 和Integer修订号。

13.5.1. 用法

您现在可以使用RevisionRepository查询实体的修订,如以下示例所示:spring-doc.cadn.net.cn

实施例 23.用RevisionRepository
RevisionCredentialsRepository repo = …;

Revisions<Integer, Credentials> revisions = repo.findRevisions("my-secret-id");

Page<Revision<Integer, Credentials>> firstPageOfRevisions = repo.findRevisions("my-secret-id", Pageable.ofSize(4));

14. 客户支持

Spring Vault 支持各种 HTTP 客户端访问 Vault 的 HTTP API。Spring Vault 使用RestTemplate作为访问 Vault 的主接口。 专用客户端支持源自自定义的 SSL 配置,该配置仅限于 Spring Vault 的客户端组件。spring-doc.cadn.net.cn

Spring Vault 支持以下 HTTP 命令式客户端:spring-doc.cadn.net.cn

Spring Vault 的响应式集成支持以下响应式 HTTP 客户端:spring-doc.cadn.net.cn

使用特定客户端需要相应的依赖关系在类路径上可用 因此,Spring Vault 可以使用可用的客户端与 Vault 进行通信。spring-doc.cadn.net.cn

14.1. Java 的内置HttpURLConnection

Java 的内置HttpURLConnection开箱即用,无需额外 配置。用HttpURLConnection带有有关 SSL 配置的限制。 Spring Vault 不会像以前那样应用自定义的 SSL 配置 需要对 JVM 进行深度重新配置。此配置将影响所有 组件依赖于默认 SSL 上下文。使用HttpURLConnection要求您将这些设置作为系统属性提供。有关更多详细信息,请参阅自定义 JSSEspring-doc.cadn.net.cn

14.2. 外部客户端

您可以使用外部客户端访问 Vault 的 API。只需添加以下内容之一 依赖项。如果使用 Spring Vault 的依赖项 BOM,则可以省略版本号spring-doc.cadn.net.cn

实施例 24.Apache Http 组件依赖项
<dependency>
  <groupId>org.apache.httpcomponents.client5</groupId>
  <artifactId>httpclient5</artifactId>
</dependency>
Apache HttpClient 的线路日志可以通过日志记录配置来启用。确保不要意外启用有线日志记录,因为日志可能会以纯文本形式暴露应用程序和 Vault 之间的流量(Tokens和密钥)。
示例 25.方形 OkHttp 3
<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
</dependency>
示例 26.反应器 Netty
<dependency>
  <groupId>io.projectreactor.netty</groupId>
  <artifactId>reactor-netty</artifactId>
</dependency>
示例 27.Apache Http 组件响应式依赖关系
<dependency>
  <groupId>org.apache.httpcomponents.core5</groupId>
  <artifactId>httpcore5-reactive</artifactId>
</dependency>
实施例 28. Jetty
<dependency>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-reactive-httpclient</artifactId>
</dependency>

14.3. Vault 客户端 SSL 配置

SSL 可以使用SslConfiguration通过设置各种属性。 您可以设置javax.net.ssl.trustStore配置 JVM 范围的 SSL 设置或配置SslConfiguration仅为 Spring Vault 设置 SSL 设置。spring-doc.cadn.net.cn

SslConfiguration sslConfiguration = SslConfiguration.create(            (1)
		new FileSystemResource("client-cert.jks"), "changeit".toCharArray(),
		new FileSystemResource("truststore.jks"), "changeit".toCharArray());

SslConfiguration.forTrustStore(new FileSystemResource("keystore.jks"),  (2)
                                      "changeit".toCharArray())

SslConfiguration.forKeyStore(new FileSystemResource("keystore.jks"),    (3)
                                      "changeit".toCharArray())

SslConfiguration.forKeyStore(new FileSystemResource("keystore.jks"),    (4)
                                      "changeit".toCharArray(),
                                      KeyConfiguration.of("key-password".toCharArray(),
                                      "my-key-alias"))
1 完整配置。
2 仅配置信任存储设置。
3 仅配置密钥存储设置。
4 仅配置密钥存储设置,并提供密钥配置。

请注意,提供SslConfiguration只能在 Apache Http 组件或 OkHttp 客户端位于您的类路径上时应用。spring-doc.cadn.net.cn

SSL 配置还支持 PEM 编码的证书,作为 Java 密钥库的替代方案。spring-doc.cadn.net.cn

KeyStoreConfiguration keystore = KeyStoreConfiguration
        .of(new ClassPathResource("ca.pem")).withStoreType("PEM");
SslConfiguration configuration = SslConfiguration.forTrustStore(keystore);

PEM 文件可能包含一个或多个证书(-----BEGIN CERTIFICATE----------END CERTIFICATE-----). 添加到基础KeyStore使用完整的主题名称作为别名。spring-doc.cadn.net.cn

15. 认证方法

不同的组织对安全有不同的要求 和身份验证。Vault 通过提供多重身份验证来反映这一需求 方法。Spring Vault 支持多种身份验证机制。spring-doc.cadn.net.cn

15.1. 外部化登录凭证

首次访问安全系统称为安全引入。 任何客户端都需要临时或永久凭据才能访问 Vault。外部化凭据 是保持高代码可维护性的良好模式,但存在增加披露的风险。spring-doc.cadn.net.cn

向任何一方披露登录凭据允许登录 Vault 并访问 由基础角色允许。选择适当的客户端身份验证和 将凭据注入应用程序需要进行风险评估。spring-doc.cadn.net.cn

Spring 的 PropertySource 抽象是自然而然的 将配置保留在应用程序代码之外。您可以使用系统属性、环境 变量或属性文件来存储登录凭据。每种方法都有自己的属性。 请记住,命令行和环境属性可以使用适当的 作系统访问级别。spring-doc.cadn.net.cn

实施例 29.具体化vault.token到属性文件
@PropertySource("configuration.properties")
@Configuration
public class Config extends AbstractVaultConfiguration {

    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication(getEnvironment().getProperty("vault.token"));
    }
}
Spring 允许多种方式获取Environment.使用时VaultPropertySource,注射通过@Autowired Environment environment不会提供Environment由于环境 Bean 仍在建设中,自动布线是在后期阶段进行的。您的配置类应该实现ApplicationContextAware并获取EnvironmentApplicationContext.

SecurePropertyUsage.java有关引用组件和其他属性源中的属性的示例。spring-doc.cadn.net.cn

15.2. Tokens身份验证

Tokens是 Vault 中身份验证的核心方法。 Tokens身份验证需要提供静态Tokens。spring-doc.cadn.net.cn

Tokens身份验证是默认的身份验证方法。 如果Tokens被披露为非预期方,则该Tokens将获得对 Vault 的访问权限,并且 可以访问目标客户端的密钥。

通常,Tokens身份验证用于创建和续订Tokens的方案 外部(例如 HashiCorp Vault 服务代理)。 根据实际设置,您可能希望也可能不需要Tokens续订和吊销。 看LifecycleAwareSessionManager有关 TTL 和Tokens吊销的详细信息。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("…");
    }

    // …
}

15.3. AppId 身份验证

Vault 已弃用 AppId 身份验证。请改用 AppRole 身份验证

Vault 支持 AppId 身份验证,该身份验证由两个难以猜测的Tokens组成。The AppId 默认为spring.application.name这是静态配置的。 第二个Tokens是 UserId,它是由应用程序确定的部分, 通常与运行时环境有关。IP 地址、Mac 地址或 Docker 容器名称就是很好的例子。Spring Vault 支持 IP 地址、Mac 地址和静态 UserId(例如通过系统属性提供)。 IP 和 Mac 地址表示为十六进制编码的 SHA256 哈希值。spring-doc.cadn.net.cn

基于 IP 地址的用户 ID 使用本地主机的 IP 地址。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {
        AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder()
                .appId("myapp")
                .userIdMechanism(new IpAddressUserId())
                .build();

        return new AppIdAuthentication(options, restOperations());
    }

    // …
}

从命令行生成 IP 地址 UserId 的相应命令是:spring-doc.cadn.net.cn

$ echo -n 192.168.99.1 | sha256sum
包括echo导致不同的哈希值 因此,请确保包含-n旗。

基于 Mac 地址的 UserId 从 localhost 绑定设备。该配置还允许指定 一个network-interface提示选择正确的设备。的值network-interface是可选的,可以是接口 名称或接口索引(从 0 开始)。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder()
                .appId("myapp")
                .userIdMechanism(new MacAddressUserId())
                .build();

        return new AppIdAuthentication(options, restOperations());
    }

    // …
}

从命令行生成 Mac 地址 UserId 的相应命令是:spring-doc.cadn.net.cn

$ echo -n 0AFEDE1234AC | sha256sum
Mac 地址指定为大写,不带冒号。 包括echo导致不同的哈希值 因此,请确保包含-n旗。

15.3.1. 自定义用户 ID

更高级的方法允许您实现自己的AppIdUserIdMechanism. 此类必须位于您的类路径上,并且必须实现 这org.springframework.vault.authentication.AppIdUserIdMechanism接口 和createUserId方法。Spring Vault 将获取 UserId 通过调用createUserId每次使用 AppId 进行身份验证时,它都会使用 获取Tokens。spring-doc.cadn.net.cn

MyUserIdMechanism.java
public class MyUserIdMechanism implements AppIdUserIdMechanism {

  @Override
  public String createUserId() {

    String userId = …
    return userId;
  }
}

15.4. AppRole 身份验证

AppRole 允许计算机 身份验证,就像已弃用的(自 Vault 0.6.1 起)AppId 身份验证一样。 AppRole 身份验证由两个难以猜测的(机密)Tokens组成:RoleId 和 SecretId。spring-doc.cadn.net.cn

Spring Vault 通过仅提供 RoleId 来支持 AppRole 身份验证 或与提供的 SecretId 一起,并从 Vault 获取 RoleId/SecretId (推拉模式,响应展开)。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AppRoleAuthenticationOptions options = AppRoleAuthenticationOptions.builder()
                .roleId(RoleId.provided("…"))
                .secretId(SecretId.wrapped(VaultToken.of("…")))
                .build();

        return new AppRoleAuthentication(options, restOperations());
    }

    // …
}

Spring Vault 还支持全拉模式:如果未提供 RoleId 和 SecretId, Spring Vault 将使用角色名称和初始Tokens检索它们。这 初始Tokens可能与 TTL 和使用限制相关联。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        VaultToken initialToken = VaultToken.of("…");
        AppRoleAuthenticationOptions options = AppRoleAuthenticationOptions.builder()
                .appRole("…")
                .roleId(RoleId.pull(initialToken))
                .secretId(SecretId.pull(initialToken))
                .build();

        return new AppRoleAuthentication(options, restOperations());
    }

    // …
}

15.5. AWS-EC2 身份验证

aws-ec2 auth 后端提供安全的引入机制 对于 AWS EC2 实例,允许自动检索 Vault Tokens。与大多数 Vault 身份验证后端不同,此后端 不需要首次部署或配置安全敏感型 凭据(Tokens、用户名/密码、客户端证书等)。 相反,它将 AWS 视为受信任的第三方,并使用 加密签名的动态元数据信息,唯一的 表示每个 EC2 实例。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {
        return new AwsEc2Authentication(restOperations());
    }

    // …
}

AWS-EC2 身份验证默认情况下允许随机数遵循 首次使用时信任 (TOFU) 原则。任何意外的一方 获得对 PKCS#7 身份元数据的访问权限可以进行身份验证 反对 Vault。spring-doc.cadn.net.cn

在第一次登录期间,Spring Vault 会生成一个随机数 存储在实例 ID 旁边的身份验证后端中。 重新身份验证需要发送相同的随机数。任何其他 party 没有随机数,并且可以在 Vault 中针对 进一步调查。spring-doc.cadn.net.cn

随机数保存在内存中,并在应用程序重新启动期间丢失。spring-doc.cadn.net.cn

AWS-EC2 身份验证角色是可选的,默认为 AMI。 您可以通过设置 它AwsEc2AuthenticationOptions.spring-doc.cadn.net.cn

15.6. AWS-IAM 身份验证

aws auth 后端允许使用现有的 AWS IAM 凭证登录 Vault。spring-doc.cadn.net.cn

AWS IAM 身份验证会创建一个签名的 HTTP 请求,该请求是 由 Vault 执行,以使用 AWS STS 获取签名者的身份GetCallerIdentity方法。AWSv4 签名需要 IAM 凭证。spring-doc.cadn.net.cn

可以从任一运行时环境中获取 IAM 凭证 或外部供应。运行时环境,例如 AWS-EC2、 分配了 IAM 主体的 Lambda 和 ECS 不需要特定于客户端 凭据的配置,但可以从其元数据源获取这些凭据。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder()
                .credentials(new BasicAWSCredentials(…)).build();

        return new AwsIamAuthentication(options, restOperations());
    }

    // …
}
实施例 30.使用 AWS-EC2 实例配置文件作为凭证源
@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder()
                .credentialsProvider(InstanceProfileCredentialsProvider.getInstance()).build();

        return new AwsIamAuthentication(options, restOperations());
    }

    // …
}

AwsIamAuthentication需要 AWS Java SDK 依赖项 (com.amazonaws:aws-java-sdk-core) 因为身份验证实施使用 AWS SDK 类型进行凭证和请求签名。spring-doc.cadn.net.cn

您可以通过以下方式配置身份验证AwsIamAuthenticationOptions.spring-doc.cadn.net.cn

15.7. Azure (MSI) 身份验证

Azure 身份验证后端提供安全的引入机制 对于 Azure VM 实例,允许自动检索保管库 Tokens。与大多数 Vault 身份验证后端不同,此后端 不需要首次部署或配置安全敏感型 凭据(Tokens、用户名/密码、客户端证书等)。 相反,它将 Azure 视为受信任的第三方,并使用 托管服务标识和实例元数据信息,可以是 绑定到 VM 实例。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder()
                    .role(…).build();

        return new AzureMsiAuthentication(options, restOperations());
    }

    // …
}

Azure 身份验证需要有关 VM 环境的详细信息(订阅 ID、 资源组名称、VM 名称)。这些详细信息可以通过AzureMsiAuthenticationOptionsBuilder. 如果未配置,AzureMsiAuthentication将 Azure 的实例元数据服务查询到 获取这些详细信息。spring-doc.cadn.net.cn

15.8. GCP-GCE 身份验证

gcp 身份验证后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭据登录 Vault。spring-doc.cadn.net.cn

GCP GCE(Google Compute Engine)身份验证会以JSON Web Tokens (JWT) 的形式为服务帐号创建签名。Compute Engine 实例的 JWT是使用实例标识从 GCE 元数据服务获取的。此 API 会创建一个 JSON Web Tokens,可用于确认实例身份。spring-doc.cadn.net.cn

与大多数保管库身份验证后端不同,此后端不需要首次部署或配置安全敏感的凭据(Tokens、用户名/密码、客户端证书等)。相反,它将 GCP 视为受信任的第三方,并使用加密签名的动态元数据信息,这些信息唯一代表每个 GCP 服务帐户。spring-doc.cadn.net.cn

您可以通过以下方式配置身份验证GcpComputeAuthenticationOptions.spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        GcpComputeAuthenticationOptions options = GcpComputeAuthenticationOptions.builder()
				.role(…).build();

		GcpComputeAuthentication authentication = new GcpComputeAuthentication(options,
				restOperations());
    }

    // …
}

15.9. GCP-IAM 身份验证

gcp 身份验证后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭据登录 Vault。spring-doc.cadn.net.cn

GCP IAM 身份验证以 JSON Web Tokens (JWT) 的形式创建签名 对于服务帐户。服务帐户的 JWT 由以下方式获取 调用 GCP IAMprojects.serviceAccounts.signJwt应用程序接口。调用方针对 GCP IAM 进行身份验证 并由此证明其身份。此 Vault 后端将 GCP 视为受信任的第三方。spring-doc.cadn.net.cn

可以从任一运行时环境中获取 IAM 凭证 或作为e.g. JSON从外部供应。JSON 是首选形式,因为它 携带调用所需的项目 ID 和服务帐户标识符projects.serviceAccounts.signJwt.spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        GcpIamCredentialsAuthenticationOptions options = GcpIamCredentialsAuthenticationOptions.builder()
				.role(…).credential(GoogleCredentials.getApplicationDefault()).build();

		GcpIamCredentialsAuthentication authentication = new GcpIamCredentialsAuthentication(options,
				restOperations());
    }

    // …
}

GcpIamCredentialsAuthenticationOptions需要 Google Cloud Java SDK 依赖项 (com.google.cloud:google-cloud-iamcredentials) 因为身份验证实现使用 Google API 进行凭据和 JWT 签名。spring-doc.cadn.net.cn

您可以通过以下方式配置身份验证GcpIamCredentialsAuthenticationOptions.spring-doc.cadn.net.cn

Google 凭据需要 OAuth 2 Tokens来维护Tokens生命周期。所有 API 因此是同步的,GcpIamCredentialsAuthentication不支持AuthenticationSteps这是 需要被动使用。
GcpIamCredentialsAuthentication使用 IAM 凭证 API,并且是使用GcpIamAuthentication使用已弃用的 IAM API

15.10. PCF 身份验证

pcf 身份验证后端允许 PCF 实例的 Vault 登录。 它利用 PCF 的应用程序和容器身份保证spring-doc.cadn.net.cn

PCF 身份验证使用实例密钥和证书创建由 Vault 验证的签名。 如果签名匹配,并且可能绑定组织/空间/应用程序 ID 匹配,Vault 将颁发适当范围的Tokens。spring-doc.cadn.net.cn

实例凭据可从以下文件中获得:CF_INSTANCE_CERTCF_INSTANCE_KEY变量。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        PcfAuthenticationOptions options = PcfAuthenticationOptions.builder()
                .role(…).build();

        PcfAuthentication authentication = new PcfAuthentication(options,
                restOperations());
    }

    // …
}

PcfAuthenticationOptions需要 BouncyCastle 库来创建 RSA-PSS 签名。spring-doc.cadn.net.cn

您可以通过以下方式配置身份验证PcfAuthenticationOptions.spring-doc.cadn.net.cn

15.11. TLS 证书身份验证

cert身份验证后端允许使用 SSL/TLS 客户端进行身份验证 由 CA 签名或自签名的证书。spring-doc.cadn.net.cn

启用cert身份验证,您需要:spring-doc.cadn.net.cn

  1. 使用 SSL,请参见 Vault 客户端 SSL 配置spring-doc.cadn.net.cn

  2. 配置 JavaKeystore包含客户端 证书和私钥spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        ClientCertificateAuthenticationOptions options = ClientCertificateAuthenticationOptions.builder()
                .path(…).build();

        return new ClientCertificateAuthentication(options, restOperations());
    }

    // …
}

15.12. Cubbyhole 身份验证

Cubbyhole 身份验证使用 Vault 基元提供安全身份验证 工作流程。Cubbyhole 身份验证使用Tokens作为主要登录方法。 临时Tokens用于从 Vault 的 Cubbyhole 秘密后端。登录Tokens的寿命通常较长,并且用于 与 Vault 交互。登录Tokens可以从包装的 响应或来自data部分。spring-doc.cadn.net.cn

创建包装Tokensspring-doc.cadn.net.cn

用于创建Tokens的响应包装需要 Vault 0.6.0 或更高版本。
实施例 31.装箱和存储Tokens
$ vault token-create -wrap-ttl="10m"
Key                            Value
---                            -----
wrapping_token:                397ccb93-ff6c-b17b-9389-380b01ca2645
wrapping_token_ttl:            0h10m0s
wrapping_token_creation_time:  2016-09-18 20:29:48.652957077 +0200 CEST
wrapped_accessor:              46b6aebb-187f-932a-26d7-4f3d86a68319
实施例 32.包装Tokens响应用法
@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions
                .builder()
                .initialToken(VaultToken.of("…"))
                .wrapped()
                .build();

        return new CubbyholeAuthentication(options, restOperations());
    }

    // …
}

使用存储的Tokensspring-doc.cadn.net.cn

实施例 33.装箱和存储Tokens
$ vault token create
Key                    Value
---                    -----
token                  f9e30681-d46a-cdaf-aaa0-2ae0a9ad0819
token_accessor         4eee9bd9-81bb-06d6-af01-723c54a72148
token_duration         0s
token_renewable        false
token_policies         [root]

$ vault token create -use-limit=2 -orphan -no-default-policy -policy=none
Key                    Value
---                    -----
token                  895cb88b-aef4-0e33-ba65-d50007290780
token_accessor         e84b661c-8aa8-2286-b788-f258f30c8325
token_duration         0s
token_renewable        false
token_policies         [none]

$ export VAULT_TOKEN=895cb88b-aef4-0e33-ba65-d50007290780
$ vault write cubbyhole/token token=f9e30681-d46a-cdaf-aaa0-2ae0a9ad0819
实施例 34.存储的Tokens响应用法
@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions
                .builder()
                .initialToken(VaultToken.of("…"))
                .path("cubbyhole/token")
                .build();

        return new CubbyholeAuthentication(options, restOperations());
    }

    // …
}

剩余 TTL/可续订性spring-doc.cadn.net.cn

从 Cubbyhole 检索到的与非零 TTL 关联的Tokens从 Tokens创建时间。该时间不一定与申请相同 启动。为了补偿初始延迟,Cubbyhole 身份验证执行 自查找与非零 TTL 关联的Tokens,以检索剩余的 TTL。 Cubbyhole 身份验证不会在没有 TTL 的情况下自查找包装的Tokens,因为 零 TTL 表示没有关联的 TTL。spring-doc.cadn.net.cn

非包装Tokens不提供有关可续订性和 TTL 的详细信息,仅 检索Tokens。自查找将查找可续订性和剩余 TTL。spring-doc.cadn.net.cn

15.13. Kubernetes 身份验证

Vault 从 0.8.3 开始支持使用 Kubernetes Tokens进行基于 Kubernetes 的身份验证。spring-doc.cadn.net.cn

使用 Kubernetes 身份验证需要 Kubernetes 服务帐户Tokens, 通常安装在/var/run/secrets/kubernetes.io/serviceaccount/token. 该文件包含读取并发送到 Vault 的Tokens。 Vault 在登录期间使用 Kubernetes 的 API 验证其有效性。spring-doc.cadn.net.cn

配置 Kubernetes 身份验证至少需要提供角色名称:spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions.builder()
                .role(…).jwtSupplier(…).build();

        return new KubernetesAuthentication(options, restOperations());
    }

    // …
}

您可以通过以下方式配置身份验证KubernetesAuthenticationOptions.spring-doc.cadn.net.cn

15.14. 用户名/密码身份验证

用户名/密码通常是最终用户身份验证方案。 多个 Vault 身份验证后端支持使用用户名和密码:spring-doc.cadn.net.cn

UserPasswordAuthenticationOptions可以与上述所有身份验证后端一起使用,因为登录 API 在所有机制上都是相似的。 配置时请确保使用适当的身份验证挂载路径UserPasswordAuthenticationOptions.spring-doc.cadn.net.cn

示例 35.配置UserPasswordAuthentication
@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        UserPasswordAuthenticationOptions options = UserPasswordAuthenticationOptions.builder()
                .username(…).password(…).build();

        return new UserPasswordAuthentication(options, restOperations());
    }

    // …
}

15.15. 身份验证步骤

ClientAuthentication对象描述身份验证流程并执行实际的 身份验证步骤。预先组合的身份验证易于使用和配置 与同步执行的紧密绑定。spring-doc.cadn.net.cn

身份验证方法的组成和重复使用常见步骤,例如发布登录 无意将有效负载发送到 Vault 或从 HTTP 源检索身份验证输入 跟ClientAuthentication对象。spring-doc.cadn.net.cn

身份验证步骤提供常见身份验证活动的可重用性。 通过以下方式创建的步骤AuthenticationSteps描述功能中的身份验证流 样式,将实际的身份验证执行留给特定的执行器。spring-doc.cadn.net.cn

实施例 36.存储Tokens身份验证流。
AuthenticationSteps.just(VaultToken.of(…));                              (1)
1 创建AuthenticationSteps从一个VaultToken.

可以从单个输入创建单步身份验证流。声明的流 多个身份验证步骤以SupplierHttpRequest提供 身份验证状态对象,可用于映射或发布到 Vault 进行登录。spring-doc.cadn.net.cn

实施例 37.AppRole 身份验证流
AuthenticationSteps.fromSupplier(                                       (1)

    () -> getAppRoleLogin(options.getRoleId(), options.getSecretId()))  (2)

    .login("auth/{mount}/login", options.getPath());                    (3)
1 开始声明AuthenticationSteps接受Supplier<T>. 状态对象类型取决于Supplier响应类型,可以在后续步骤中映射。
2 实际的Supplier实现。 创建Map在这种情况下。
3 通过发布状态对象 (Map) 添加到 Vault 端点以创建 Vault Tokens。 请注意,模板变量受 URL 转义的影响。

身份验证流需要执行程序来执行实际登录。我们提供两个执行者 对于不同的执行模型:spring-doc.cadn.net.cn

ClientAuthentication自带静态工厂方法来创建AuthenticationSteps对于特定于身份验证的选项:spring-doc.cadn.net.cn

实施例 38.同步AuthenticationSteps执行
CubbyholeAuthenticationOptions options = …
RestOperations restOperations = …

AuthenticationSteps steps = CubbyholeAuthentication.createAuthenticationSteps(options);

AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor(steps, restOperations);

VaultToken token = executor.login();

15.16. Tokens生命周期

Vault 的Tokens可以与生存时间相关联。通过身份验证方法获取的Tokens 只要会话处于活动状态,就可以使用,并且在应用程序处于活动状态时不应过期。spring-doc.cadn.net.cn

Spring Vault 提供了LifecycleAwareSessionManager一个会话管理器,可以续订Tokens,直到它达到其终端 TTL,然后执行另一次登录以获取与会话关联的下一个Tokens。spring-doc.cadn.net.cn

根据身份验证方法,登录可以创建两种Tokens:spring-doc.cadn.net.cn

身份验证方法,例如TokenAuthentication只需创建一个VaultToken不包含任何可续订性/TTL 详细信息。LifecycleAwareSessionManager将对Tokens运行自查找,以从 Vault 检索可续订性和 TTL。VaultToken如果启用了自查找,则会定期续订。请注意,VaultToken永远不会被撤销,只有LoginToken被撤销。spring-doc.cadn.net.cn

创建身份验证方法LoginToken直接(所有基于登录的身份验证方法)已经提供了设置Tokens续订所需的所有详细信息。从登录中获取的Tokens由LifecycleAwareSessionManager如果会话管理器已关闭。spring-doc.cadn.net.cn