本指南将带您了解如何使用 Spring Vault 构建一个应用程序,该应用程序从 HashiCorp Vault(一个密钥管理工具)加载密钥。
您将构建的内容
您将加载存储在 Vault 中的密钥,并使用传输加密后端。
所需准备
-
大约 15 分钟
-
常用的文本编辑器或集成开发环境
-
Java 17 或更高版本
-
您也可以直接将代码导入到您的 IDE 中:
如何完成本指南
与大多数 Spring 入门指南一样,您可以从头开始并完成每个步骤,也可以跳过您已经熟悉的基本设置步骤。无论哪种方式,您最终都能得到可运行的代码。
要从头开始,请继续 使用 Gradle 构建。
要跳过基础部分,请执行以下操作:
-
下载并解压本指南的源代码仓库,或使用 Git 克隆它:
git clone https://github.com/spring-guides/gs-accessing-vault.git
-
进入
gs-accessing-vault/initial
目录 -
直接跳转到 安装并启动 HashiCorp Vault。
完成之后,您可以将结果与 gs-accessing-vault/complete
中的代码进行对比。
使用 Gradle 构建
使用 Gradle 构建
首先,您需要设置一个基本的构建脚本。在使用 Spring 构建应用程序时,您可以使用任何喜欢的构建系统,但这里包含了与 Gradle 和 Maven 一起工作所需的代码。如果您对这两者都不熟悉,请参考 使用 Gradle 构建 Java 项目 或 使用 Maven 构建 Java 项目。
创建目录结构
在您选择的项目目录中,创建以下子目录结构;例如,在 *nix 系统上使用 mkdir -p src/main/java/hello
:
└── src
└── main
└── java
└── hello
创建一个 Gradle 构建文件
以下是 初始的 Gradle 构建文件。
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.0'
id 'io.spring.dependency-management' version '1.1.5'
}
group = 'gs-accessing-vault'
version = '0.1.0'
repositories {
mavenCentral()
maven {
url "https://repo.spring.io/milestone"
}
}
ext {
set('springCloudVersion', "2023.0.2")
}
dependencies {
implementation('org.springframework.cloud:spring-cloud-starter-vault-config')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
Spring Boot gradle 插件 提供了许多便捷的功能:
-
它会收集类路径上的所有 jar 包,并构建一个单独的可运行的 "über-jar",这使得执行和传输您的服务更加方便。
-
它会搜索
public static void main()
方法,将其标记为可运行的类。 -
它提供了一个内置的依赖解析器,用于设置版本号以匹配 Spring Boot 依赖项。您可以覆盖任何您希望的版本,但默认情况下它将使用 Boot 选择的版本集。
使用 Maven 构建
使用 Maven 构建
首先,您需要设置一个基本的构建脚本。在使用 Spring 构建应用程序时,您可以使用任何您喜欢的构建系统,但这里包含了您需要使用 Maven 的代码。如果您不熟悉 Maven,请参考 使用 Maven 构建 Java 项目。
创建目录结构
在您选择的项目目录中,创建以下子目录结构;例如,在 *nix 系统上使用 mkdir -p src/main/java/hello
:
└── src
└── main
└── java
└── hello
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-accessing-vault</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
</parent>
<properties>
<spring-cloud.version>2023.0.2</spring-cloud.version>
</properties>
<dependencies>
<!-- Vault Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-libs-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</repository>
</repositories>
</project>
Spring Boot Maven 插件 提供了许多便捷的功能:
-
它会收集类路径上的所有 jar 文件,并构建一个可运行的 "über-jar",这使得您的服务更便于执行和传输。
-
它会搜索
public static void main()
方法,将其标记为可运行类。 -
它提供了一个内置的依赖解析器,用于设置版本号以匹配 Spring Boot 依赖项。您可以覆盖任何您希望的版本,但默认情况下它将使用 Boot 选择的版本集。
使用您的 IDE 进行构建
使用你的 IDE 构建
- 阅读如何将此指南直接导入 Spring Tool Suite。
- 阅读如何在 IntelliJ IDEA 中使用此指南。
安装并启动 HashiCorp Vault
在项目设置完成后,您可以安装并启动 HashiCorp Vault。
如果您使用的是带有 Homebrew 的 Mac,操作非常简单:
$ brew install vault
或者,从 https://www.vaultproject.io/downloads.html 下载适用于您操作系统的 Vault:
$ https://releases.hashicorp.com/vault/1.12.2/vault_1.12.2_darwin_amd64.zip
$ unzip vault_1.12.2_darwin_amd64.zip
对于其他带有包管理系统的系统,如 Redhat、Ubuntu、Debian、CentOS 和 Windows,请参阅 https://www.vaultproject.io/docs/install/index.html 上的说明。
安装 Vault 后,在控制台窗口中启动它。此命令还会启动一个服务器进程。
$ vault server --dev --dev-root-token-id="00000000-0000-0000-0000-000000000000"
您应该会在最后的输出行中看到以下内容:
[INFO ] core: post-unseal setup complete
上述命令以开发模式启动 Vault,使用内存存储且不进行传输加密。这适用于在本地评估 Vault。请确保在生产环境中使用适当的 SSL 证书和可靠的存储后端。更多详情请参阅 Vault 的生产环境加固指南。
在 Vault 中存储机密
Vault 是一个密钥管理系统,允许您存储加密的敏感数据。它是存储密码、加密密钥、API 密钥等敏感配置信息的理想选择。
使用 Vault 命令行,在另一个控制台窗口中将应用程序配置存储到 Vault 中。
首先,您需要设置两个环境变量,以将 Vault CLI 指向 Vault 端点并提供身份验证令牌。
$ export VAULT_TOKEN="00000000-0000-0000-0000-000000000000"
$ export VAULT_ADDR="http://127.0.0.1:8200"
现在您可以在 Vault 中存储配置键值对:
$ vault kv put secret/github github.oauth2.key=foobar
配置您的应用程序
在这里,您可以使用 application.properties
来配置您的应用程序。Spring Cloud Vault 是通过引导上下文进行配置的。
src/main/resources/application.properties
spring.cloud.vault.token=00000000-0000-0000-0000-000000000000
spring.cloud.vault.scheme=http
创建一个应用程序类
在这里,您创建了一个包含所有组件的 Application 类。
src/main/java/hello/Application.java
package hello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.vault.core.VaultKeyValueOperationsSupport.KeyValueBackend;
import org.springframework.vault.core.VaultSysOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultTransitOperations;
import org.springframework.vault.support.VaultMount;
import org.springframework.vault.support.VaultResponse;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private VaultTemplate vaultTemplate;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) throws Exception {
// You usually would not print a secret to stdout
VaultResponse response = vaultTemplate
.opsForKeyValue("secret", KeyValueBackend.KV_2).get("github");
System.out.println("Value of github.oauth2.key");
System.out.println("-------------------------------");
System.out.println(response.getData().get("github.oauth2.key"));
System.out.println("-------------------------------");
System.out.println();
// Let's encrypt some data using the Transit backend.
VaultTransitOperations transitOperations = vaultTemplate.opsForTransit();
// We need to setup transit first (assuming you didn't set up it yet).
VaultSysOperations sysOperations = vaultTemplate.opsForSys();
if (!sysOperations.getMounts().containsKey("transit/")) {
sysOperations.mount("transit", VaultMount.create("transit"));
transitOperations.createKey("foo-key");
}
// Encrypt a plain-text value
String ciphertext = transitOperations.encrypt("foo-key", "Secure message");
System.out.println("Encrypted value");
System.out.println("-------------------------------");
System.out.println(ciphertext);
System.out.println("-------------------------------");
System.out.println();
// Decrypt
String plaintext = transitOperations.decrypt("foo-key", ciphertext);
System.out.println("Decrypted value");
System.out.println("-------------------------------");
System.out.println(plaintext);
System.out.println("-------------------------------");
System.out.println();
}
}
Spring Cloud Vault 使用 VaultOperations
与 Vault 进行交互。来自 Vault 的属性被映射到 MyConfiguration
,以实现类型安全的访问。@EnableConfigurationProperties(MyConfiguration.class)
启用了配置属性映射,并注册了一个 MyConfiguration
bean。
Application
包含一个 main()
方法,该方法自动装配了一个 MyConfiguration
的实例。
构建一个可执行的 JAR 文件 {#_build_an_executable_jar}
您可以使用 Gradle 或 Maven 从命令行运行应用程序。您还可以构建一个包含所有必要依赖、类和资源的单个可执行 JAR 文件并运行它。构建可执行 jar 文件可以方便地在整个开发生命周期、跨不同环境等场景中作为应用程序进行分发、版本控制和部署。
如果您使用的是 Gradle,可以通过 ./gradlew bootRun
来运行应用程序。或者,您可以通过 ./gradlew build
构建 JAR 文件,然后运行该 JAR 文件,如下所示:
java -jar build/libs/gs-accessing-vault-0.1.0.jar
如果您使用 Maven,可以通过 ./mvnw spring-boot:run
来运行应用程序。或者,您也可以使用 ./mvnw clean package
构建 JAR 文件,然后运行该 JAR 文件,如下所示:
java -jar target/gs-accessing-vault-0.1.0.jar
这里描述的步骤是创建一个可运行的 JAR 文件。您也可以构建一个经典的 WAR 文件。
由于我们的 Application
实现了 CommandLineRunner
,因此当 Spring Boot 启动时,run
方法会自动被调用。您应该会看到类似以下的内容:
Value of github.oauth2.key
*------------------------------
foobar
*------------------------------
Encrypted value
*------------------------------
vault:v1:2wgVE2PXiR9o55xbyur5KHJl8IwyGDkDU4l1SZScUq6BuqZYgTopwvc4
*------------------------------
Decrypted value
*------------------------------
Secure message
*------------------------------
Vault 的密钥后端与使用 URI 来标识文档的文档存储非常相似。文档基于 JSON 格式,这使得 Vault 数据的对象映射非常方便。
总结
恭喜!您已经成功设置了一个 Vault 服务器,并编写了一个简单的应用程序,该应用程序使用 Spring Vault 来读取密钥并使用强加密算法加密数据——这一切都无需费心实现密钥管理、加密模式和填充。