参考文档

7. 保险库支持

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

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

  • VaultTemplate提高执行公共 Vault 操作。包括 Vault 响应和 POJO 之间的集成对象映射。spring-doc.cn

对于大多数任务,您会发现自己使用 丰富的通信功能。 是值得寻找的地方 访问功能,例如从 Vault 读取数据或颁发 管理命令。 还提供回调方法,方便您 获取低级 API 工件,例如 to communicate 直接与 Vault 一起使用。VaultTemplateVaultTemplateVaultTemplateRestTemplatespring-doc.cn

7.1. 依赖项

如果要在项目中使用 Spring Vault,请声明对工件的依赖关系。spring-vault-corespring-doc.cn

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

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

7.2. Spring 框架

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

8. 开始使用

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

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

要在 STS 中创建 Spring 项目,请转到 File → New → Spring 模板项目 → 简单的 Spring Utility Project → 出现提示时按 Yes。然后输入项目和包名称,例如 .org.spring.vault.examplespring-doc.cn

然后将以下内容添加到 dependencies 部分。pom.xmlspring-doc.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 存储库添加到位于元素同一级别的 maven。pom.xml<dependencies/>spring-doc.cn

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

存储库也可以在此处浏览spring-doc.cn

如果您使用的是 SNAPSHOT,则还需要添加 Spring 的位置 Snapshot repository 添加到您的 maven,该 maven 位于元素的同一级别。pom.xml<dependencies/>spring-doc.cn

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

存储库也可以在此处浏览spring-doc.cn

创建一个简单的类以持久化:Secretsspring-doc.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.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.cn

  • 您可以使用对象和 . 你不需要启动 Spring Context 来使用 Spring Vault。org.springframework.vault.client.VaultEndpointClientAuthenticationspring-doc.cn

  • Vault 应配置根令牌 of 以运行此应用程序。00000000-0000-0000-0000-000000000000spring-doc.cn

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

  • 映射约定可以使用字段访问。请注意,该类只有 getter。Secretsspring-doc.cn

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

9. VaultTemplate 简介

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

配置后,是线程安全的,并且可以在 多个实例。VaultTemplate

Vault 文档和域类之间的映射是通过委托 来完成的。Spring Web 支持提供了映射基础结构。RestTemplatespring-doc.cn

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

引用实例上的操作的首选方式 通过其接口 .VaultTemplateVaultOperations

虽然有许多方便的方法可以轻松帮助您 如果您需要直接访问 Vault API 以访问 功能未明确公开的 你可以使用 多个 execute 回调方法以访问底层 API。执行回调 将为您提供对对象的引用。 有关更多信息,请参阅 执行回调 部分。VaultTemplateVaultTemplateRestOperationsspring-doc.cn

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

9.1. 注册和配置 Spring Vault bean

使用 Spring Vault 不需要 Spring Context。但是,托管上下文的实例 和 注册 将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处理活动的 Vault 会话非常有用 应用程序关闭。您还可以在应用程序中重复使用同一实例。VaultTemplateSessionManagerVaultTemplatespring-doc.cn

Spring Vault 附带了一个支持 bean 定义的配置类 在 Spring 上下文中使用。应用程序配置 类通常扩展自 和 required 到 提供特定于环境的其他详细信息。AbstractVaultConfigurationspring-doc.cn

从 requires 扩展到 implement ' VaultEndpoint vaultEndpoint()' 和方法。AbstractVaultConfigurationClientAuthentication clientAuthentication()spring-doc.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 创建一个默认指向 的新 。VaultEndpointhttps://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 方法的依赖项可以从您的配置中获得,也可以由您的配置提供。ClientAuthenticationAbstractVaultConfiguration
在某些情况下,创建自定义配置类可能会很麻烦。 看看它允许使用 来自现有属性源的属性和 Spring 的 .阅读更多 在使用 EnvironmentVaultConfiguration 中。EnvironmentVaultConfigurationEnvironment

9.2. 会话管理

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

  • SimpleSessionManager:仅从提供的 中获取令牌,无需刷新和吊销ClientAuthenticationspring-doc.cn

  • LifecycleAwareSessionManager:此计划令牌 如果令牌可续订,则续订,并在处置时撤销登录令牌。 续订计划使用 . 如果使用 .SessionManagerAsyncTaskExecutorLifecycleAwareSessionManagerAbstractVaultConfigurationspring-doc.cn

9.3. 使用EnvironmentVaultConfiguration

Spring Vault 包括从 Spring 配置 Vault 客户端和一组预定义的 属性键。 支持经常应用的配置。通过从最合适的配置类派生来支持其他配置。Include with 到现有 基于 Java 的配置类,并通过 Spring 的任何 s.EnvironmentVaultConfigurationEnvironmentEnvironmentVaultConfigurationEnvironmentVaultConfiguration@Import(EnvironmentVaultConfiguration.class)PropertySourcespring-doc.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.cn

  • Vault URI:vault.urispring-doc.cn

  • SSL 配置spring-doc.cn

    • 密钥库资源:(可选)vault.ssl.key-storespring-doc.cn

    • 密钥库密码:(可选)vault.ssl.key-store-passwordspring-doc.cn

    • 密钥库类型:(可选,通常,还支持vault.ssl.key-store-typejkspem)spring-doc.cn

    • 信任库资源:(可选)vault.ssl.trust-storespring-doc.cn

    • 信任库密码:(可选)vault.ssl.trust-store-passwordspring-doc.cn

    • 信任库类型:(可选,通常,还支持vault.ssl.trust-store-typejkspem)spring-doc.cn

    • 已启用的 SSL/TLS 协议:(自 2.3.2 起,可选,协议以逗号分隔)vault.ssl.enabled-protocolsspring-doc.cn

    • 已启用 SSL/TLS 密码套件:(自 2.3.2 起,可选,密码套件以逗号分隔)vault.ssl.enabled-cipher-suitesspring-doc.cn

  • 身份验证方法:(默认为 ,支持的身份验证方法包括:、、vault.authenticationTOKENTOKENAPPIDAPPROLEAWS_EC2AWS_IAMAZURECERTCUBBYHOLEKUBERNETES)spring-doc.cn

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

  • AppId 路径:(默认为vault.app-id.app-id-pathapp-id)spring-doc.cn

  • AppId 中:vault.app-id.app-idspring-doc.cn

  • UserId: . 并使用相应的用户 ID 机制。 任何其他值都与 一起使用。vault.app-id.user-idMAC_ADDRESSIP_ADDRESSMacAddressUserIdIpAddressUserIdStaticUserIdspring-doc.cn

无配置选项。spring-doc.cn

  • Kubernetes path:(默认为vault.kubernetes.kubernetes-pathkubernetes)spring-doc.cn

  • 角色:vault.kubernetes.rolespring-doc.cn

  • 服务帐户令牌文件的路径:(默认为vault.kubernetes.service-account-token-file/var/run/secrets/kubernetes.io/serviceaccount/token)spring-doc.cn

9.4. 执行回调

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

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

  • <T> T doWithVault 执行给定的 ,允许使用 与 Vault 交互,而无需会话。(RestOperationsCallback<T> callback)RestOperationsCallbackRestOperationsspring-doc.cn

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

下面是一个使用 初始化 Vault 的示例:ClientCallbackspring-doc.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.cn

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

你可以通过直接 (, ) 上的方法使用所有其他后端。VaultTemplateVaultTemplate.read(…)VaultTemplate.write(…)spring-doc.cn

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

Secrets 引擎用于将任意 Secret 存储在为 Vault 配置的物理存储中。kvspring-doc.cn

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

Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。 遵循 Vault CLI 设计。 这是 Vault 的主要命令行工具,提供 等命令。VaultKeyValueOperationsvault kv getvault kv putspring-doc.cn

通过指定版本和挂载路径,您可以将此 API 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 1:spring-doc.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 操作,例如 、 。putgetdeletelistspring-doc.cn

或者,由于 API 的直接映射和使用简单,因此可以通过 API 使用,因为键和响应直接映射到输入和输出键。 以下示例说明了在 中写入和读取密钥。 Secrets 引擎挂载在 :VaultTemplatemykeykvsecretspring-doc.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.cn

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

您可以在以下两个版本之一中运行密钥引擎。 本节介绍如何使用版本 2。运行后端的版本 2 时,密钥可以保留可配置数量的版本。 您可以检索旧版本的元数据和数据。 此外,您还可以使用 check-and-set 操作来避免无意中覆盖数据。kvkvspring-doc.cn

键值版本 1(“未版本控制的秘密”)类似,Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。 Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。 遵循 Vault CLI 设计。 这是 Vault 的主要命令行工具,提供 、 等命令。VaultKeyValueOperationsvault kv getvault kv putspring-doc.cn

通过指定版本和挂载路径,您可以将此 API 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 2:spring-doc.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支持所有键值操作,例如 、 、 、 。putgetdeletelistspring-doc.cn

您还可以与版本控制的键值 API 的具体内容进行交互。如果要获取特定密钥或需要访问元数据,这将非常有用。spring-doc.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 更新版本控制密钥时,输入必须引用之前获取的版本。

虽然可以使用 v2 Secrets Engine through。 这不是最方便的方法,因为 API 为上下文路径以及 input/output 的表示方式提供了一种不同的方法。 具体来说,与实际 secret 的交互需要包装和解包数据部分,并在挂载和 secrets 键之间引入路径段。kvVaultTemplatedata/spring-doc.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.cn

10.3. PKI(公钥基础设施)

Secrets 引擎通过实施证书颁发机构操作来表示证书的后端。pkispring-doc.cn

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

Spring Vault 支持通过 . 所有其他 PKI 功能都可以通过 使用。VaultPkiOperationsVaultOperationsspring-doc.cn

以下示例简要说明了如何颁发和吊销证书的用法:spring-doc.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.cn

10.4. 令牌认证后端

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

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

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

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

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

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

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

10.5. Transit 后端

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

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

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

其中的所有操作都以键为中心。 Transit 引擎支持密钥和各种密钥类型的版本控制。 请注意,密钥类型可能会对可以使用的操作施加限制。transitspring-doc.cn

以下示例说明如何创建密钥以及如何加密和解密数据:spring-doc.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 接下来,我们加密包含应加密的纯文本的 a。 input 使用 default 将字符串编码为其二进制表示形式。 请求令牌会返回一个 ,该令牌用作 Vault 令牌的值对象。 该方法返回 Base64 编码的密文,通常以 .StringStringCharsetVaultTokenencryptvault:
3 要将密文解密为纯文本,请调用该方法。 它解密密文并返回使用默认字符集解码的 a。decryptString

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

要加密和解密二进制数据,请使用可以保存二进制值的 and value 对象:PlaintextCiphertextspring-doc.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-keyPlaintextencryptCiphertext
2 该对象可以直接用于解密并返回一个对象。CiphertextPlaintext

Plaintext并附带一个上下文对象 . 它用于为收敛加密提供 nonce 值,以及用于利用密钥派生的上下文值。CiphertextVaultTransitContextspring-doc.cn

Transit 允许对纯文本进行签名并验证给定纯文本的签名。 签名操作需要非对称密钥,通常使用椭圆曲线加密或 RSA。spring-doc.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 将为纯文本消息创建签名。返回的字符串包含使用 Base64 字符的 ASCII 安全字符串。Signature
3 要验证签名,验证需要一个 Signature 对象和纯文本消息。作为返回值,您可以获得签名是否有效。

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

11. ReactiveVaultTemplate 简介

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

11.1. 什么是反应式编程?

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

响应式应用程序的一个关键方面是背压的概念,这是一种机制 确保生产者不会压倒消费者。例如,在 reactive 的管道中 组件从数据库扩展到 HTTP 响应(当 HTTP 连接为 太慢,数据存储库也可能减慢或完全停止,直到网络容量释放。spring-doc.cn

11.2. 反应式 Vault 客户端

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

它公开为 的供应商 以验证 HTTP 请求 并作为主要入口点。的核心配置和 SSL 在 各种客户端实现。VaultTokenSupplierVaultTokenReactiveVaultOperationsVaultEndpointClientOptionsspring-doc.cn

类 ,位于包 中 , 是 Spring 的反应式 Vault 支持的中心类,提供了丰富的功能集,以 与 Vault 交互。该模板提供了方便的读取、写入和 删除 Vault 中的数据,并提供域对象与 Vault 数据之间的映射。ReactiveVaultTemplateorg.springframework.vault.corespring-doc.cn

配置后,是线程安全的,并且可以在 多个实例。ReactiveVaultTemplate

Vault 文档和域类之间的映射是通过 declarating to 及其编解码器完成的。WebClientspring-doc.cn

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

引用实例上的操作的首选方式 通过其接口 .ReactiveVaultTemplateReactiveVaultOperations

功能未由 你可以使用 多个 execute 回调方法以访问底层 API。执行回调 将为您提供对对象的引用。 有关更多信息,请参阅 执行回调 部分。ReactiveVaultTemplateWebClientspring-doc.cn

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

11.3. 注册和配置 Spring Vault bean

使用 Spring Vault 不需要 Spring Context。但是,托管上下文的实例 和 注册 将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处理活动的 Vault 会话非常有用 应用程序关闭。您还可以在应用程序中重复使用同一实例。ReactiveVaultTemplateVaultTokenSupplierReactiveVaultTemplatespring-doc.cn

Spring Vault 附带了一个支持 bean 定义的配置类 在 Spring 上下文中使用。应用程序配置 类通常扩展自 和 required 到 提供特定于环境的其他详细信息。AbstractVaultConfigurationspring-doc.cn

从 requires 扩展到 implement ' VaultEndpoint vaultEndpoint()' 和方法。AbstractVaultConfigurationClientAuthentication clientAuthentication()spring-doc.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 创建一个默认指向 的新 。VaultEndpointhttps://localhost:8200
2 此示例用于快速入门。 有关支持的身份验证方法的详细信息,请参阅身份验证方法TokenAuthentication

11.4. 会话管理

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

11.5. 执行回调

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

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

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

  • <T> T doWithSession 会话 编写一个 reactive sequence 中给定的 ,允许在经过身份验证的会话中与 Vault 进行交互。(Function<WebClient, ? extends T> clientCallback)WebClientspring-doc.cn

下面是一个使用回调初始化 Vault 的示例:spring-doc.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.cn

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

12.1. 注册VaultPropertySource

Spring Vault 提供了一个与 Vault 一起使用以获取 性能。它使用嵌套元素来公开 stored 和 在 Vault 中加密。VaultPropertySourcedataspring-doc.cn

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

在上面的代码中, 已添加具有最高优先级 在搜索中。如果它包含 'foo' 属性,则将被检测并返回 在任何其他 . 公开了许多允许精确 操作属性源集。VaultPropertySourcefooPropertySourceMutablePropertySourcesspring-doc.cn

12.2. @VaultPropertySource

注解提供了一个方便且声明性的 将 a 添加到 Spring 以与 classes 结合使用的机制。@VaultPropertySourcePropertySourceEnvironment@Configurationspring-doc.cn

@VaultPropertySource采用 Vault 路径(如 and )将存储在节点中的数据公开在 . 支持与租约关联的密钥的租约 (即来自后端的凭证)和终端上的凭证轮换 租约到期。默认情况下,租约续订处于禁用状态。secret/my-applicationPropertySource@VaultPropertySourcemysqlspring-doc.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
}
从秘密后端获得的秘密与 TTL () 相关联,而不是与租约 ID 相关联。Spring Vault 在达到其 TTL 时轮换通用秘密。genericrefresh_intervalPropertySource
您可以使用 从受版本控制的 Key-Value 后端获取最新的密钥版本。确保路径中不包含该区段。@VaultPropertySourcedata/

路径中存在的任何占位符都将根据已针对环境注册的属性源集进行解析,如下例所示:${…​}@VaultPropertySourcespring-doc.cn

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

假设它存在于已注册的属性源之一(例如,系统属性或环境变量)中,则占位符将解析为相应的值。 如果不是,则 用作默认值。 如果未指定 default 且无法解析属性,则会引发 an。my.placeholderfallback/valueIllegalArgumentExceptionspring-doc.cn

在某些情况下,严格控制可能是不可能的或不切实际的 使用注释时的属性源排序。 例如,如果上面的类是通过 component-scanning 中,顺序很难预测。 在这种情况下 - 如果覆盖很重要 - 建议将 用户回退到使用编程式 PropertySource API。 有关详细信息,请参阅 ConfigurableEnvironmentMutablePropertySources@VaultPropertySource@Configurationspring-doc.cn

13. Vault 存储库

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

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

13.1. 用法

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

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

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

我们这里有一个非常简单的 domain 对象。 请注意,它有一个名为 annotated with 的属性,并且其类型上有一个 annotation。 这两个负责创建用于将对象作为 JSON 保存在 Vault 中的实际密钥。idorg.springframework.data.annotation.Id@Secretspring-doc.cn

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

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

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

}

随着我们的存储库扩展,它提供了基本的 CRUD 和查询方法。 Vault 存储库需要 Spring Data 组件。 确保在类路径中包含 and artifacts。CrudRepositoryspring-data-commonsspring-data-keyvaluespring-doc.cn

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

然后将以下内容添加到 dependencies 部分。pom.xmlspring-doc.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.cn

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

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

鉴于上面的设置,我们可以继续并注入到我们的组件中。CredentialsRepositoryspring-doc.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 使用键模式将 Vault Hash 中的属性存储在键值 Secret Secrets 引擎中。Credentialskeyspace/idcredentials/heisenberg
2 使用提供的 ID 检索存储在 .keyspace/id
3 计算 on 定义的密钥空间凭据中可用的实体总数。@SecretCredentials
4 从 Vault 中删除给定对象的密钥。

13.2. 对象到 Vault 的 JSON 映射

Vault 存储库使用 JSON 作为交换格式将对象存储在 Vault 中。 JSON 和实体之间的对象映射由 完成。 转换器读取和写入包含来自 .从 Vault 中读取,并且 Jackson 将正文反序列化为 of 和 。 默认实现读取 with nested values 和 objects 并将它们转换为 entities,反之亦然。VaultConverterSecretDocumentVaultResponseVaultResponseMapStringObjectVaultConverterMapListMapspring-doc.cn

给定前面部分的类型,默认映射如下:Credentialsspring-doc.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 简单属性值按 path 进行映射。
3 复杂类型的属性映射为嵌套对象。
该属性必须映射到 。@IdString
表 1.默认映射规则
类型 样本 映射值

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

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

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

复杂型
(例如。地址)spring-doc.cn

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

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

简单类型列表
spring-doc.cn

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

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

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

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

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

复杂类型列表
spring-doc.cn

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

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

您可以通过在 中注册 来自定义映射行为。 这些转换器可以处理从类型转换/转换为类型,例如,第一个转换器适合将简单属性转换为其 JSON 表示形式,最后一个复杂类型适合转换。 第二个选项提供对生成的 . 写入对象将删除内容并重新创建整个条目,因此未映射的数据将丢失。ConverterVaultCustomConversionsLocalDateSecretDocumentSecretDocumentVaultspring-doc.cn

13.3. 查询和查询方法

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

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

  List<Credentials> findByIdStartsWith(String prefix);
}
Vault 存储库的查询方法仅支持在属性上具有谓词的查询。@Id

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

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

After,GreaterThanspring-doc.cn

findByIdGreaterThan(String id)spring-doc.cn

GreaterThanEqualspring-doc.cn

findByIdGreaterThanEqual(String id)spring-doc.cn

Before,LessThanspring-doc.cn

findByIdLessThan(String id)spring-doc.cn

LessThanEqualspring-doc.cn

findByIdLessThanEqual(String id)spring-doc.cn

Betweenspring-doc.cn

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

Inspring-doc.cn

findByIdIn(Collection ids)spring-doc.cn

NotInspring-doc.cn

findByIdNotIn(Collection ids)spring-doc.cn

Like, ,StartingWithEndingWithspring-doc.cn

findByIdLike(String id)spring-doc.cn

NotLike,IsNotLikespring-doc.cn

findByIdNotLike(String id)spring-doc.cn

Containingspring-doc.cn

findByFirstnameContaining(String id)spring-doc.cn

NotContainingspring-doc.cn

findByFirstnameNotContaining(String name)spring-doc.cn

Regexspring-doc.cn

findByIdRegex(String id)spring-doc.cn

(No keyword)spring-doc.cn

findById(String name)spring-doc.cn

Notspring-doc.cn

findByIdNot(String id)spring-doc.cn

Andspring-doc.cn

findByLastnameAndFirstnamespring-doc.cn

Orspring-doc.cn

findByLastnameOrFirstnamespring-doc.cn

Is,Equalsspring-doc.cn

findByFirstname,,findByFirstnameIsfindByFirstnameEqualsspring-doc.cn

Top,Firstspring-doc.cn

findFirst10ByFirstname,findTop5ByFirstnamespring-doc.cn

13.3.1. 排序和分页

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

使用分页和排序需要在过滤 Id 之前获取密钥,这会影响性能。 排序和分页保证即使 Vault 返回的 Id 的自然顺序发生变化,也会返回相同的结果。 因此,首先从 Vault 获取所有 ID,然后应用排序,然后进行过滤和偏移/限制。spring-doc.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 属性的实际值将通过该属性添加到更新请求中。 如果另一个操作同时更改了密钥,则会引发 OptimisticLockingFailureException,并且不会更新密钥。@Versioncasspring-doc.cn

更新密钥时,版本属性必须是数字属性,例如 or 和 map 到属性。intlongcasspring-doc.cn

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

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

以下示例显示了这些功能:spring-doc.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 更新使用以前版本的第二个实例。 操作失败,并显示 an ,因为在此期间 Vault 中的版本已递增。OptimisticLockingFailureException
删除受版本控制的密钥时,按 ID 删除将删除最新的密钥。Delete by entity (按实体删除) 删除所提供版本的密钥。

13.5. 访问受版本控制的 secret

键/值版本 2 密钥引擎维护可通过在 Vault 存储库接口声明中实现 RevisionRepository 来访问的密钥版本。 修订版本库定义查找方法以获取特定标识符的修订版本。 标识符必须为 .Stringspring-doc.cn

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

}
1 第一个类型参数 () 表示实体类型,第二个 () 表示 id 属性的类型,最后一个 () 是修订号的类型。Vault 仅支持标识符和修订版号。CredentialsStringIntegerStringInteger

13.5.1. 用法

您现在可以使用 methods from 来查询实体的修订版,如下例所示:RevisionRepositoryspring-doc.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.cn

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

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

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

14.1. Java 的内置HttpURLConnection

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

14.2. 外部客户端

您可以使用外部客户端访问 Vault 的 API。只需添加以下选项之一 dependencies 添加到您的项目中。如果使用 Spring Vault 的依赖项 BOM,则可以省略版本号spring-doc.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。 您可以设置其中任一来配置 JVM 范围的 SSL 设置或配置为仅为 Spring Vault 设置 SSL 设置。SslConfigurationjavax.net.ssl.trustStoreSslConfigurationspring-doc.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 仅配置密钥存储设置并提供密钥配置。

请注意,只有当 Apache Http Components 或 OkHttp 客户端位于您的 class-path 上时,才能应用提供。SslConfigurationspring-doc.cn

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

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

PEM 文件可能包含一个或多个证书(和 块)。 添加到底层的证书使用完整的使用者名称作为别名。-----BEGIN CERTIFICATE----------END CERTIFICATE-----KeyStorespring-doc.cn

15. 身份验证方法

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

15.1. 外部化登录凭证

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

向任何一方泄露登录凭证允许登录 Vault 并访问以下 Secret 由基础角色允许。选择适当的客户端身份验证,然后 将凭证注入应用程序需要接受风险评估。spring-doc.cn

Spring 的 PropertySource 抽象是天作之合 将配置保留在应用程序代码之外。您可以使用系统属性、环境 变量或属性文件来存储登录凭据。每种方法都有自己的属性。 请记住,命令行和环境属性可以通过适当的 OS 访问级别。spring-doc.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 允许通过多种方式获取 .使用 , inject via 时,将不会提供,因为环境 bean 仍在构建中,并且自动装配将在稍后阶段进行。您的配置类应该实现并获取 from .EnvironmentVaultPropertySource@Autowired Environment environmentEnvironmentApplicationContextAwareEnvironmentApplicationContext

有关在组件和其他属性源中引用属性的示例,请参阅 SecurePropertyUsage.javaspring-doc.cn

15.2. 令牌身份验证

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

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

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

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

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

    // …
}

另请参阅:spring-doc.cn

15.3. AppId 身份验证

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

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

基于 IP 地址的 UserId 使用本地主机的 IP 地址。spring-doc.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.cn

$ echo -n 192.168.99.1 | sha256sum
包括指向不同哈希值的潜在客户的换行符 因此,请确保包含该标志。echo-n

基于 Mac 地址的 UserId 从 localhost 绑定的设备。该配置还允许指定 选择正确设备的提示。的值是可选的,可以是接口 名称或接口索引(从 0 开始)。network-interfacenetwork-interfacespring-doc.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.cn

$ echo -n 0AFEDE1234AC | sha256sum
Mac 地址指定为大写,不带冒号。 包括指向不同哈希值的潜在客户的换行符 因此,请确保包含该标志。echo-n

15.3.1. 自定义 UserId

更高级的方法允许您实现自己的 . 此类必须位于您的 Classpath 上,并且必须实现 界面 和方法。Spring Vault 将获取 UserId 每次使用 AppId 进行身份验证时调用 获取 Token。AppIdUserIdMechanismorg.springframework.vault.authentication.AppIdUserIdMechanismcreateUserIdcreateUserIdspring-doc.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.cn

Spring Vault 通过仅提供 RoleId 来支持 AppRole 身份验证 或者与提供的 SecretId 一起从 Vault 获取 RoleId/SecretId (带有响应展开的推拉模式)。spring-doc.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.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.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

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

    // …
}

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

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

nonce 保存在内存中,并在应用程序重启期间丢失。spring-doc.cn

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

15.6. AWS-IAM 身份验证

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

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

IAM 凭证可以从运行时环境中获取 或外部供应。运行时环境,例如 AWS-EC2、 具有分配的 IAM 委托人的 Lambda 和 ECS 不需要特定于客户端的 配置凭证,但可以从其元数据源获取这些凭证。spring-doc.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 开发工具包依赖项 () 因为身份验证实施使用 AWS 开发工具包类型进行凭证和请求签名。com.amazonaws:aws-java-sdk-corespring-doc.cn

您可以通过 配置身份验证。AwsIamAuthenticationOptionsspring-doc.cn

另请参阅:spring-doc.cn

15.7. Azure (MSI) 身份验证

azure auth 后端提供了一种安全的引入机制 对于 Azure VM 实例,允许自动检索 Vault 令 牌。与大多数 Vault 身份验证后端不同,此后端 不需要首先部署或预置安全敏感型 凭据(令牌、用户名/密码、客户端证书等)。 相反,它将 Azure 视为受信任的第三方,并使用 托管服务身份和实例元数据信息,可以是 绑定到 VM 实例。spring-doc.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 名称)。这些详细信息可以通过 进行配置。 如果未配置,则查询 Azure 的实例元数据服务以 获取这些详细信息。AzureMsiAuthenticationOptionsBuilderAzureMsiAuthenticationspring-doc.cn

另请参阅:spring-doc.cn

15.8. GCP-GCE 身份验证

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

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

与大多数 Vault 身份验证后端不同,此后端 不需要首先部署或预置安全敏感型 凭据(令牌、用户名/密码、客户端证书等)。 相反,它将 GCP 视为受信任的第三方,并使用 加密签名的动态元数据信息,该信息具有唯一性 表示每个 GCP 服务帐户。spring-doc.cn

您可以通过 配置身份验证。GcpComputeAuthenticationOptionsspring-doc.cn

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

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

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

    // …
}

另请参阅:spring-doc.cn

15.9. GCP-IAM 身份验证

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

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

IAM 凭证可以从运行时环境中获取 或作为 e.g. JSON 从外部供应。JSON 是首选形式,因为它 包含调用 所需的项目 ID 和服务帐户标识符。projects.serviceAccounts.signJwtspring-doc.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 依赖项 () 因为身份验证实施使用 Google API 进行凭据和 JWT 签名。com.google.cloud:google-cloud-iamcredentialsspring-doc.cn

您可以通过 配置身份验证。GcpIamCredentialsAuthenticationOptionsspring-doc.cn

Google 凭据需要 OAuth 2 令牌来维护令牌生命周期。所有 API 是同步的,因此不支持哪个是 对于反应式使用是必需的。GcpIamCredentialsAuthenticationAuthenticationSteps
GcpIamCredentialsAuthentication使用 IAM 凭证 API,并且是使用已弃用的 IAM API 替换已弃用的。GcpIamAuthentication

另请参阅:spring-doc.cn

15.10. PCF 身份验证

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

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

实例凭证可从 files at 和 variables.CF_INSTANCE_CERTCF_INSTANCE_KEYspring-doc.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.cn

您可以通过 配置身份验证。PcfAuthenticationOptionsspring-doc.cn

另请参阅:spring-doc.cn

15.11. TLS 证书身份验证

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

要启用身份验证,您需要:certspring-doc.cn

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

  2. 配置包含客户端的 Java certificate 和私有密钥Keystorespring-doc.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 交互。登录令牌可以从包装的 响应或从该部分。dataspring-doc.cn

创建包装令牌spring-doc.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.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.cn

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

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

另请参阅:spring-doc.cn

15.13. Kubernetes 身份验证

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

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

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

@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

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

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

    // …
}

您可以通过 配置身份验证。KubernetesAuthenticationOptionsspring-doc.cn

另请参阅:spring-doc.cn

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

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

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

15.15. 身份验证步骤

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

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

身份验证步骤提供常见身份验证活动的可重用性。 通过 描述函数中的身份验证流创建的步骤 样式将实际的身份验证执行留给特定的执行程序。AuthenticationStepsspring-doc.cn

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

可以从单个输入创建单步身份验证流程。声明 多个身份验证步骤以 或 开头,提供 authentication state 对象,该对象可用于 Map 或 post 到 Vault 进行登录。SupplierHttpRequestspring-doc.cn

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

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

    .login("auth/{mount}/login", options.getPath());                    (3)
1 开始声明接受 . 状态对象类型取决于响应类型,该类型可在后续步骤中映射。AuthenticationStepsSupplier<T>Supplier
2 实际实现。 在本例中创建一个。SupplierMap
3 通过将状态对象 () 发布到 Vault 端点以创建 Vault 令牌来执行 Vault 登录。 请注意,模板变量受 URL 转义的约束。Map

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

  • AuthenticationStepsExecutor作为 SYNCHRONOUS 的直接替代品。ClientAuthenticationspring-doc.cn

  • AuthenticationStepsOperator进行响应式执行。spring-doc.cn

许多 都带有静态工厂方法,用于为其特定于身份验证的选项创建:ClientAuthenticationAuthenticationStepsspring-doc.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.cn

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

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

TokenAuthentication 等身份验证方法只是创建一个不携带任何可续订性/TTL 详细信息的身份验证方法。 将对令牌运行自查找,以从 Vault 中检索可续订性和 TTL。 如果启用了自查找,则会定期续订。请注意,永远不会撤销,只会被撤销。VaultTokenLifecycleAwareSessionManagerVaultTokenVaultTokenLoginTokenspring-doc.cn

直接创建的身份验证方法(所有基于登录的身份验证方法)已经提供了设置令牌续订所需的所有详细信息。如果会话管理器已关闭,则从登录中获取的令牌将被撤销。LoginTokenLifecycleAwareSessionManagerspring-doc.cn