参考文档
7. 保险库支持
Vault 支持包含广泛的功能,总结如下。
-
使用基于 Java 的 @Configuration 类的 Spring 配置支持
-
VaultTemplate
提高执行公共 Vault作。包括 Vault 响应和 POJO 之间的集成对象映射。
对于大多数任务,您会发现自己使用VaultTemplate
它利用了
丰富的通信功能。VaultTemplate
是值得寻找的地方
访问功能,例如从 Vault 读取数据或颁发
管理命令。VaultTemplate
还提供回调方法,方便您
获取低级 API 工件,例如RestTemplate
进行沟通
直接与 Vault 一起使用。
7.1. 依赖项
如果你想在项目中使用 Spring Vault,请声明对spring-vault-core
人工制品。
<dependencies>
<dependency>
<groupId>org.springframework.vault</groupId>
<artifactId>spring-vault-core</artifactId>
</dependency>
</dependencies>
查找 Spring Vault 依赖项的兼容版本的最简单方法是检查spring-vault-parent
.
我们通常建议升级到 Jackson、HTTP 客户端和云提供商 SDK 的最新依赖项。
8. 开始使用
Spring Vault 支持需要 Vault 0.6 或更高版本以及 Java SE 6 或更高版本。 引导设置工作环境的一种简单方法是创建一个 STS 中基于 Spring 的项目。
首先,您需要设置一个正在运行的 Vault 服务器。 有关如何启动 Vault 实例的说明,请参阅 Vault。
要在 STS 中创建 Spring 项目,请转到 File → New →
Spring 模板项目 → 简单的 Spring Utility Project →
出现提示时按 Yes。然后输入项目和包名称,例如org.spring.vault.example
.
然后将以下内容添加到pom.xml
dependencies 部分。
<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/>
元素。
<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/>
元素。
<repositories>
<repository>
<id>spring-snapshot</id>
<name>Spring Maven SNAPSHOT Repository</name>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
存储库也可以在此处浏览。
创建一个简单的Secrets
类来保留:
package org.spring.vault.example;
public class Secrets {
String username;
String password;
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
以及要运行的主应用程序
package org.springframework.vault.example;
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 Vault 的中心类,
VaultTemplate
,使用org.springframework.vault.client.VaultEndpoint
object 和ClientAuthentication
. 你不需要启动 Spring Context 来使用 Spring Vault。 -
Vault 应使用根令牌
00000000-0000-0000-0000-000000000000
以运行此应用程序。 -
映射器适用于标准 POJO 对象,不需要任何 其他元数据(尽管您可以选择提供该信息)。
-
映射约定可以使用字段访问。请注意
Secrets
class 只有 getter。 -
如果构造函数参数名称与存储文档的字段名称匹配,则 它们将用于实例化对象。
9. VaultTemplate 简介
类VaultTemplate
,位于包装中org.springframework.vault.core
,
是 Spring 的 Vault 支持的中心类,它提供了丰富的功能集
与 Vault 交互。该模板提供了方便的读取、写入和
删除 Vault 中的数据,并提供域对象与 Vault 数据之间的映射。
配置完成后,VaultTemplate 是线程安全的,并且可以在
多个实例。 |
Vault 文档和域类之间的映射是通过委托给RestTemplate
.Spring Web 支持提供了映射基础结构。
这VaultTemplate
类实现接口VaultOperations
.
尽可能地使用VaultOperations
以方法
在 Vault API 上提供,以使现有 Vault 开发人员熟悉 API
他们习惯了 API 和 CLI。例如,您将找到诸如
“write”、“delete”、“read” 和 “revoke”。
设计目标是尽可能轻松地在
使用 Vault API 和VaultOperations
.两者之间的主要区别
这两个 API 是VaultOperations
可以传递域对象而不是
JSON 键值对。
引用VaultTemplate 实例
通过其接口VaultOperations . |
虽然 上有许多方便的方法VaultTemplate
轻松帮助您
如果您需要直接访问 Vault API 以访问
未由VaultTemplate
您可以使用以下
多个 execute 回调方法以访问底层 API。执行回调
将为您提供对RestOperations
对象。
有关更多信息,请参阅 执行回调 部分。
现在让我们看看如何在 Spring 容器的上下文中使用 Vault 的示例。
9.1. 注册和配置 Spring Vault bean
使用 Spring Vault 不需要 Spring Context。但是,VaultTemplate
和SessionManager
在 Managed Context 中注册将参与
在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处理活动的 Vault 会话非常有用
应用程序关闭。您还可以从重复使用中受益VaultTemplate
实例。
Spring Vault 附带了一个支持 bean 定义的配置类
在 Spring 上下文中使用。应用程序配置
类通常从AbstractVaultConfiguration
并且需要
提供特定于环境的其他详细信息。
扩展自AbstractVaultConfiguration
需要实现
' VaultEndpoint vaultEndpoint()' 和ClientAuthentication clientAuthentication()
方法。
@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 以快速入门。
有关支持的身份验证方法的详细信息,请参阅身份验证方法。 |
@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 带有两个实现:
-
SimpleSessionManager
:仅从提供的ClientAuthentication
无刷新和吊销 -
LifecycleAwareSessionManager
:这SessionManager
schedules 令牌 如果令牌可续订,则续订,并在处置时撤销登录令牌。 续订计划使用AsyncTaskExecutor
.LifecycleAwareSessionManager
如果使用AbstractVaultConfiguration
.
9.3. 使用EnvironmentVaultConfiguration
Spring Vault 包括EnvironmentVaultConfiguration
从 Spring 的Environment
和一组预定义的
属性键。EnvironmentVaultConfiguration
支持经常应用的配置。通过从最合适的配置类派生来支持其他配置。包括EnvironmentVaultConfiguration
跟@Import(EnvironmentVaultConfiguration.class)
到现有
基于 Java 的配置类,并通过 Spring 的任何PropertySource
s.
@PropertySource("vault.properties")
@Import(EnvironmentVaultConfiguration.class)
public class MyConfiguration{
}
vault.uri=https://localhost:8200
vault.token=00000000-0000-0000-0000-000000000000
属性键
-
Vault URI:
vault.uri
-
SSL 配置
-
密钥库资源:
vault.ssl.key-store
(可选) -
密钥库密码:
vault.ssl.key-store-password
(可选) -
密钥库类型:
vault.ssl.key-store-type
(可选,通常jks
,还支持pem
) -
信任库资源:
vault.ssl.trust-store
(可选) -
信任库密码:
vault.ssl.trust-store-password
(可选) -
信任库类型:
vault.ssl.trust-store-type
(可选,通常jks
,还支持pem
) -
已启用的 SSL/TLS 协议:
vault.ssl.enabled-protocols
(从 2.3.2 开始,可选,协议用逗号分隔) -
已启用的 SSL/TLS 密码套件:
vault.ssl.enabled-cipher-suites
(从 2.3.2 开始,可选,密码套件以逗号分隔)
-
-
身份验证方法:
vault.authentication
(默认为TOKEN
,支持的身份验证方法包括:TOKEN
,APPID
,APPROLE
,AWS_EC2
,AWS_IAM
,AZURE
,CERT
,CUBBYHOLE
,KUBERNETES
)
特定于身份验证的属性键
-
Vault 代币:
vault.token
-
AppId 路径:
vault.app-id.app-id-path
(默认为app-id
) -
AppId 中:
vault.app-id.app-id
-
用户 ID (UserId):
vault.app-id.user-id
.MAC_ADDRESS
和IP_ADDRESS
用MacAddressUserId
各自IpAddressUserId
用户 ID 机制。 任何其他值与StaticUserId
.
-
AppRole 路径:
vault.app-role.app-role-path
(默认为approle
) -
RoleId 中:
vault.app-role.role-id
-
SecretId 的 SecretId 中:
vault.app-role.secret-id
(可选)
-
AWS EC2 路径:
vault.aws-ec2.aws-ec2-path
(默认为aws-ec2
) -
角色:
vault.aws-ec2.role
-
RoleId 中:
vault.aws-ec2.role-id
(废弃: 使用vault.aws-ec2.role
相反) -
身份证明文件 URL:
vault.aws-ec2.identity-document
(默认为http://169.254.169.254/latest/dynamic/instance-identity/pkcs7
)
-
角色:
vault.aws-iam.role
-
Azure MSI 路径:
vault.azure-msi.azure-path
(默认为azure
) -
角色:
vault.azure-msi.role
-
元数据服务 URL:
vault.azure-msi.metadata-service
(默认为http://169.254.169.254/metadata/instance?api-version=2017-08-01
) -
Identity TokenService URL:
vault.azure-msi.identity-token-service
(默认为http://169.254.169.254/metadata/identity/oauth2/token?resource=https://vault.hashicorp.com&api-version=2018-02-01
)
无配置选项。
-
初始 Vault Token:
vault.token
-
Kubernetes 路径:
vault.kubernetes.kubernetes-path
(默认为kubernetes
) -
角色:
vault.kubernetes.role
-
服务帐户令牌文件的路径:
vault.kubernetes.service-account-token-file
(默认为/var/run/secrets/kubernetes.io/serviceaccount/token
)
9.4. 执行回调
所有 Spring 模板类的一个共同设计特征是所有功能都路由到模板执行回调方法之一。
这有助于确保异常和可能需要的任何资源管理的执行一致性。
虽然在 JDBC 和 JMS 的情况下,这比在 Vault 中的需求要大得多,但它仍然提供了一个访问和日志记录的单一位置。
因此,使用 execute 回调是访问 Vault API 的首选方式
执行我们尚未作为方法公开的不常见作VaultTemplate
.
以下是 execute 回调方法的列表。
-
<T> T
doWithVault(RestOperationsCallback<T> callback)
执行给定的RestOperationsCallback
,允许使用RestOperations
而无需会话。 -
<T> T
doWithSession 会话(RestOperationsCallback<T> callback)
执行给定的RestOperationsCallback
,允许在经过身份验证的会话中与 Vault 进行交互。
下面是一个使用ClientCallback
要初始化 Vault:
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 Vault 附带了以下扩展:
-
转换(Enterprise 功能)
-
系统后端
您可以通过VaultTemplate
直接 (VaultTemplate.read(…)
,VaultTemplate.write(…)
).
10.1. 键值版本 1(“未版本控制的 secret”)
这kv
secrets 引擎用于将任意 secret 存储在为 Vault 配置的物理存储中。
运行kv
Secrets Engine 中,仅保留最近写入的键值。
非版本控制 kv 的好处是减少了每个键的存储大小,因为没有存储额外的元数据或历史记录。
此外,发送到以这种方式配置的后端的请求性能更高,因为存储调用更少,并且任何给定请求都没有锁定。
Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。VaultKeyValueOperations
遵循 Vault CLI 设计。
这是 Vault 的主要命令行工具,提供如下命令:vault kv get
,vault kv put
等等。
通过指定版本和挂载路径,您可以将此 API 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 1:
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
.
或者,可以通过 API 使用VaultTemplate
由于其直接映射和简单使用,因为 KEY 和 Responses 直接映射到输入和输出键。
以下示例说明了在mykey
.
这kv
Secrets Engine 挂载在secret
:
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 的更多详细信息。
10.2. 键值版本 2(“版本化 secret”)
您可以运行kv
Secrets Engine 中的一个版本。
本节介绍如何使用版本 2。当运行 2 版本的kv
backend 一个 key 可以保留可配置数量的版本。
您可以检索旧版本的元数据和数据。
此外,您还可以使用 check-and-set作来避免无意中覆盖数据。
与键值版本 1(“未版本控制的秘密”)类似,Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。
Spring Vault 附带了一个专用的键值 API 来封装各个键值 API 实现之间的差异。VaultKeyValueOperations
遵循 Vault CLI 设计。
这是 Vault 的主要命令行工具,提供如下命令vault kv get
,vault kv put
等。
通过指定版本和挂载路径,您可以将此 API 与两个 Key-Value 引擎版本一起使用。 以下示例使用 Key-Value 版本 2:
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
.
您还可以与版本控制的键值 API 的具体内容进行交互。如果要获取特定密钥或需要访问元数据,这将非常有用。
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 | 将机密存储在elvis 在secret/ 安装。 |
2 | 将数据存储在版本控制后端会返回版本号等元数据。 |
3 | 版本控制的键值 API 允许检索由版本号标识的特定版本。 |
4 | 版本控制的键值密钥可以映射到值对象中。 |
5 | 使用 CAS 更新版本控制密钥时,输入必须引用之前获取的版本。 |
使用kv
v2 Secrets Engine 通过VaultTemplate
是可能的。
这不是最方便的方法,因为 API 为上下文路径以及 input/output 的表示方式提供了一种不同的方法。
具体来说,与实际 secret 的交互需要包装和解包数据部分,并引入data/
mount 和 secrets 键之间的 path 段。
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 的更多详细信息。
10.3. PKI(公钥基础设施)
这pki
Secrets Engine 通过实施证书颁发机构作来表示证书的后端。
PKI 密钥引擎生成动态 X.509 证书。 借助此密钥引擎,服务可以获取证书,而无需经历通常的手动过程,例如生成私钥和 CSR、提交到 CA 并等待验证和签名过程完成。 Vault 的内置身份验证和授权机制提供了验证功能。
Spring Vault 支持通过以下方式颁发、签名、撤销证书和 CRL 检索VaultPkiOperations
.
所有其他 PKI 功能都可以通过以下方式使用VaultOperations
.
以下示例简要说明了如何颁发和吊销证书的用法:
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 的更多详细信息。
10.4. 令牌认证后端
此后端是不与实际密钥交互的身份验证后端。 相反,它提供对访问令牌管理的访问权限。 您可以在 Authentication methods 一章中阅读有关基于 Token 的身份验证的更多信息。
这token
身份验证方法是内置的,并自动在/auth/token
.
它允许用户使用令牌进行身份验证,以及创建新令牌、按令牌撤销密钥等。
当任何其他身份验证方法返回身份时,Vault 核心会调用 token 方法为该身份创建新的唯一令牌。
您还可以使用令牌存储来绕过任何其他身份验证方法。您可以直接创建 Token,也可以对 Token 执行各种其他作,例如续订和撤销。
Spring Vault 使用此后端来更新和撤销由配置的身份验证方法提供的会话令牌。
以下示例展示了如何从应用程序中请求、续订和撤销 Vault 令牌:
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 的更多详细信息。
10.5. Transit 后端
传输密钥引擎处理传输中数据的加密功能。 Vault 不存储发送到此 Secrets 引擎的数据。 它也可以看作是 “cryptography as a service” 或 “encryption as a service”。 传输密钥引擎还可以对数据进行签名和验证,生成数据的哈希和 HMAC,并充当随机字节源。
传输的主要用例是加密来自应用程序的数据,同时仍将加密数据存储在某些主数据存储中。 这减轻了应用程序开发人员进行适当加密和解密的负担,并将负担推给了 Vault 的运营商。
Spring Vault 支持广泛的 Transit作:
-
密钥创建
-
密钥重新配置
-
加密/解密/重新包装
-
HMAC 计算
-
签名和签名验证
所有作transit
以键为中心。
Transit 引擎支持密钥和各种密钥类型的版本控制。
请注意,密钥类型可能会对可以使用的作施加限制。
以下示例说明如何创建密钥以及如何加密和解密数据:
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 令牌的值对象。
这encrypt method 返回 Base64 编码的密文,通常以vault: . |
3 | 要将密文解密为纯文本,请调用decrypt 方法。
它解密密文并返回一个String 使用默认 charset 进行解码。 |
前面的示例使用简单字符串进行加密作。 虽然这是一种简单的方法,但它存在 charset 错误配置的风险,并且不是二进制安全的。 当纯文本对数据(如图像、压缩数据或二进制数据结构)使用二进制表示时,需要二进制安全性。
要加密和解密二进制数据,请使用Plaintext
和Ciphertext
value 对象:
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 对象。
作为回报,encrypt method 返回一个Ciphertext 对象。 |
2 | 这Ciphertext Object 可以直接用于解密,并返回一个Plaintext 对象。 |
Plaintext
和Ciphertext
带有一个上下文对象,VaultTransitContext
.
它用于为收敛加密提供 nonce 值,以及用于利用密钥派生的上下文值。
Transit 允许对纯文本进行签名并验证给定纯文本的签名。 签名作需要非对称密钥,通常使用椭圆曲线加密或 RSA。
签名使用公钥/私钥拆分来确保真实性。 签名者使用其私有密钥创建签名。否则,任何人都可以以您的名义签署消息。 验证者使用公钥部分来验证签名。实际签名通常是一个哈希值。 在内部,使用私钥计算和加密哈希以创建最终签名。验证会解密签名消息,计算他们自己的纯文本哈希值,并比较两个哈希值以检查签名是否有效。 |
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 的更多详细信息。
11. ReactiveVaultTemplate 简介
本节涵盖了有关使用 Spring Vault 的反应式编程支持的基本信息。
11.1. 什么是反应式编程?
简单来说,反应式编程是关于非阻塞应用程序 异步和事件驱动,并且需要少量线程来垂直扩展 (即在 JVM 中)而不是水平(即通过集群)。
响应式应用程序的一个关键方面是背压的概念,这是一种机制 确保生产者不会压倒消费者。例如,在 reactive 的管道中 组件从数据库扩展到 HTTP 响应(当 HTTP 连接为 太慢,数据存储库也可能减慢或完全停止,直到网络容量释放。
11.2. 反应式 Vault 客户端
Spring Vault 的反应式客户端支持建立在可组合的身份验证步骤和 Spring 的功能WebClient
通过 Reactor Netty 或 Jetty,它们都具有完全无阻塞、事件驱动的 HTTP 客户端。
它暴露了VaultTokenSupplier
作为VaultToken
对 HTTP 请求进行身份验证
和ReactiveVaultOperations
作为主要入口点。的核心配置VaultEndpoint
,ClientOptions
和 SSL 在
各种客户端实现。
类ReactiveVaultTemplate
,位于包装中org.springframework.vault.core
,
是 Spring 的反应式 Vault 支持的中心类,提供了丰富的功能集,以
与 Vault 交互。该模板提供了方便的读取、写入和
删除 Vault 中的数据,并提供域对象与 Vault 数据之间的映射。
配置完成后,ReactiveVaultTemplate 是线程安全的,并且可以在
多个实例。 |
Vault 文档和域类之间的映射是通过委托给WebClient
及其编解码器。
这ReactiveVaultTemplate
类实现接口ReactiveVaultOperations
.
尽可能地使用ReactiveVaultOperations
以方法
在 Vault API 上提供,以使现有 Vault 开发人员熟悉 API
他们习惯了 API 和 CLI。例如,您将找到诸如
“write”、“delete” 和 “read” 来获取。
设计目标是尽可能轻松地在
使用 Vault API 和ReactiveVaultOperations
.两者之间的主要区别
这两个 API 是ReactiveVaultOperations
可以传递域对象而不是
JSON 键值对。
引用ReactiveVaultTemplate 实例
通过其接口ReactiveVaultOperations . |
未由ReactiveVaultTemplate
您可以使用以下
多个 execute 回调方法以访问底层 API。执行回调
将为您提供对WebClient
对象。
有关更多信息,请参阅 执行回调 部分。
现在让我们看看如何在 Spring 容器的上下文中使用 Vault 的示例。
11.3. 注册和配置 Spring Vault bean
使用 Spring Vault 不需要 Spring Context。但是,ReactiveVaultTemplate
和VaultTokenSupplier
在 Managed Context 中注册将参与
在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处理活动的 Vault 会话非常有用
应用程序关闭。您还可以从重复使用中受益ReactiveVaultTemplate
实例。
Spring Vault 附带了一个支持 bean 定义的配置类
在 Spring 上下文中使用。应用程序配置
类通常从AbstractVaultConfiguration
并且需要
提供特定于环境的其他详细信息。
扩展自AbstractVaultConfiguration
需要实现
' VaultEndpoint vaultEndpoint()' 和ClientAuthentication clientAuthentication()
方法。
@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.5. 执行回调
所有 Spring 模板类的一个共同设计特性是所有功能
路由到其中一个模板执行回调方法。这有助于确保
执行异常和可能需要的任何资源管理
一致性。虽然在 JDBC 和 JMS 的情况下,这更需要
与 Vault 相比,它仍然提供一个用于访问和日志记录的位置。
因此,使用 execute 回调是访问 Vault API 的首选方式
执行我们尚未作为方法公开的不常见作ReactiveVaultTemplate
.
以下是 execute 回调方法的列表。
-
<T> T
doWithVault(Function<WebClient, ? extends T> clientCallback)
编写一个 reactive 对给定的WebClient
,允许在没有会话上下文的情况下与 Vault 进行交互。 -
<T> T
doWithSession 会话(Function<WebClient, ? extends T> clientCallback)
编写一个 reactive 对给定的WebClient
,允许在经过身份验证的会话中与 Vault 进行交互。
下面是一个使用回调初始化 Vault 的示例:
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 抽象获取配置属性。
您可以在其他特性源中引用存储在 Vault 中的特性,或者使用@Value(…) .在引导需要数据存储在 Vault 内的 bean 时,需要特别注意。一个VaultPropertySource 必须在此时初始化才能从 Vault 中检索属性。 |
Spring Boot/Spring Cloud 用户可以从 Spring Cloud Vault 的 配置集成,用于在应用程序启动期间初始化各种属性源。 |
12.1. 注册VaultPropertySource
Spring Vault 提供了一个VaultPropertySource
与 Vault 一起使用以获取
性能。它使用嵌套的data
元素来公开存储的属性,并
在 Vault 中加密。
ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new VaultPropertySource(vaultTemplate, "secret/my-application"));
在上面的代码中,VaultPropertySource
已添加为最高优先级
在搜索中。如果它包含 'foo' 属性,则将被检测并返回
领先于任何foo
property 在任何其他PropertySource
.MutablePropertySources
公开了许多允许精确
作属性源集。
12.2. @VaultPropertySource
这@VaultPropertySource
注解提供了一个方便且声明性的
添加PropertySource
到 Spring 的Environment
与@Configuration
类。
@VaultPropertySource
采用 Vault 路径,例如secret/my-application
并将存储在节点中的数据公开在PropertySource
.@VaultPropertySource
支持与租约关联的密钥的租约
(即来自mysql
backend) 和终端上的凭证轮换
租约到期。默认情况下,租约续订处于禁用状态。
{
// …
"data": {
"database": {
"password": ...
},
"user.name": ...,
}
// …
}
@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;
}
}
@VaultPropertySource
使用凭证轮换和前缀@Configuration
@VaultPropertySource(value = "aws/creds/s3-access",
propertyNamePrefix = "aws.",
renewal = Renewal.ROTATE)
public class AppConfig {
// provides aws.access_key and aws.secret_key properties
}
从generic secret 后端与 TTL (refresh_interval ),而不是租约 ID 的PropertySource 在达到其 TTL 时轮换通用密钥。 |
您可以使用@VaultPropertySource 从受版本控制的 Key-Value 后端获取最新的密钥版本。确保不包含data/ 段。 |
任何${…}
placeholder 存在于@VaultPropertySource
path 根据已针对环境注册的属性源集进行解析,如下例所示:
@VaultPropertySource
使用占位符的路径@Configuration
@VaultPropertySource(value = "aws/creds/${my.placeholder:fallback/value}",
propertyNamePrefix = "aws.",
renewal = Renewal.ROTATE)
public class AppConfig {
}
假设my.placeholder
存在于已注册的属性源之一(例如,系统属性或环境变量)中,则占位符将解析为相应的值。
如果不是,则fallback/value
用作默认值。
如果未指定 default 且无法解析属性,则IllegalArgumentException
被抛出。
在某些情况下,严格控制可能是不可能的或不切实际的
使用@VaultPropertySource
附注。
例如,如果@Configuration
以上类是通过
component-scanning 中,顺序很难预测。
在这种情况下 - 如果覆盖很重要 - 建议将
用户回退到使用编程式 PropertySource API。
看ConfigurableEnvironment
和MutablePropertySources
了解详情。
13. Vault 存储库
使用VaultTemplate
映射到 Java 类的响应允许执行基本数据作,如读取、写入和删除。
Vault 存储库在 Vault 之上应用 Spring Data 的存储库概念。
Vault 存储库公开了基本的 CRUD 功能,并支持使用限制标识符属性、分页和排序的谓词进行查询派生。
文件库存储库使用键/值密钥引擎功能来保存和查询数据。
从版本 2.4 开始, Spring Vault 可以使用额外的键/值版本 2 秘密引擎,实际的秘密引擎版本是在运行时发现的。
版本控制的键/值 Secret 引擎中的 Deletes 使用DELETE 操作。机密不会通过以下方式销毁CrudRepository.delete(…) . |
在 Spring Data Commons 参考文档中阅读有关 Spring Data Repositories 的更多信息。 参考文档将为您提供 Spring Data 存储库的介绍。 |
13.1. 用法
要访问存储在 Vault 中的域实体,您可以利用存储库支持来大大简化这些实体的实施。
@Secret
class Credentials {
@Id String id;
String password;
String socialSecurityNumber;
Address address;
}
我们这里有一个非常简单的 domain 对象。
请注意,它有一个名为id
注解org.springframework.data.annotation.Id
以及@Secret
注解。
这两个负责创建用于将对象作为 JSON 保存在 Vault 中的实际密钥。
注释 的属性@Id 以及那些被命名为id 被视为标识符属性。
带有注释的 Comments 比其他 Comments 更受欢迎。 |
下一步是声明使用 domain 对象的存储库接口。
Credentials
实体interface CredentialsRepository extends CrudRepository<Credentials, String> {
}
随着我们的存储库扩展CrudRepository
它提供了基本的 CRUD 和查询方法。
Vault 存储库需要 Spring Data 组件。
确保包括spring-data-commons
和spring-data-keyvalue
artifacts 的 artifacts 中。
实现此目的的最简单方法是设置依赖项管理并将工件添加到pom.xml
:
然后将以下内容添加到pom.xml
dependencies 部分。
<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 配置。
@Configuration
@EnableVaultRepositories
class ApplicationConfig {
@Bean
VaultTemplate vaultTemplate() {
return new VaultTemplate(…);
}
}
根据上面的设置,我们可以继续注入CredentialsRepository
融入我们的组件中。
@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 | 计算由@Secret 上Credentials . |
4 | 从 Vault 中删除给定对象的密钥。 |
13.2. 对象到 Vault 的 JSON 映射
Vault 存储库使用 JSON 作为交换格式将对象存储在 Vault 中。
JSON 和实体之间的对象映射由VaultConverter
.
转换器读取和写入SecretDocument
,其中包含来自VaultResponse
.VaultResponse
从 Vault 中读取,并且 Jackson 将正文反序列化为Map
之String
和Object
.
默认的VaultConverter
implementation 会读取Map
with 嵌套值,List
和Map
对象并将其转换为实体,反之亦然。
鉴于Credentials
type 的 default 映射如下:
{
"_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 attribute 包含在根级别以及任何嵌套接口或抽象类型中。 |
2 | 简单属性值按 path 进行映射。 |
3 | 复杂类型的属性映射为嵌套对象。 |
这@Id property 必须映射到String . |
类型 | 样本 | 映射值 |
---|---|---|
简单类型 |
字符串 firstname = “Walter”; |
“firstname”: “沃尔特” |
复杂型 |
地址 adress = 新地址(“308 Negra Arroyo Lane”); |
“address”: { “street”: “308 Negra Arroyo Lane” } |
简单类型列表 |
List<String> 昵称 = asList(“walt”, “heisenberg”); |
“昵称”: [“Walt”, “Heisenberg”] |
简单类型的映射 |
Map<String, 整数> atts = asMap(“age”, 51) |
“atts” : {“age” : 51} |
复杂类型列表 |
List<Address> addresses = asList(new Address(“308... |
“address”: [{ “street”: “308 Negra Arroyo Lane” }, ...] |
您可以通过注册Converter
在VaultCustomConversions
.
这些转换器可以负责从/转换为类型,例如LocalDate
以及SecretDocument
而第一个适合将简单属性转换为其 JSON 表示形式,最后一个复杂类型。
第二个选项提供对生成的SecretDocument
.
将对象写入Vault
将删除内容并重新创建整个条目,因此未映射的数据将丢失。
13.3. 查询和查询方法
Query methods 允许从方法名称自动派生简单查询。 Vault 没有查询引擎,但需要直接访问 HTTP 上下文路径。 Vault 查询方法将 Vault 的 API 可能性转换为查询。 查询方法执行在上下文路径下列出子项,对 Id 应用筛选,(可选)使用 offset/limit 限制 Id 流,并在获取结果后应用排序。
interface CredentialsRepository extends CrudRepository<Credentials, String> {
List<Credentials> findByIdStartsWith(String prefix);
}
Vault 存储库的查询方法仅支持在@Id 财产。 |
以下是 Vault 支持的关键字概述。
关键词 | 样本 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13.3.1. 排序和分页
查询方法支持排序和分页,方法是在内存中选择从 Vault 上下文路径中检索到的子列表(偏移量/限制)Id。 与查询方法谓词不同,排序 has 不限于特定字段。 在 Id 筛选后应用未分页排序,并从 Vault 获取所有生成的密钥。 这样,查询方法仅获取也作为结果的一部分返回的结果。
使用分页和排序需要在过滤 Id 之前获取密钥,这会影响性能。 排序和分页保证即使 Vault 返回的 Id 的自然顺序发生变化,也会返回相同的结果。 因此,首先从 Vault 获取所有 ID,然后应用排序,然后进行过滤和偏移/限制。
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,并且不会更新密钥。
版本属性必须是数值属性,例如int
或long
并映射到cas
属性。
@Secret
class VersionedCredentials {
@Id String id;
@Version int version;
String password;
String socialSecurityNumber;
Address address;
}
以下示例显示了这些功能:
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
.
RevisionRepository
interface RevisionCredentialsRepository extends CrudRepository<Credentials, String>,
RevisionRepository<Credentials, String, Integer> (1)
{
}
1 | 第一个类型参数 (Credentials ) 表示实体类型,第二个 (String ) 表示 id 属性的类型,最后一个 (Integer ) 是修订版号的类型。Vault 仅支持String identifiers 和Integer 修订号。 |
13.5.1. 用法
您现在可以使用RevisionRepository
查询实体的修订版,如下例所示:
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 Vault 支持以下 HTTP 命令式客户端:
-
Java 的内置
HttpURLConnection
(如果没有其他可用的客户端,则默认客户端) -
Apache Http 组件
-
OkHttp 3
Spring Vault 的反应式集成支持以下反应式 HTTP 客户端:
-
Java 的内置响应式
HttpClient
(如果没有其他可用的客户端,则默认客户端) -
Reactor Netty
-
Apache Http 组件
-
Jetty
使用特定客户端需要在 Classpath 上提供相应的依赖项 因此 Spring Vault 可以使用可用的 Client 端与 Vault 进行通信。
14.1. Java 的内置HttpURLConnection
Java 的内置HttpURLConnection
开箱即用,无需额外
配置。用HttpURLConnection
带有有关 SSL 配置的限制。
Spring Vault 不会像以前那样应用自定义的 SSL 配置
需要对 JVM 进行深度重新配置。此配置将影响所有
组件。配置 SSL 设置HttpURLConnection
要求您将这些设置作为 System Properties (系统属性) 提供。有关更多详细信息,请参阅自定义 JSSE。
14.2. 外部客户端
您可以使用外部客户端访问 Vault 的 API。只需添加以下选项之一 dependencies 添加到您的项目中。如果使用 Spring Vault 的依赖项 BOM,则可以省略版本号
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
Apache HttpClient 的线路日志记录可以通过日志记录配置来启用。确保不要意外启用线路日志记录,因为日志可能会以纯文本形式公开应用程序和 Vault 之间的流量(令牌和密钥)。 |
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5-reactive</artifactId>
</dependency>
<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 设置。
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 上时,才能应用。
SSL 配置还支持 PEM 编码的证书,作为 Java 密钥存储的替代方案。
KeyStoreConfiguration keystore = KeyStoreConfiguration
.of(new ClassPathResource("ca.pem")).withStoreType("PEM");
SslConfiguration configuration = SslConfiguration.forTrustStore(keystore);
PEM 文件可能包含一个或多个证书(-----BEGIN CERTIFICATE-----
和-----END CERTIFICATE-----
).
添加到底层的证书KeyStore
使用完整的使用者名称作为别名。
15. 身份验证方法
不同的组织对安全性有不同的要求 和身份验证。Vault 通过提供多重身份验证来反映这一需求 方法。Spring Vault 支持多种身份验证机制。
15.1. 外部化登录凭证
首次访问安全系统称为安全引入。 任何客户端都需要临时或永久凭证才能访问 Vault。外部化凭证 是保持代码可维护性的良好模式,但存在增加泄露的风险。
向任何一方泄露登录凭证允许登录 Vault 并访问以下 Secret 由基础角色允许。选择适当的客户端身份验证,然后 将凭证注入应用程序需要接受风险评估。
Spring 的 PropertySource 抽象是天作之合 将配置保留在应用程序代码之外。您可以使用系统属性、环境 变量或属性文件来存储登录凭据。每种方法都有自己的属性。 请记住,命令行和环境属性可以通过适当的 OS 访问级别。
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 并获取Environment 从ApplicationContext . |
看SecurePropertyUsage.java
有关在组件和其他属性源中引用属性的示例。
15.2. 令牌身份验证
令牌是 Vault 中身份验证的核心方法。 Token 身份验证需要提供静态 Token。
Token authentication 是默认的身份验证方法。 如果令牌被披露为非预期方,则它将获得对 Vault 的访问权限,并且 可以访问预期客户端的密钥。 |
通常,令牌身份验证用于创建和更新令牌的方案
外部(例如 HashiCorp Vault 服务代理)。
根据实际设置,您可能希望也可能不希望令牌续订和撤销。
看LifecycleAwareSessionManager
了解有关 TTL 和 Token 吊销的详细信息。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication("…");
}
// …
}
另请参阅:
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 哈希。
基于 IP 地址的 UserId 使用本地主机的 IP 地址。
@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 的相应命令是:
$ echo -n 192.168.99.1 | sha256sum
包括echo 导致不同的哈希值
因此,请确保包含-n 旗。 |
基于 Mac 地址的 UserId 从
localhost 绑定的设备。该配置还允许指定
一个network-interface
提示选择正确的设备。的值network-interface
是可选的,可以是接口
名称或接口索引(从 0 开始)。
@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 的相应命令是:
$ 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。
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 Vault 通过仅提供 RoleId 来支持 AppRole 身份验证 或者与提供的 SecretId 一起从 Vault 获取 RoleId/SecretId (带有响应展开的推拉模式)。
@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 和使用限制相关联。
@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 实例。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
return new AwsEc2Authentication(restOperations());
}
// …
}
AWS-EC2 身份验证默认启用 nonce 跟随 首次使用时信任 (TOFU) 原则。任何意外的一方 获得对 PKCS#7 身份元数据的访问权限可以进行身份验证 对抗 Vault。
在第一次登录期间, Spring Vault 会生成一个 nonce ,该实例 ID 存储在 auth 后端中。 重新身份验证需要发送相同的 nonce。任何其他 参与方没有 nonce,并且可以在 Vault 中引发警报 进一步调查。
nonce 保存在内存中,并在应用程序重启期间丢失。
AWS-EC2 身份验证角色是可选的,默认为 AMI。
您可以通过设置
它在AwsEc2AuthenticationOptions
.
15.6. AWS-IAM 身份验证
aws auth 后端允许使用现有 AWS IAM 凭证登录 Vault。
AWS IAM 身份验证会创建一个签名的 HTTP 请求,该请求是
由 Vault 执行,以使用 AWS STS 获取签名者的身份GetCallerIdentity
方法。AWSv4 签名需要 IAM 凭证。
IAM 凭证可以从运行时环境中获取 或外部供应。运行时环境,例如 AWS-EC2、 具有分配的 IAM 委托人的 Lambda 和 ECS 不需要特定于客户端的 配置凭证,但可以从其元数据源获取这些凭证。
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder()
.credentials(new BasicAWSCredentials(…)).build();
return new AwsIamAuthentication(options, restOperations());
}
// …
}
@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 开发工具包类型进行凭证和请求签名。
您可以通过以下方式配置身份验证AwsIamAuthenticationOptions
.
另请参阅:
15.7. Azure (MSI) 身份验证
azure auth 后端提供了一种安全的引入机制 对于 Azure VM 实例,允许自动检索 Vault 令 牌。与大多数 Vault 身份验证后端不同,此后端 不需要首先部署或预置安全敏感型 凭据(令牌、用户名/密码、客户端证书等)。 相反,它将 Azure 视为受信任的第三方,并使用 托管服务身份和实例元数据信息,可以是 绑定到 VM 实例。
@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 的实例元数据服务以
获取这些详细信息。
另请参阅:
15.8. GCP-GCE 身份验证
gcp auth 后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭证登录 Vault。
GCP GCE (Google Compute Engine) 身份验证以 服务账户的 JSON Web 令牌 (JWT)。Compute Engine 实例的 JWT 使用实例标识从 GCE 元数据服务获取。 此 API 创建可用于确认实例身份的 JSON Web 令牌。
与大多数 Vault 身份验证后端不同,此后端 不需要首先部署或预置安全敏感型 凭据(令牌、用户名/密码、客户端证书等)。 相反,它将 GCP 视为受信任的第三方,并使用 加密签名的动态元数据信息,该信息具有唯一性 表示每个 GCP 服务帐户。
您可以通过以下方式配置身份验证GcpComputeAuthenticationOptions
.
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
GcpComputeAuthenticationOptions options = GcpComputeAuthenticationOptions.builder()
.role(…).build();
GcpComputeAuthentication authentication = new GcpComputeAuthentication(options,
restOperations());
}
// …
}
另请参阅:
15.9. GCP-IAM 身份验证
gcp auth 后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭证登录 Vault。
GCP IAM 身份验证以 JSON Web 令牌 (JWT) 的形式创建签名
对于服务帐户。服务帐户的 JWT 由
调用 GCP IAM 的projects.serviceAccounts.signJwt
应用程序接口。调用方根据 GCP IAM 进行身份验证
并由此证明了它的身份。此保险柜后端将 GCP 视为受信任的第三方。
IAM 凭证可以从运行时环境中获取
或作为 e.g. JSON 从外部供应。JSON 是首选形式,因为它
携带调用projects.serviceAccounts.signJwt
.
@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 签名。
您可以通过以下方式配置身份验证GcpIamCredentialsAuthenticationOptions
.
Google 凭据需要 OAuth 2 令牌来维护令牌生命周期。所有 API
是同步的,因此,GcpIamCredentialsAuthentication 不支持AuthenticationSteps 哪个是
对于反应式使用是必需的。 |
GcpIamCredentialsAuthentication 使用 IAM 凭证 API,并使用已弃用的GcpIamAuthentication 使用已弃用的 IAM API。 |
另请参阅:
15.10. PCF 身份验证
pcf auth 后端允许 PCF 实例的 Vault 登录。 它利用 PCF 的应用程序和容器身份保证。
PCF 身份验证使用实例密钥和证书创建由 Vault 验证的签名。 如果签名匹配,并且可能绑定的 organization/space/application ID 匹配,则 Vault 会颁发适当范围的令牌。
实例凭证可从以下文件中获取CF_INSTANCE_CERT
和CF_INSTANCE_KEY
变量。
@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 签名。
您可以通过以下方式配置身份验证PcfAuthenticationOptions
.
另请参阅:
15.11. TLS 证书身份验证
这cert
auth backend 允许使用 SSL/TLS 客户端进行身份验证
由 CA 签名或自签名的证书。
要启用cert
身份验证您需要:
-
使用 SSL,请参见 Vault 客户端 SSL 配置
-
配置 Java
Keystore
,其中包含客户端 certificate 和私有密钥
@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
部分。
创建包装令牌
用于创建令牌的响应包装需要 Vault 0.6.0 或更高版本。 |
$ 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
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions
.builder()
.initialToken(VaultToken.of("…"))
.wrapped()
.build();
return new CubbyholeAuthentication(options, restOperations());
}
// …
}
使用存储的令牌
$ 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
@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/可续订性
从与非零 TTL 关联的 Cubbyhole 中检索的令牌从 令牌创建时间。该时间不一定与申请相同 启动。为了补偿初始延迟,Cubbyhole 身份验证会执行 self lookup 查找与非零 TTL 关联的令牌以检索剩余的 TTL。 Cubbyhole 身份验证不会在没有 TTL 的情况下自查找包装的令牌,因为 零 TTL 表示没有关联的 TTL。
未包装的令牌不会仅提供有关可续订性和 TTL 的详细信息 检索令牌。自查找将查找可续订性和剩余的 TTL。
另请参阅:
15.13. Kubernetes 身份验证
Vault 从 0.8.3 开始支持使用 Kubernetes 令牌进行基于 kubernetes 的身份验证。
使用 Kubernetes 身份验证需要 Kubernetes 服务帐户令牌,
通常安装在/var/run/secrets/kubernetes.io/serviceaccount/token
.
该文件包含读取并发送到 Vault 的令牌。
Vault 在登录期间使用 Kubernetes 的 API 验证其有效性。
配置 Kubernetes 身份验证至少需要提供角色名称:
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions.builder()
.role(…).jwtSupplier(…).build();
return new KubernetesAuthentication(options, restOperations());
}
// …
}
您可以通过以下方式配置身份验证KubernetesAuthenticationOptions
.
另请参阅:
15.14. 用户名/密码身份验证
用户名/密码通常是最终用户身份验证方案。 多个 Vault 身份验证后端支持使用 username 和 password:
-
用户名和密码 (
userpass
) -
LDAP (
ldap
) -
Okta (
okta
,支持额外的基于时间的一次性令牌) -
半径 (
radius
)
UserPasswordAuthenticationOptions
可以与上述所有身份验证后端一起使用,因为 Login API 在所有机制中都是相似的。
请确保在配置时使用适当的 auth 挂载路径UserPasswordAuthenticationOptions
.
UserPasswordAuthentication
@Configuration
class AppConfig extends AbstractVaultConfiguration {
// …
@Override
public ClientAuthentication clientAuthentication() {
UserPasswordAuthenticationOptions options = UserPasswordAuthenticationOptions.builder()
.username(…).password(…).build();
return new UserPasswordAuthentication(options, restOperations());
}
// …
}
另请参阅:
15.15. 身份验证步骤
ClientAuthentication
对象描述身份验证流程并执行实际的
身份验证步骤。预先组合的身份验证易于使用和配置
与同步执行的紧密绑定。
身份验证方法的组合和重用常见步骤,例如发布登录
payload 添加到 Vault 或从 HTTP 源检索身份验证输入
跟ClientAuthentication
对象。
身份验证步骤提供常见身份验证活动的可重用性。
步骤创建方式AuthenticationSteps
在函数式
样式将实际的身份验证执行留给特定的执行程序。
AuthenticationSteps.just(VaultToken.of(…)); (1)
1 | 创建AuthenticationSteps 从VaultToken . |
可以从单个输入创建单步身份验证流程。声明
多个身份验证步骤以Supplier
或HttpRequest
提供
authentication state 对象,该对象可用于 Map 或 post 到 Vault 进行登录。
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 对于不同的执行模型:
-
AuthenticationStepsExecutor
作为 SYNCHRONOUS 的直接替代品ClientAuthentication
. -
AuthenticationStepsOperator
进行响应式执行。
多ClientAuthentication
自带的静态工厂方法来创建AuthenticationSteps
对于其特定于身份验证的选项:
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 Vault 提供了LifecycleAwareSessionManager
一个会话管理器,可以更新令牌,直到它到达其终端 TTL,然后执行另一次登录以获取与会话关联的下一个令牌。
根据身份验证方法,登录可以创建两种类型的令牌:
-
VaultToken
:封装实际令牌的通用令牌。 -
LoginToken
:与 renewability/TTL 关联的令牌。
身份验证方法(如TokenAuthentication
只需创建一个VaultToken
它不包含任何可续订性/TTL 详细信息。LifecycleAwareSessionManager
将对令牌运行自查找,以从 Vault 中检索可续订性和 TTL。VaultToken
如果启用了自查找,则会定期续订。请注意,VaultToken
永远不会被撤销,只有LoginToken
被撤销。
身份验证方法创建LoginToken
直接(所有基于登录的身份验证方法)已经提供了设置 Token 续订所需的所有详细信息。从登录中获取的令牌由LifecycleAwareSessionManager
如果会话管理器已关闭。