当前位置 : 主页 > 编程语言 > java >

Spring Vault的Vault 的概念和语义以及语法、核心功能

来源:互联网 收集:自由互联 发布时间:2023-02-04
Spring Vault项目将Spring的核心概念应用于使用HashiCorp Vault开发解决方案。我们提供了一个“模板”作为存储和查询文档的高级抽象。你会注意到与 Spring 框架中的 REST 支持有相似之处。 本

Spring Vault的Vault 的概念和语义以及语法、核心功能_API

Spring Vault项目将Spring的核心概念应用于使用HashiCorp Vault开发解决方案。我们提供了一个“模板”作为存储和查询文档的高级抽象。你会注意到与 Spring 框架中的 REST 支持有相似之处。

本文档是 Spring Vault 的参考指南。它解释了 Vault 的概念和语义以及语法。

参考文档的这一部分解释了 Spring Vault 提供的核心功能。

库支持引入了库模块功能集。

1. 文档结构

本节提供对 Spring 和 Vault 的基本介绍。 它包含有关后续开发以及如何获得支持的详细信息。

文档的其余部分引用了 Spring Vault 功能并假设 用户熟悉HashiCorp Vault以及Spring概念。

2. 认识春天

Spring Vault使用Spring框架的核心功能,例如IoC容器。虽然了解Spring API并不重要,但了解它们背后的概念才是重要的。至少,对于您选择使用的任何 IoC 容器,都应该熟悉 IoC 背后的理念。

Vault 支持的核心功能可以直接使用,无需调用 Spring 容器的 IoC 服务。这很像可以在没有 Spring 容器的任何其他服务的情况下“独立”使用。要利用 Spring Vault 文档的所有功能,例如会话支持,您需要使用 Spring 配置库的某些部分。​​RestTemplate​​

要了解有关 Spring 的更多信息,您可以参考详细解释 Spring 框架的全面(有时是撤防)文档。有很多关于这个问题的文章,博客条目和书籍 - 请查看Spring框架主页以获取更多信息。

3. 了解保险库

安全性和使用机密是每个使用数据库、用户凭据或 API 密钥的开发人员关注的问题。Vault 通过提供与访问控制、吊销、密钥滚动和审核相结合的安全存储来介入。简而言之:保险柜是一种用于安全访问和存储机密的服务。机密是您想要严格控制访问的任何内容,例如 API 密钥、密码、证书等。

了解Vault的起点是 www.vaultproject.io。以下是有用资源的列表:

  • 该手册介绍了 Vault,并包含入门指南、参考文档和教程的链接。
  • 结合在线教程,在线 shell 提供了一种与 Vault 实例交互的便捷方式。
  • 桥狮金库介绍
  • 桥狮公司保险库文档

Spring Vault 为访问、存储和撤销密钥提供客户端支持。 有了桥牌公司的金库,你有一个中心的地方 管理所有环境中应用程序的外部机密数据。 保险柜可以管理静态和动态机密,例如应用程序数据, 远程应用程序/资源的用户名/密码并提供凭据 用于外部服务,如MySQL,PostgreSQL,Apache Cassandra,Consul,AWS等。

4. 要求

Spring Vault 2.x 二进制文件需要 JDK 8.0 及以上版本,以及 Spring Framework 5.2.12.RELEASE 及更高版本。

在保险库方面,保险柜至少为0.6。

5. 其他帮助资源

学习一个新框架并不总是直截了当的。在本节中,我们尝试提供我们认为易于遵循的指南,以便从Spring Vault模块开始。但是,如果您遇到问题或只是在寻找建议,请随时使用以下链接之一:

5.1. 支持

有几个支持选项可用:

5.1.1. 社区论坛

在 Stackoverflow 上发布有关 Spring Vault 的问题,以共享信息并互相帮助。请注意,只有发布时才需要注册。

5.1.2. 专业支持

专业的,从源头支持,保证响应时间,可从Spring Vault和Spring背后的公司Pivotal Sofware,Inc.获得。

5.2. 后续开发

有关 Spring Vault 源代码存储库、夜间构建和快照工件的信息,请参阅 Spring Vault 主页​。您可以通过 Stackoverflow​ 上的社区与开发人员互动,帮助 Spring Vault 最好地满足 Spring 社区的需求。如果您遇到错误或想提出改进建议,请在Spring Vault问题跟踪器​上创建票证。要及时了解 Spring 生态系统中的最新消息和公告,请订阅 Spring 社区门户​。最后,您可以在Twitter(SpringCentral​)上关注Spring博客或项目团队。

6. 新的和值得注意的

6.1. 春季保险库 2.2 中的新功能

  • 通过 支持键值 v2(版本控制后端)机密。@VaultPropertySource
  • 中的 SpEL 支持 。@Secret
  • 添加对 Jetty 作为反应式 HttpClient 的支持。
  • ​​LifecycleAwareSessionManager​​并发出现在的 s。ReactiveLifecycleAwareSessionManagerAuthenticationEvent
  • PCF 身份验证。
  • 弃用 。请按照HashiCorp Vault的建议使用。AppIdAuthenticationAppRoleAuthentication
  • ​​CubbyholeAuthentication​​和包装现在默认使用端点。AppRoleAuthenticationsys/wrapping/unwrap
  • Kotlin 协程对 的支持。ReactiveVaultOperations

6.2. 春季保险库 2.1 中的新功能

  • GCP Compute、GCP IAM 和 Azure 身份验证。
  • 模板 API 支持版本化和不受版本控制的键/值后端以及保管库包装操作。
  • 在反应式 AppRole 身份验证中支持完全拉取模式。
  • 改进了保管库登录失败的异常层次结构。

6.3. 春季保险库 2.0 中的新功能

  • 用于组合身份验证流的身份验证步骤 DSL。
  • 通过 反应式保管库客户端。ReactiveVaultOperations
  • 基于Spring Data KeyValue的Vault存储库支持。
  • 传输批量加密和解密支持。
  • 存储为 JSON 的策略的策略管理。
  • 支持CSR签名、证书吊销和CRL检索。
  • Kubernetes 身份验证。
  • 用于 AppRole 身份验证的 RoleId/SecretId 解包。
  • Spring 安全与基于传输后端和 .BytesKeyGeneratorBytesEncryptor

6.4. 春季保险库 1.1.0 中的新功能

  • AWS IAM 身份验证。
  • 配置传输密钥的加密/解密版本。
  • 应用角色身份验证的拉取模式。
  • 传输批量加密和解密支持。
  • 基于 TTL 的通用机密轮换。

6.5. 春季保险库 1.0 中的新功能

  • 初始保管库支持。

参考文档

7. 保险库支持

Vault 支持包含广泛的功能,总结如下。

  • 使用基于 Java 的 @Configuration 类的 Spring 配置支持
  • ​​VaultTemplate​​帮助程序类,可提高工作效率,执行常见性能 保险库操作。包括保险柜响应和 POJO 之间的集成对象映射。

对于大多数任务,您会发现自己使用 丰富的通信功能。 是寻找的地方 访问功能,例如从保险柜读取数据或发出 管理命令。 还提供回调方法,以便您轻松 获取低级 API 工件,例如用于通信 直接与保险柜。​​VaultTemplate​​​​VaultTemplate​​​​VaultTemplate​​​​RestTemplate​​

7.1. 依赖关系

查找兼容版本的 Spring Vault 依赖项的最简单方法 是依靠我们随兼容版本一起提供的Spring Vault BOM 定义。在 Maven 项目中,您将在 :​​<dependencyManagement />​​​​pom.xml​​

例 1.使用 Spring Vault BOM

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.vault</groupId> <artifactId>spring-vault-dependencies</artifactId> <version>2.2.3.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies></dependencyManagement>

当前版本为 。版本名称如下 模式:其中释放可以是以下之一:​​2.2.3.RELEASE​​​​${version}-${release}​​

  • ​​BUILD-SNAPSHOT​​- 当前快照
  • ​​M1​​等 - 里程碑M2
  • ​​RC1​​等 - 发布候选版本RC2
  • ​​RELEASE​​- 正式发布
  • ​​SR1​​等 - 服务发布SR2

例 2.声明对 Spring Vault 的依赖关系

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

7.2. 弹簧框架

Spring Vault 的当前版本需要 Spring Framework 5.2.12.发布或更好。这些模块也可能使用较旧的错误修复 该次要版本的版本。但是,使用最新版本 强烈建议在这一代内。

8. 入门

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

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

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

然后将以下内容添加到依赖项部分。​​pom.xml​​

例 3.添加 Spring Vault 依赖项

<dependencies> <!-- other dependency elements omitted --> <dependency> <groupId>org.springframework.vault</groupId> <artifactId>spring-vault-core</artifactId> <version>2.2.3.RELEASE</version> </dependency></dependencies>

如果您使用的是里程碑或候选版本,则还需要添加 Spring 的位置 您的 maven 的里程碑存储库,它与您的元素处于同一级别。​​pom.xml​​​​<dependencies/>​​

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

存储库也可以在此处浏览。

如果您使用的是快照,则还需要添加弹簧的位置 快照存储库到您的 maven,该存储库与您的元素处于同一级别。​​pom.xml​​​​<dependencies/>​​

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

存储库也可以在此处浏览。

创建一个简单的类来持久保存:​​Secrets​​

例 4.映射的数据对象

package org.spring.vault.example;public class Secrets { String username; String password; public String getUsername() { return username; } public String getPassword() { return password; }}

和要运行的主要应用程序

例 5.使用 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 上下文即可使用 Spring Vault。org.springframework.vault.client.VaultEndpointClientAuthentication
  • 保管库应配置根令牌 以运行此应用程序。00000000-0000-0000-0000-000000000000
  • 映射器针对标准 POJO 对象工作,无需任何 其他元数据(但您可以选择提供该信息)。
  • 映射约定可以使用字段访问。请注意,该类只有 getter。Secrets
  • 如果构造函数参数名称与存储文档的字段名称匹配, 它们将用于实例化对象。

9. 保险库模板简介

类 ,位于包中, 是 Spring 的 Vault 支持的核心类,提供丰富的功能集 与保险柜互动。该模板提供了读取、写入和 删除保险柜中的数据,并提供网域对象与保险柜数据之间的映射。​​VaultTemplate​​​​org.springframework.vault.core​​

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

Vault 文档和域类之间的映射是通过委派给 来完成的。Spring Web 支持提供了映射基础结构。​​RestTemplate​​

该类实现接口 。 尽可能以方法命名 在保险柜 API 上可用,使现有保险柜开发者熟悉该 API 习惯了 API 和 CLI。例如,您会发现诸如 “写入”、“删除”、“读取”和“撤销”。 设计目标是尽可能轻松地在 保管库 API 的使用和 .两者之间的主要区别 这两个 API 是可以传递域对象而不是 JSON 键值对。​​VaultTemplate​​​​VaultOperations​​​​VaultOperations​​​​VaultOperations​​​​VaultOperations​​

引用实例上操作的首选方法 是通过它的界面.​​VaultTemplate​​​​VaultOperations​​

虽然有许多方便的方法可以帮助您轻松 如果您需要直接访问保管库 API 才能访问,请执行常见任务 未显式公开的功能 您可以使用以下之一 几个执行回调方法来访问底层 API。执行回调 将为您提供对对象的引用。 有关详细信息,请参阅执行回调部分。​​VaultTemplate​​​​VaultTemplate​​​​RestOperations​​

现在让我们看一个如何在 Spring 容器上下文中使用 Vault 的示例。

9.1. 注册和配置 Spring Vault bean

使用 Spring Vault 不需要 Spring 上下文。但是,在托管上下文中注册的实例将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处置活动的保管库会话非常有用 应用程序关闭。您还可以从在整个应用程序中重用同一实例中受益。​​VaultTemplate​​​​SessionManager​​​​VaultTemplate​​

Spring Vault 附带了一个支持配置类,该类提供 Bean 定义 用于 Spring 上下文。应用程序配置 类通常从 并且需要 提供特定于环境的其他详细信息。​​AbstractVaultConfiguration​​

从需求扩展到实现 ' VaultEndpoint vaultEndpoint()' 和方法。​​AbstractVaultConfiguration​​​​ClientAuthentication clientAuthentication()​​

例 6.使用基于 Java 的 Bean 元数据注册 Spring Vault 对象

@Configurationpublic class AppConfig extends AbstractVaultConfiguration { /** * Specify an endpoint for connecting to Vault. */ @Override public VaultEndpoint vaultEndpoint() { return new VaultEndpoint(); } /** * Configure a client authentication. * Please consider a more secure authentication method * for production use. */ @Override public ClientAuthentication clientAuthentication() { return new TokenAuthentication("…"); }}

创建一个缺省情况下指向 的新节点。​​VaultEndpoint​​​​https://localhost:8200​​

此示例用于快速入门。

有关支持的身份验证方法的详细信息,请参阅身份验证方法​。​​TokenAuthentication​​

例 7.注册应用注入属性的 Spring Vault

@Configurationpublic 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); } /** * Configure a Client Certificate authentication. * {@link RestOperations} can be obtained from {@link #restOperations()}. */ @Override public ClientAuthentication clientAuthentication() { return new ClientCertificateAuthentication(restOperations()); }}

​​VaultEndpoint​​​可以使用各种工厂方法(如 或 )进行构造。​​from(URI uri)​​​​VaultEndpoint.create(String host, int port)​​

方法的依赖项可以从配置中获取,也可以由配置提供。​​ClientAuthentication​​​​AbstractVaultConfiguration​​

在某些情况下,创建自定义配置类可能很麻烦。 看看允许使用 来自现有属性源和 Spring 的属性。阅读更多 在使用环境保管库配置中。​​EnvironmentVaultConfiguration​​​​Environment​​

9.2. 会话管理

Spring Vault 需要登录和访问 Vault。 有关身份验证的详细信息,请参阅身份验证方法。 保管库登录不应发生在每个经过身份验证的保管库交互中,但应 必须在整个会话中重复使用。这方面由实现处理。A 决定多久一次 获取有关吊销和续订的令牌。Spring Vault 带有两个实现:​​ClientAuthentication​​​​SessionManager​​​​SessionManager​​

  • ​​SimpleSessionManager​​:仅从提供的令牌中获取令牌,无需刷新和吊销ClientAuthentication
  • ​​LifecycleAwareSessionManager​​:此计划令牌 如果令牌可续订,则续订,并在处置时撤销登录令牌。 续订计划使用 . 如果使用 ,则默认配置 。SessionManagerAsyncTaskExecutorLifecycleAwareSessionManagerAbstractVaultConfiguration

9.3. 使用​​EnvironmentVaultConfiguration​​

Spring Vault包括从Spring配置Vault客户端和一组预定义的 属性键。 支持频繁应用的配置。通过派生自最合适的配置类来支持其他配置。包含到现有 基于 Java 的配置类,并通过 Spring 的任何配置类提供配置属性。​​EnvironmentVaultConfiguration​​​​Environment​​​​EnvironmentVaultConfiguration​​​​EnvironmentVaultConfiguration​​​​@Import(EnvironmentVaultConfiguration.class)​​​​PropertySource​​

例 8.将环境保险库配置与属性文件结合使用

基于 Java 的配置类

@PropertySource("vault.properties")@Import(EnvironmentVaultConfiguration.class)public class MyConfiguration{}

保管库属性

vault.uri=https://localhost:8200vault.token=00000000-0000-0000-0000-000000000000

属性键

  • 保管库 URI:vault.uri
  • SSL 配置
  • 密钥库资源:(可选)vault.ssl.key-store
  • 密钥库密码:(可选)vault.ssl.key-store-password
  • 信任库资源:(可选)vault.ssl.trust-store
  • 信任库密码:(可选)vault.ssl.trust-store-password
  • 身份验证方法:(默认为 ,支持的身份验证方法包括:、、、vault.authenticationTOKENTOKENAPPIDAPPROLEAWS_EC2AZURECERTCUBBYHOLEKUBERNETES)

特定于身份验证的属性键

​令牌身份验证​

  • 金库令牌:vault.token

​应用标识身份验证​

  • AppId 路径:(默认为vault.app-id.app-id-pathapp-id)
  • 应用标识:vault.app-id.app-id
  • 用户标识:。 并使用各自的用户 ID 机制。 任何其他值都与 一起使用。vault.app-id.user-idMAC_ADDRESSIP_ADDRESSMacAddressUserIdIpAddressUserIdStaticUserId

​应用角色身份验证​

  • 应用角色路径:(默认为vault.app-role.app-role-pathapprole)
  • 角色标识:vault.app-role.role-id
  • 秘密 ID:(可选)vault.app-role.secret-id

​AWS-EC2 身份验证​

  • AWS EC2 路径:(默认为vault.aws-ec2.aws-ec2-pathaws-ec2)
  • 角色:vault.aws-ec2.role
  • 角色 ID:(已弃用:改用)vault.aws-ec2.role-idvault.aws-ec2.role
  • 身份证件网址:(默认为vault.aws-ec2.identity-documenthttp://169.254.169.254/latest/dynamic/instance-identity/pkcs7)

​Azure (MSI) 身份验证​

  • Azure MSI 路径:(默认为vault.azure-msi.azure-pathazure)
  • 角色:vault.azure-msi.role
  • 元数据服务 URL:(默认为vault.azure-msi.metadata-servicehttp://169.254.169.254/metadata/instance?api-version=2017-08-01)
  • 身份令牌服务 URL:(默认为vault.azure-msi.identity-token-servicehttp://169.254.169.254/metadata/identity/oauth2/token?resource=https://vault.hashicorp.com&api-version=2018-02-01)

TLS 证书身份验证

没有配置选项。

隔间孔认证

  • 初始保管库令牌:vault.token

Kubernetes 身份验证

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

9.4. 执行回调

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

下面是执行回调方法的列表。

  • ​​<T> T​​ doWithVault 执行给定的,允许使用与 Vault 进行交互,而无需会话。(RestOperationsCallback<T> callback)RestOperationsCallbackRestOperations
  • ​​<T> T​​ doWithSession 执行给定的 ,允许在经过身份验证的会话中与 Vault 交互。(RestOperationsCallback<T> callback)RestOperationsCallback

下面是一个使用 初始化 Vault 的示例:​​ClientCallback​​

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. 反应式保险库模板简介

本节介绍有关使用 Spring Vault 的响应式编程支持的基本信息。

10.1. 什么是响应式编程?

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

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

10.2. 反应式保险库客户端

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

它公开为对 HTTP 请求进行身份验证的供应商 并作为主要入口点。的核心配置 和 SSL 在 各种客户端实现。​​VaultTokenSupplier​​​​VaultToken​​​​ReactiveVaultOperations​​​​VaultEndpoint​​​​ClientOptions​​

类 ,位于包中, 是 Spring 反应式 Vault 支持的核心类,提供丰富的功能集 与保险柜互动。该模板提供了读取、写入和 删除保险柜中的数据,并提供网域对象与保险柜数据之间的映射。​​ReactiveVaultTemplate​​​​org.springframework.vault.core​​

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

Vault 文档和域类之间的映射是通过委派 to 及其编解码器来完成的。​​WebClient​​

该类实现接口 。 尽可能以方法命名 在保险柜 API 上可用,使现有保险柜开发者熟悉该 API 习惯了 API 和 CLI。例如,您会发现诸如 “写入”、“删除”和“读取”。 设计目标是尽可能轻松地在 保管库 API 的使用和 .两者之间的主要区别 这两个 API 是可以传递域对象而不是 JSON 键值对。​​ReactiveVaultTemplate​​​​ReactiveVaultOperations​​​​ReactiveVaultOperations​​​​ReactiveVaultOperations​​​​ReactiveVaultOperations​​

引用实例上操作的首选方法 是通过它的界面.​​ReactiveVaultTemplate​​​​ReactiveVaultOperations​​

未显式公开的功能 您可以使用以下之一 几个执行回调方法来访问底层 API。执行回调 将为您提供对对象的引用。 有关详细信息,请参阅执行回调部分。​​ReactiveVaultTemplate​​​​WebClient​​

现在让我们看一个如何在 Spring 容器上下文中使用 Vault 的示例。

10.3. 注册和配置 Spring Vault bean

使用 Spring Vault 不需要 Spring 上下文。但是,在托管上下文中注册的实例将参与 在 Spring IoC 容器提供的生命周期事件中。这对于在以下情况下处置活动的保管库会话非常有用 应用程序关闭。您还可以从在整个应用程序中重用同一实例中受益。​​ReactiveVaultTemplate​​​​VaultTokenSupplier​​​​ReactiveVaultTemplate​​

Spring Vault 附带了一个支持配置类,该类提供 Bean 定义 用于 Spring 上下文。应用程序配置 类通常从 并且需要 提供特定于环境的其他详细信息。​​AbstractVaultConfiguration​​

从需求扩展到实现 ' VaultEndpoint vaultEndpoint()' 和方法。​​AbstractVaultConfiguration​​​​ClientAuthentication clientAuthentication()​​

例 9.使用基于 Java 的 Bean 元数据注册 Spring Vault 对象

@Configurationpublic class AppConfig extends AbstractReactiveVaultConfiguration { /** * Specify an endpoint for connecting to Vault. */ @Override public VaultEndpoint vaultEndpoint() { return new VaultEndpoint(); } /** * Configure a client authentication. * Please consider a more secure authentication method * for production use. */ @Override public ClientAuthentication clientAuthentication() { return new TokenAuthentication("…"); }}

创建一个缺省情况下指向 的新节点。​​VaultEndpoint​​​​https://localhost:8200​​

此示例用于快速入门。

有关支持的身份验证方法的详细信息,请参阅身份验证方法​。​​TokenAuthentication​​

10.4. 会话管理

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

10.5. 执行回调

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

下面是执行回调方法的列表。

  • ​​<T> T​​ doWithVault 组成反应式 序列给定的,允许在没有会话上下文的情况下与 Vault 交互。(Function<WebClient, ? extends T> clientCallback)WebClient
  • ​​<T> T​​ doWithSession 组成反应式 序列给定的,允许在经过身份验证的会话中与 Vault 交互。(Function<WebClient, ? extends T> clientCallback)WebClient

下面是一个使用回调初始化 Vault 的示例:

reactiveVaultOperations.doWithVault(webClient -> { return webClient.put() .uri("/sys/init") .syncBody(request) .retrieve() .toEntity(VaultInitializationResponse.class);});

11. 库属性源支持

Vault 可以以许多不同的方式使用。一个特定的用例是使用 用于存储加密属性的保管库。Spring Vault 支持将 Vault 作为属性 source 以使用 Spring 的 PropertySource 抽象获取配置属性。

您可以在其他特性源中引用存储在 Vault 中的特性,也可以将值注入与 一起使用。引导需要存储在 Vault 中的数据的 Bean 时需要特别注意。此时必须初始化 才能从 Vault 检索属性。​​@Value(…)​​​​VaultPropertySource​​

Spring Boot/Spring Cloud 用户可以从 Spring Cloud Vault 中受益。 在应用程序启动期间初始化各种属性源的配置集成。

11.1. 注册​​VaultPropertySource​​

Spring Vault 提供了一个与 Vault 一起使用以获得 性能。它使用嵌套元素来公开存储的属性和 在保管库中加密。​​VaultPropertySource​​​​data​​

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

在上面的代码中,已添加具有最高优先级 在搜索中。如果它包含“foo”属性,它将被检测并返回 在任何其他财产之前。 公开了许多允许精确 操作属性源集。​​VaultPropertySource​​​​foo​​​​PropertySource​​​​MutablePropertySources​​

11.2. @VaultPropertySource

注释提供了方便的声明性 将 a 添加到 Spring 以与类结合使用的机制。​​@VaultPropertySource​​​​PropertySource​​​​Environment​​​​@Configuration​​

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

例 10.存储在库中的属性

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

例 11.声明​​@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; }}

例 12.声明具有凭据轮换和前缀的​​@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 时会轮换通用机密。​​generic​​​​refresh_interval​​​​PropertySource​​

您可以使用 从受版本控制的键值后端获取最新的密钥版本。确保不在路径中包含该段。​​@VaultPropertySource​​​​data/​​

路径中存在的任何占位符都是根据已针对环境注册的属性源集解析的,如以下示例所示:​​${…}​​​​@VaultPropertySource​​

例 13.使用占位符声明路径​​@VaultPropertySource​​

@Configuration@VaultPropertySource(value = "aws/creds/${my.placeholder:fallback/value}", propertyNamePrefix = "aws.", renewal = Renewal.ROTATE)public class AppConfig {}

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

在某些情况下,严格控制可能是不可能的或不切实际的 使用批注时的属性源排序。 例如,如果上述类是通过 组件扫描,排序很难预测。 在这种情况下 - 如果覆盖很重要 - 建议 用户回退到使用编程属性源 API。 有关详细信息,请参阅 ConfigurableEnvironment 和 muttablePropertySources。​​@VaultPropertySource​​​​@Configuration​​

12. 库存储库

使用和映射到 Java 类的响应允许基本的数据操作,如读取、写入 并删除。Vault存储库在Vault之上应用Spring Data的存储库概念。 Vault 存储库公开了基本的 CRUD 功能,并支持具有谓词约束的查询派生 Id 属性,分页和排序。​​VaultTemplate​​

在Spring Data Commons参考文档中阅读有关Spring Data Repository的更多信息。参考文档将向您介绍 Spring 数据存储库。

12.1. 用法

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

例 14。示例凭据实体

@Secretpublic class Credentials { @Id String id; String password; String socialSecurityNumber; Address address;}

我们这里有一个非常简单的域对象。请注意,它有一个名为 annotated with 的属性,并对其类型进行了注释。 这两个负责创建用于将对象作为 JSON 保留在保管库中的实际密钥。​​id​​​​org.springframework.data.annotation.Id​​​​@Secret​​

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

下一步是声明使用域对象的存储库接口。

例 15。实体的基本存储库接口​​Credentials​​

public interface CredentialsRepository extends CrudRepository<Credentials, String> {}

随着我们的存储库扩展,它提供了基本的 CRUD 和查询方法。库存储库 需要 Spring 数据组件。确保在类路径中包含 和项目。​​CrudRepository​​​​spring-data-commons​​​​spring-data-keyvalue​​

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

然后将以下内容添加到依赖项部分。​​pom.xml​​

例 16。使用弹簧数据BOM

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-releasetrain</artifactId> <version>Moore-SR12</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>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-keyvalue</artifactId> <!-- Version inherited from the BOM --> </dependency></dependencies>

我们需要在两者之间将东西粘合在一起的东西是相应的 Spring 配置。

例 17.JavaConfig for Vault Repository

@Configuration@EnableVaultRepositoriespublic class ApplicationConfig { @Bean public VaultTemplate vaultTemplate() { return new VaultTemplate(…); }}

鉴于上述设置,我们可以继续注入到我们的组件中。​​CredentialsRepository​​

例 18。对个人实体的访问权限

@Autowired CredentialsRepository repo;public 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); repo.findOne(creds.getId()); repo.count(); repo.delete(creds); }

使用键模式存储保管库哈希内部的属性,

在本例中,在通用密钥后端中。​​Credentials​​​​keyspace/id​​​​credentials/heisenberg​​

使用提供的 ID 检索存储在 中的对象。​​keyspace/id​​

计算 上定义的密钥空间凭据中可用的实体总数。​​@Secret​​​​Credentials​​

从保管库中删除给定对象的密钥。

12.2. 对象到文件库 JSON 映射

保管库存储库使用 JSON 作为交换格式将对象存储在保管库中。JSON 和 JSON 之间的对象映射 该实体由 完成。转换器读取和写入包含正文 从 .从 Vault 读取,主体由 杰克逊成和. 默认实现读取 与嵌套值,对象和 将它们转换为实体,反之亦然。​​VaultConverter​​​​SecretDocument​​​​VaultResponse​​​​VaultResponse​​​​Map​​​​String​​​​Object​​​​VaultConverter​​​​Map​​​​List​​​​Map​​

给定前面部分中的类型,默认映射如下所示:​​Credentials​​

{ "_class": "org.example.Credentials", "password", "327215", "socialSecurityNumber": "AAA-GG-SSSS", "address": { "street": "308 Negra Arroyo Lane", "city": "Albuquerque", "state": "New Mexico", "zip":"87104" }}

该属性包含在根级别以及任何嵌套接口或抽象类型中。​​_class​​

简单属性值按路径映射。

复杂类型的属性映射为嵌套对象。

该属性必须映射到 。​​@Id​​​​String​​

Table 1. Default Mapping Rules

类型

样本

映射值

简单类型(例如。字符串)

字符串名字 =“瓦尔特”;

名字 = “瓦尔特”

复杂类型(例如地址)

地址地址 = 新地址(“308 Negra Arroyo Lane”);

地址: { “街道”: “308 Negra Arroyo Lane” }

简单类型列表

列表<字符串>昵称 = asList(“walt”, “heisenberg”);

昵称:[“沃尔特”、“海森堡”]

简单类型的地图

Map<String, Integer> atts = asMap(“age”, 51)

atts : {“age” : 51}

复杂类型列表

列表<地址> 地址 = asList(新地址(“308...

地址: [{ “街道”: “308 Negra Arroyo Lane” }, ...]

您可以通过在 中注册 来自定义映射行为。 这些转换器可以负责从/转换为类型,例如,而第一个转换器适用于将简单属性转换为,最后一个复杂类型适用于将 JSON 转换为 表示法。第二个选项提供对结果的完全控制。将对象写入将删除内容并重新创建整个条目,因此未映射的数据将丢失。​​Converter​​​​VaultCustomConversions​​​​LocalDate​​​​SecretDocument​​​​SecretDocument​​​​Vault​​

12.3. 查询和查询方法

查询方法允许从方法名称自动派生简单查询。保险柜没有查询引擎,但 需要直接访问 HTTP 上下文路径。保险柜查询方法将保险柜的 API 可能性转换为查询。 查询方法执行在上下文路径下列出子项,对 Id 应用筛选,可以选择限制 具有偏移量/限制的 id 流,并在获取结果后应用排序。

例 19。示例存储库查询方法

public interface CredentialsRepository extends CrudRepository<Credentials, String> { List<Credentials> findByIdStartsWith(String prefix);}

Vault 存储库的查询方法仅支持对属性具有谓词的查询。​​@Id​​

下面概述了保险柜支持的关键字。

Table 2. Supported keywords for query methods

关键词

样本

​​After​​​,​​GreaterThan​​

​​findByIdGreaterThan(String id)​​

​​GreaterThanEqual​​

​​findByIdGreaterThanEqual(String id)​​

​​Before​​​,​​LessThan​​

​​findByIdLessThan(String id)​​

​​LessThanEqual​​

​​findByIdLessThanEqual(String id)​​

​​Between​​

​​findByIdBetween(String from, String to)​​

​​In​​

​​findByIdIn(Collection ids)​​

​​NotIn​​

​​findByIdNotIn(Collection ids)​​

​​Like​​​, ,​​StartingWith​​​​EndingWith​​

​​findByIdLike(String id)​​

​​NotLike​​​,​​IsNotLike​​

​​findByIdNotLike(String id)​​

​​Containing​​

​​findByFirstnameContaining(String id)​​

​​NotContaining​​

​​findByFirstnameNotContaining(String name)​​

​​Regex​​

​​findByIdRegex(String id)​​

​​(No keyword)​​

​​findById(String name)​​

​​Not​​

​​findByIdNot(String id)​​

​​And​​

​​findByLastnameAndFirstname​​

​​Or​​

​​findByLastnameOrFirstname​​

​​Is,Equals​​

​​findByFirstname​​​,,​​findByFirstnameIs​​​​findByFirstnameEquals​​

​​Top,First​​

​​findFirst10ByFirstname​​​,​​findTop5ByFirstname​​

12.3.1. 排序和分页

查询方法通过在内存中选择从中检索的子列表(偏移/限制)ID 来支持排序和分页 保险柜上下文路径。与查询方法谓词不同,排序不限于特定字段。 在 Id 过滤后应用未分页排序,并从保管库获取所有生成的机密。这边 查询方法仅提取也作为结果的一部分返回的结果。

使用分页和排序需要在过滤 ID 之前进行秘密获取,这会影响性能。 排序和分页保证返回相同的结果,即使 Vault 返回的 Id 的自然顺序发生更改也是如此。 因此,首先从 Vault 获取所有 Id,然后应用排序,然后进行过滤和偏移/限制。

例 20。分页和排序存储库

public interface CredentialsRepository extends PagingAndSortingRepository<Credentials, String> { List<Credentials> findTop10ByIdStartsWithOrderBySocialSecurityNumberDesc(String prefix); List<Credentials> findByIdStarts(String prefix, Pageable pageRequest);}

13. 客户支持

Spring Vault 支持各种 HTTP 客户端访问 Vault 的 HTTP API。Spring Vault 使用 RestTemplate 作为访问 Vault 的主要界面。 专用客户端支持源自自定义的 SSL 配置,该配置的范围仅限于 Spring Vault 的客户端组件。

Spring Vault 支持以下 HTTP 命令式客户端:

  • Java的内置(默认客户端)HttpURLConnection
  • Apache Http Components
  • 内蒂
  • OkHttp 3

Spring Vault 的反应式集成支持以下反应式 HTTP 客户端:

  • 反应器网
  • 码头

使用特定客户机要求相应的依赖关系在类路径上可用 因此,Spring Vault 可以使用可用的客户端与 Vault 进行通信。

13.1. Java的内置​​HttpURLConnection​​

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

13.2. 外部客户端

您可以使用外部客户端访问保险柜的 API。只需添加以下其中一项 项目的依赖项。如果使用 Spring Vault 的依赖项 BOM,则可以省略版本号

例 21。Apache Http Components Dependency

<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId></dependency>

Apache HttpClient 的线路日志记录可以通过日志记录配置启用。请确保不要意外启用线路日志记录,因为日志可能会以纯文本形式公开应用程序和 Vault 之间的流量(令牌和机密)。

例 22。Netty Dependency

<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId></dependency>

例 23。方形 OkHttp 3

<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId></dependency>

例 24。反应器网

<dependency> <groupId>io.projectreactor.netty</groupId> <artifactId>reactor-netty</artifactId></dependency>

例 25。码头

<dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-reactive-httpclient</artifactId></dependency>

13.3. 库客户端 SSL 配置

可以通过设置各种属性来配置 SSL。 您可以设置配置为配置 JVM 范围的 SSL 设置或配置为仅为 Spring Vault 设置 SSL 设置。​​SslConfiguration​​​​javax.net.ssl.trustStore​​​​SslConfiguration​​

SslConfiguration sslConfiguration = SslConfiguration.create( new FileSystemResource("client-cert.jks"), "changeit".toCharArray(), new FileSystemResource("truststore.jks"), "changeit".toCharArray());SslConfiguration.forTrustStore(new FileSystemResource("keystore.jks"), "changeit".toCharArray())SslConfiguration.forKeyStore(new FileSystemResource("keystore.jks"), "changeit".toCharArray())SslConfiguration.forKeyStore(new FileSystemResource("keystore.jks"), "changeit".toCharArray(), KeyConfiguration.of("key-password".toCharArray(), "my-key-alias"))

完整配置。

仅配置信任存储设置。

仅配置密钥存储设置。

通过提供密钥配置仅配置密钥存储设置。

请注意,只能提供 在 Apache Http 组件或 OkHttp 客户端时应用 在您的类路径上。​​SslConfiguration​​

14. 身份验证方法

不同的组织对安全性有不同的要求 和身份验证。保险柜通过传送多个身份验证来反映这一需求 方法。Spring Vault 支持多种身份验证机制。

14.1. 外部化登录凭据

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

向任何一方披露登录凭据都允许登录到 Vault 并访问以下机密: 由基础角色允许。选择适当的客户端身份验证和 将凭据注入应用程序需要接受风险评估。

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

例 26。外部化到属性文件​​vault.token​​

@PropertySource("configuration.properties")@Configurationpublic class Config extends AbstractVaultConfiguration { @Override public ClientAuthentication clientAuthentication() { return new TokenAuthentication(getEnvironment().getProperty("vault.token")); }}

弹簧允许多种方式获得。使用时,注入通孔不会提供,因为环境豆仍在建设中,自动布线将在稍后阶段出现。您的配置类应该实现并获取来自 .​​Environment​​​​VaultPropertySource​​​​@Autowired Environment environment​​​​Environment​​​​ApplicationContextAware​​​​Environment​​​​ApplicationContext​​

有关在组件和其他属性源中引用属性的示例.java请参阅 SecurePropertyUsage。

14.2. 令牌身份验证

令牌是保管库中身份验证的核心方法。 令牌身份验证需要提供静态令牌。

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

通常,令牌身份验证用于创建和续订令牌的方案 外部(如桥生保险库服务代理)。 根据实际设置,您可能需要也可能不需要令牌续订和吊销。 有关 TTL 和令牌吊销的详细信息,请参阅 LifecycleAwareSessionManager。

@Configurationclass AppConfig extends AbstractVaultConfiguration { // … @Override public ClientAuthentication clientAuthentication() { return new TokenAuthentication("…"); } // …}

另请参阅:

  • 保管库文档:令牌
  • 保管库文档:使用令牌身份验证后端

14.3. 应用标识身份验证

保管库已弃用 AppId 身份验证。请改用应用角色身份验证。

保险柜支持由两个难以猜测的令牌组成的 AppId 身份验证。应用标识 默认为静态配置。 第二个令牌是 UserId,它是由应用程序确定的部分, 通常与运行时环境相关。IP 地址、Mac 地址或 Docker 容器名称就是很好的例子。弹簧穹顶支架 IP 地址、Mac 地址和静态用户 ID(例如,通过系统属性提供)。 IP 和 Mac 地址表示为十六进制编码的 SHA256 哈希。​​spring.application.name​​

基于 IP 地址的用户 ID 使用本地主机的 IP 地址。

@Configurationclass 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 地址的用户 ID 从 本地主机绑定设备。该配置还允许指定 选择正确设备的提示。的值是可选的,可以是接口 名称或接口索引(从 0 开始)。​​network-interface​​​​network-interface​​

@Configurationclass 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​​

网友评论