开篇词
该指南将引导你使用 Spring Cloud Vault 构建可从 HashiCorp Vault 检索其配置属性的应用。
你将创建的应用
我们将启动 Vault ,将配置属性存储在 Vault 中,构建 Spring 应用并将其与 Vault 连接。
你将需要的工具
- 大概 15 分钟左右;
- 你最喜欢的文本编辑器或集成开发环境(IDE)
- JDK 1.8 或更高版本;
- Gradle 4+ 或 Maven 3.2+
- 你还可以将代码直接导入到 IDE 中:
如何完成这个指南
像大多数的 Spring 入门指南一样,你可以从头开始并完成每个步骤,也可以绕过你已经熟悉的基本设置步骤。如论哪种方式,你最终都有可以工作的代码。
- 要从头开始,移步至用 Gradle 来构建;
- 要跳过基础,执行以下操作:
- 下载并解压缩该指南将用到的源代码,或借助 Git 来对其进行克隆操作:
git clone https://github.com/spring-guides/gs-vault-config.git
- 切换至
gs-vault-config/initial
目录; - 跳转至该指南的安装及启动 HashiCorp Vault。
- 下载并解压缩该指南将用到的源代码,或借助 Git 来对其进行克隆操作:
待一切就绪后,可以检查一下 gs-vault-config/complete
目录中的代码。
用 Gradle 来构建
首先,我们设置一个基本的构建脚本。在使用 Spring 构建应用时可以使用任何喜欢的构建系统,但此处包含使用 Gradle 和 Maven 所需的代码。如果你都不熟悉,请参阅使用 Gradle 构建 Java 项目或使用 Maven 构建 Java 项目。
创建目录结构
在我们选择的项目目录中,创建以下自目录结构;例如,在 *nix 系统上使用 mkdir -p src/main/java/hello
:
└── src
└── main
└── java
└── hello
创建 Gradle 构建文件
以下是初始 Gradle 构建文件。
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.2.1.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'gs-vault-config'
version = '0.1.0'
}
repositories {
mavenCentral()
}
ext {
springCloudVersion = 'Greenwich.SR2'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile('org.springframework.cloud:spring-cloud-starter-vault-config')
testCompile("org.springframework.boot:spring-boot-starter-test")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
Spring Boot gradle 插件提供了许多方便的功能:
- 它收集类路径上的所有 jar,并构建一个可运行的单个超级 jar,这使执行和传输服务更加方便;
- 它搜索
public static void main()
方法并将其标记为可运行类; - 它提供了一个内置的依赖解析器,用于设置版本号以及匹配 Spring Boot 依赖。我们可以覆盖所需的任何版本,但默认为 Boot 选择的一组版本。
用 Maven 来构建
首先,我们搭建一个基本的构建脚本。使用 Spring 构建应用时,可以使用任何喜欢的构建系统,但是此处包含了使用 Maven 所需的代码。如果你不熟悉 Maven,请参阅使用 Maven 构建 Java 项目。
创建目录结构
在我们选择的项目目录中,创建以下自目录结构;例如,在 *nix 系统上使用 mkdir -p src/main/java/hello
:
└── src
└── main
└── java
└── hello
创建 Maven 构建文件
以下是初始 Maven 构建文件。
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-vault-config</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
<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>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Spring Boot Maven 插件提供了许多方便的功能:
- 它收集类路径上的所有 jar,并构建一个可运行的单个超级 jar,这使执行和传输服务更加方便;
- 它搜索
public static void main()
方法并将其标记为可运行类; - 它提供了一个内置的依赖解析器,用于设置版本号以及匹配 Spring Boot 依赖。我们可以覆盖所需的任何版本,但默认为 Boot 选择的一组版本。
用 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.2.1/vault_1.2.1_darwin_amd64.zip
unzip vault_1.2.1_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 export VAULT_TOKEN="00000000-0000-0000-0000-000000000000"
export VAULT_ADDR="http://127.0.0.1:8200"
现在,我们可以在 Vault 中存储配置键值对:
vault kv put secret/gs-vault-config example.username=demouser example.password=demopassword
vault kv put secret/gs-vault-config/cloud example.username=clouduser example.password=cloudpassword
现在,我们已经在 Vault secret/gs-vault-config
和 secret/gs-vault-config/cloud
中写入了两个条目。
定义应用类
为我们的 Spring 应用创建一个简单的配置:
src/main/java/hello/MyConfiguration.java
package hello;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Mark Paluch
*/
@ConfigurationProperties("example")
public class MyConfiguration {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
配置应用
在这里,我们可以使用 bootstrap.properties
配置应用。Spring Cloud Vault 在引导上下文中运行,以最初获取配置属性,因此可以讲这些属性提供给自动配置和我们的应用本身。
src/main/resources/bootstrap.properties
spring.application.name=gs-vault-config
spring.cloud.vault.token=00000000-0000-0000-0000-000000000000
spring.cloud.vault.scheme=http
spring.cloud.vault.kv.enabled=true
创建应用
在这里,我们创建一个具有所有组件的 Application 类。
src/main/java/hello/Application.java
package hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(MyConfiguration.class)
public class Application implements CommandLineRunner {
private final MyConfiguration configuration;
public Application(MyConfiguration configuration) {
this.configuration = configuration;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) {
Logger logger = LoggerFactory.getLogger(Application.class);
logger.info("----------------------------------------");
logger.info("Configuration properties");
logger.info(" example.username is {}", configuration.getUsername());
logger.info(" example.password is {}", configuration.getPassword());
logger.info("----------------------------------------");
}
}
Spring Cloud Vault 使用 VaultOperations
与 Vault 进行交互。Vault 中的属性被映射到 MyConfiguration
以进行类型安全的访问。@EnableConfigurationProperties(MyConfiguration.class)
启用配置属性映射并注册 MyConfiguration
bean。
Application
包括 main()
方法,该方法自动装配 MyConfiguration
的实例。
构建可执行 JAR
我们可以结合 Gradle 或 Maven 来从命令行运行该应用。我们还可以构建一个包含所有必须依赖项、类以及资源的可执行 JAR 文件,然后运行该文件。在整个开发生命周期中,跨环境等等情况下,构建可执行 JAR 可以轻松地将服务作为应用进行发布、版本化以及部署。
如果使用 Gradle,则可以借助 ./gradlew bootRun
来运行应用。或通过借助 ./gradlew build
来构建 JAR 文件,然后运行 JAR 文件,如下所示:
java -jar build/libs/gs-vault-config-0.1.0.jar
如果使用 Maven,则可以借助 ./mvnw spring-boot:run
来运行该用。或可以借助 ./mvnw clean package
来构建 JAR 文件,然后运行 JAR 文件,如下所示:
java -jar target/gs-vault-config-0.1.0.jar
我们还可以将 JAR 应用转换成 WAR 应用。
当我们的 Applictaion
实现 CommandLineRunner
时,启动时会自动调用 run
方法。我们应该会看到以下内容:
----------------------------------------
Configuration properties
example.username is demouser
example.password is demopassword
----------------------------------------
现在,在激活了 cloud
配置文件的情况下启动我们的应用。我们应该会看到以下内容:
----------------------------------------
Configuration properties
example.username is clouduser
example.password is cloudpassword
----------------------------------------
配置属性根据激活的配置文件进行绑定。Spring Cloud Vault 从 spring.application.name
(即 gs-vault
)构造一个 Vault 上下文路径,并附加配置文件名称(cloud
),因此启用 cloud
配置文件将另外从 secret/gs-vault-config/cloud
获取配置属性。
概述
恭喜你!我们搭建了一个 Vault 服务器,并编写了一个简单的应用,该应用使用 Spring Vault 读取密码并使用强大的暗号对数据进行加密 - 所有这些密钥管理、暗号模式及填充都无需去费心实现。
想看指南的其他内容?请访问该指南的所属专栏:《Spring 官方指南》