参考文档

7. 保险库支持

Vault 支持包含广泛的功能,总结如下。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 或更高版本。 这些模块也可能与该次要版本的旧 bug 修复版本一起使用。 但是,强烈建议使用该代中的最新版本。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 项目,请转到 File → New → Spring 模板项目 → 简单的 Spring Utility Project → 出现提示时按 Yes。然后输入项目和包名称,例如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>

如果您使用的是 milestone 或 release candidate,则还需要添加 Spring 的位置 Milestone 存储库添加到您的 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

  • 映射约定可以使用字段访问。请注意Secretsclass 只有 getter。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

VaultTemplate类实现接口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您可以使用以下 多个 execute 回调方法以访问底层 API。执行回调 将为您提供对RestOperations对象。 有关更多信息,请参阅 执行回调 部分。spring-doc.cadn.net.cn

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

9.1. 注册和配置 Spring Vault bean

使用 Spring Vault 不需要 Spring Context。但是,VaultTemplateSessionManager在 Managed Context 中注册将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处理活动的 Vault 会话非常有用 应用程序关闭。您还可以从重复使用中受益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允许使用 来自现有属性源的 properties 和 Spring 的Environment.阅读更多 在EnvironmentVaultConfiguration.

9.2. 会话管理

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

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

  • LifecycleAwareSessionManager:这SessionManagerschedules 令牌 如果令牌可续订,则续订,并在处置时撤销登录令牌。 续订计划使用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 中的需求要大得多,但它仍然提供了一个访问和日志记录的单一位置。 因此,使用 execute 回调是访问 Vault API 的首选方式 执行我们尚未作为方法公开的不常见作VaultTemplate.spring-doc.cadn.net.cn

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

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

  • <T> T doWithSession 会话 (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 的 Secret 引擎

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(“未版本控制的 secret”)

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

运行kvSecrets Engine 中,仅保留最近写入的键值。 非版本控制 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 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 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支持所有 Key-Value作,例如put,get,delete,list.spring-doc.cadn.net.cn

或者,可以通过 API 使用VaultTemplate由于其直接映射和简单使用,因为 KEY 和 Responses 直接映射到输入和输出键。 以下示例说明了在mykey. 这kvSecrets Engine 挂载在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(“版本化 secret”)

您可以运行kvSecrets Engine 中的一个版本。 本节介绍如何使用版本 2。当运行 2 版本的kvbackend 一个 key 可以保留可配置数量的版本。 您可以检索旧版本的元数据和数据。 此外,您还可以使用 check-and-set作来避免无意中覆盖数据。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 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 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支持所有 Key-Value作,例如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 Engine 通过VaultTemplate是可能的。 这不是最方便的方法,因为 API 为上下文路径以及 input/output 的表示方式提供了一种不同的方法。 具体来说,与实际 secret 的交互需要包装和解包数据部分,并引入data/mount 和 secrets 键之间的 path 段。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 Engine 通过实施证书颁发机构作来表示证书的后端。spring-doc.cadn.net.cn

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

Spring Vault 支持通过以下方式颁发、签名、撤销证书和 CRL 检索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 的形式获取生成的证书,其中包含公钥和私钥以及颁发者证书。KeyStore 具有广泛的用途,这使得这种格式适合配置(例如,HTTP 客户端、数据库驱动程序或 SSL 保护的 HTTP 服务器)。
4 CertificateBundle允许直接通过 Java Cryptography Extension API 访问私钥以及公钥和颁发者证书。
5 一旦证书不再使用(或已泄露),您可以通过其序列号吊销该证书。 Vault 在其 CRL 中包含已吊销的证书。

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

10.4. 令牌认证后端

此后端是不与实际密钥交互的身份验证后端。 相反,它提供对访问令牌管理的访问权限。 您可以在 Authentication methods 一章中阅读有关基于 Token 的身份验证的更多信息。spring-doc.cadn.net.cn

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

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

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

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

以下示例展示了如何从应用程序中请求、续订和撤销 Vault 令牌: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 通过应用角色默认值创建令牌。
2 使用生成器 API,您可以为要请求的令牌定义精细设置。 请求令牌会返回一个VaultToken,它用作 Vault 令牌的值对象。
3 您可以通过 Token API 续订 Token。通常,这是由SessionManager以跟踪 Vault 会话令牌。
4 如果需要,可以通过令牌 API 撤销令牌。通常,这是由SessionManager以跟踪 Vault 会话令牌。

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

10.5. Transit 后端

传输密钥引擎处理传输中数据的加密功能。 Vault 不存储发送到此 Secrets 引擎的数据。 它也可以看作是 “cryptography as a service” 或 “encryption as a service”。 传输密钥引擎还可以对数据进行签名和验证,生成数据的哈希和 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将字符串编码为其二进制表示形式。 请求令牌会返回一个VaultToken,它用作 Vault 令牌的值对象。 这encryptmethod 返回 Base64 编码的密文,通常以vault:.
3 要将密文解密为纯文本,请调用decrypt方法。 它解密密文并返回一个String使用默认 charset 进行解码。

前面的示例使用简单字符串进行加密作。 虽然这是一种简单的方法,但它存在 charset 错误配置的风险,并且不是二进制安全的。 当纯文本对数据(如图像、压缩数据或二进制数据结构)使用二进制表示时,需要二进制安全性。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 假设一个 keymy-aes-key已经就位,我们正在加密Plaintext对象。 作为回报,encryptmethod 返回一个Ciphertext对象。
2 CiphertextObject 可以直接用于解密,并返回一个Plaintext对象。

PlaintextCiphertext带有一个上下文对象,VaultTransitContext. 它用于为收敛加密提供 nonce 值,以及用于利用密钥派生的上下文值。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 签名需要非对称密钥。您可以使用任何 Elliptic Curve Cryptography 或 RSA 密钥类型。创建密钥后,您就具备了创建签名的所有先决条件。
2 将为纯文本消息创建签名。返回的Signature包含使用 Base64 字符的 ASCII 安全字符串。
3 要验证签名,验证需要一个 Signature 对象和纯文本消息。作为返回值,您可以获得签名是否有效。

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

11. ReactiveVaultTemplate 简介

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

11.1. 什么是反应式编程?

简单来说,反应式编程是关于非阻塞应用程序 异步和事件驱动,并且需要少量线程来垂直扩展 (即在 JVM 中)而不是水平(即通过集群)。spring-doc.cadn.net.cn

响应式应用程序的一个关键方面是背压的概念,这是一种机制 确保生产者不会压倒消费者。例如,在 reactive 的管道中 组件从数据库扩展到 HTTP 响应(当 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

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

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

未由ReactiveVaultTemplate您可以使用以下 多个 execute 回调方法以访问底层 API。执行回调 将为您提供对WebClient对象。 有关更多信息,请参阅 执行回调 部分。spring-doc.cadn.net.cn

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

11.3. 注册和配置 Spring Vault bean

使用 Spring Vault 不需要 Spring Context。但是,ReactiveVaultTemplateVaultTokenSupplier在 Managed Context 中注册将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处理活动的 Vault 会话非常有用 应用程序关闭。您还可以从重复使用中受益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 需要一个令牌来验证 Vault 请求。 有关身份验证的详细信息,请参阅身份验证方法。 反应式客户端需要一个非阻塞的代币供应商,其合约已定义 在VaultTokenSupplier.令牌可以是静态的,也可以通过声明的身份验证流程获取。 Vault 登录不应在每次经过身份验证的 Vault 交互时进行,但 会话令牌应在整个会话中保留。这方面由 Session Manager 实现ReactiveSessionManagerReactiveLifecycleAwareSessionManager.spring-doc.cadn.net.cn

11.5. 执行回调

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

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

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

  • <T> T doWithSession 会话 (Function<WebClient, ? extends T> clientCallback)编写一个 reactive 对给定的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' 属性,则将被检测并返回 领先于任何fooproperty 在任何其他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
}
genericsecret 后端与 TTL (refresh_interval),而不是租约 ID 的PropertySource在达到其 TTL 时轮换通用密钥。
您可以使用@VaultPropertySource从受版本控制的 Key-Value 后端获取最新的密钥版本。确保不包含data/段。

任何${…​}placeholder 存在于@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用作默认值。 如果未指定 default 且无法解析属性,则IllegalArgumentException被抛出。spring-doc.cadn.net.cn

在某些情况下,严格控制可能是不可能的或不切实际的 使用@VaultPropertySource附注。 例如,如果@Configuration以上类是通过 component-scanning 中,顺序很难预测。 在这种情况下 - 如果覆盖很重要 - 建议将 用户回退到使用编程式 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

版本控制的键/值 Secret 引擎中的 Deletes 使用DELETE操作。机密不会通过以下方式销毁CrudRepository.delete(…).
Spring Data Commons 参考文档中阅读有关 Spring Data Repositories 的更多信息。 参考文档将为您提供 Spring Data 存储库的介绍。

13.1. 用法

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

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

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

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

注释 的属性@Id以及那些被命名为id被视为标识符属性。 带有注释的 Comments 比其他 Comments 更受欢迎。

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

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

}

随着我们的存储库扩展CrudRepository它提供了基本的 CRUD 和查询方法。 Vault 存储库需要 Spring Data 组件。 确保包括spring-data-commonsspring-data-keyvalueartifacts 的 artifacts 中。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.访问 Person 实体
@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中,在键值 Secret Secrets 引擎中。
2 使用提供的 ID 检索存储在keyspace/id.
3 计算@SecretCredentials.
4 从 Vault 中删除给定对象的密钥。

13.2. 对象到 Vault 的 JSON 映射

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

鉴于Credentialstype 的 default 映射如下: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 _classattribute 包含在根级别以及任何嵌套接口或抽象类型中。
2 简单属性值按 path 进行映射。
3 复杂类型的属性映射为嵌套对象。
@Idproperty 必须映射到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

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

“address”: { “street”: “308 Negra Arroyo Lane” }spring-doc.cadn.net.cn

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

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

“昵称”: [“Walt”, “Heisenberg”]spring-doc.cadn.net.cn

简单类型的映射
spring-doc.cadn.net.cn

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

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

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

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

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

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

13.3. 查询和查询方法

Query methods 允许从方法名称自动派生简单查询。 Vault 没有查询引擎,但需要直接访问 HTTP 上下文路径。 Vault 查询方法将 Vault 的 API 可能性转换为查询。 查询方法执行在上下文路径下列出子项,对 Id 应用筛选,(可选)使用 offset/limit 限制 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。 与查询方法谓词不同,排序 has 不限于特定字段。 在 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. 使用乐观锁定可确保更新仅应用于具有匹配版本的密钥。 因此,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 更新 secret 并让 Vault 递增版本。
4 更新使用以前版本的第二个实例。 作失败,并显示OptimisticLockingFailureException因为在此期间 Vault 中的版本已递增。
删除受版本控制的密钥时,按 ID 删除将删除最新的密钥。Delete by entity (按实体删除) 删除所提供版本的密钥。

13.5. 访问受版本控制的 secret

键/值版本 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

使用特定客户端需要在 Classpath 上提供相应的依赖项 因此 Spring Vault 可以使用可用的 Client 端与 Vault 进行通信。spring-doc.cadn.net.cn

14.1. Java 的内置HttpURLConnection

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

14.2. 外部客户端

您可以使用外部客户端访问 Vault 的 API。只需添加以下选项之一 dependencies 添加到您的项目中。如果使用 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 之间的流量(令牌和密钥)。
例 25.方形 OkHttp 3
<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
</dependency>
例 26.Reactor 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 Components 或 OkHttp 客户端位于您的 class-path 上时,才能应用。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 并访问以下 Secret 由基础角色允许。选择适当的客户端身份验证,然后 将凭证注入应用程序需要接受风险评估。spring-doc.cadn.net.cn

Spring 的 PropertySource 抽象是天作之合 将配置保留在应用程序代码之外。您可以使用系统属性、环境 变量或属性文件来存储登录凭据。每种方法都有自己的属性。 请记住,命令行和环境属性可以通过适当的 OS 访问级别。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由于 Environment bean 仍在构建中,autowire 将在稍后阶段进行。您的 configuration 类应该实现ApplicationContextAware并获取EnvironmentApplicationContext.

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

15.2. 令牌身份验证

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

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

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

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

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

    // …
}

另请参阅:spring-doc.cadn.net.cn

15.3. AppId 身份验证

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

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

基于 IP 地址的 UserId 使用本地主机的 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. 自定义 UserId

更高级的方法允许您实现自己的AppIdUserIdMechanism. 此类必须位于您的 Classpath 上,并且必须实现 这org.springframework.vault.authentication.AppIdUserIdMechanism接口 和createUserId方法。Spring Vault 将获取 UserId 通过调用createUserId每次使用 AppId 进行身份验证时,都会将 AppId 迁移到 获取 Token。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 身份验证由两个难以猜测的(秘密)令牌组成: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 将使用角色名称和初始令牌来检索它们。这 初始令牌可能与 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 身份验证后端不同,此后端 不需要首先部署或预置安全敏感型 凭据(令牌、用户名/密码、客户端证书等)。 相反,它将 AWS 视为受信任的第三方,并使用 加密签名的动态元数据信息,该信息具有唯一性 表示每个 EC2 实例。spring-doc.cadn.net.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

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

    // …
}

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

在第一次登录期间, Spring Vault 会生成一个 nonce ,该实例 ID 存储在 auth 后端中。 重新身份验证需要发送相同的 nonce。任何其他 参与方没有 nonce,并且可以在 Vault 中引发警报 进一步调查。spring-doc.cadn.net.cn

nonce 保存在内存中,并在应用程序重启期间丢失。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 开发工具包依赖项 (com.amazonaws:aws-java-sdk-core) 因为身份验证实施使用 AWS 开发工具包类型进行凭证和请求签名。spring-doc.cadn.net.cn

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

另请参阅:spring-doc.cadn.net.cn

15.7. Azure (MSI) 身份验证

azure auth 后端提供了一种安全的引入机制 对于 Azure VM 实例,允许自动检索 Vault 令 牌。与大多数 Vault 身份验证后端不同,此后端 不需要首先部署或预置安全敏感型 凭据(令牌、用户名/密码、客户端证书等)。 相反,它将 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

另请参阅:spring-doc.cadn.net.cn

15.8. GCP-GCE 身份验证

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

GCP GCE (Google Compute Engine) 身份验证以 服务账户的 JSON Web 令牌 (JWT)。Compute Engine 实例的 JWT 使用实例标识从 GCE 元数据服务获取。 此 API 创建可用于确认实例身份的 JSON Web 令牌。spring-doc.cadn.net.cn

与大多数 Vault 身份验证后端不同,此后端 不需要首先部署或预置安全敏感型 凭据(令牌、用户名/密码、客户端证书等)。 相反,它将 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());
    }

    // …
}

另请参阅:spring-doc.cadn.net.cn

15.9. GCP-IAM 身份验证

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

GCP IAM 身份验证以 JSON Web 令牌 (JWT) 的形式创建签名 对于服务帐户。服务帐户的 JWT 由 调用 GCP IAM 的projects.serviceAccounts.signJwt应用程序接口。调用方根据 GCP IAM 进行身份验证 并由此证明了它的身份。此保险柜后端将 GCP 视为受信任的第三方。spring-doc.cadn.net.cn

IAM 凭证可以从运行时环境中获取 或作为 e.g. JSON 从外部供应。JSON 是首选形式,因为它 携带调用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 令牌来维护令牌生命周期。所有 API 是同步的,因此,GcpIamCredentialsAuthentication不支持AuthenticationSteps哪个是 对于反应式使用是必需的。
GcpIamCredentialsAuthentication使用 IAM 凭证 API,并使用已弃用的GcpIamAuthentication使用已弃用的 IAM API

另请参阅:spring-doc.cadn.net.cn

15.10. PCF 身份验证

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

PCF 身份验证使用实例密钥和证书创建由 Vault 验证的签名。 如果签名匹配,并且可能绑定的 organization/space/application ID 匹配,则 Vault 会颁发适当范围的令牌。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

另请参阅:spring-doc.cadn.net.cn

15.11. TLS 证书身份验证

certauth backend 允许使用 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,其中包含客户端 certificate 和私有密钥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 身份验证使用令牌作为主要登录方法。 临时令牌用于从 Vault 的 Cubbyhole 秘密后端。登录令牌的生命周期通常更长,并且用于 与 Vault 交互。登录令牌可以从包装的 响应或从data部分。spring-doc.cadn.net.cn

创建包装令牌spring-doc.cadn.net.cn

用于创建令牌的响应包装需要 Vault 0.6.0 或更高版本。
例 31.装箱和存储令牌
$ 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.包装令牌响应用法
@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

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

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

    // …
}

使用存储的令牌spring-doc.cadn.net.cn

例 33.装箱和存储令牌
$ 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.存储令牌响应使用情况
@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

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

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

另请参阅:spring-doc.cadn.net.cn

15.13. Kubernetes 身份验证

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

使用 Kubernetes 身份验证需要 Kubernetes 服务帐户令牌, 通常安装在/var/run/secrets/kubernetes.io/serviceaccount/token. 该文件包含读取并发送到 Vault 的令牌。 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

另请参阅:spring-doc.cadn.net.cn

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

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

UserPasswordAuthenticationOptions可以与上述所有身份验证后端一起使用,因为 Login API 在所有机制中都是相似的。 请确保在配置时使用适当的 auth 挂载路径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());
    }

    // …
}

另请参阅:spring-doc.cadn.net.cn

15.15. 身份验证步骤

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

身份验证方法的组合和重用常见步骤,例如发布登录 payload 添加到 Vault 或从 HTTP 源检索身份验证输入 跟ClientAuthentication对象。spring-doc.cadn.net.cn

身份验证步骤提供常见身份验证活动的可重用性。 步骤创建方式AuthenticationSteps在函数式 样式将实际的身份验证执行留给特定的执行程序。spring-doc.cadn.net.cn

例 36.存储令牌身份验证流程。
AuthenticationSteps.just(VaultToken.of(…));                              (1)
1 创建AuthenticationStepsVaultToken.

可以从单个输入创建单步身份验证流程。声明 多个身份验证步骤以SupplierHttpRequest提供 authentication state 对象,该对象可用于 Map 或 post 到 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 令牌。 请注意,模板变量受 URL 转义的约束。

身份验证流需要执行程序来执行实际登录。我们提供两个 executor 对于不同的执行模型: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. Token 生命周期

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

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

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

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

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