本指南将引导您完成使用SpringVault构建应用程序的过程,该应用程序从机密管理工具HashiCorp Vault中加载机密信息。您将加载存储在Vault中的机密信息,并使用传输加密的后端。

程序结构

└── 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>2.1.6.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</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>

</project>

Spring Boot将会你做如下的事:

  • 将 classpath 里面所有用到的jar包构建成一个可执行的 JAR 文件,方便执行你的程序
  • 搜索public static void main()方法并且将它当作可执行类
  • 根据springboot版本,去查找相应的依赖类版本,当然你可以定义其它版本。

安装并运行HashiCorp Vault
如果使用Mac,如下安装:

$ brew install vault

或者,从这里下载https://www.vaultproject.io/downloads.html:

$ https://releases.hashicorp.com/vault/0.8.3/vault_0.8.3_darwin_amd64.zip
$ unzip vault_0.8.3_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 write secret/github github.oauth2.key=foobar

配置你的应用程序
在这里,您使用bootstrap.properties配置应用程序。引导上下文配置了Spring Cloud Vault.
src/main/resources/bootstrap.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.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.read("secret/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。
应用程序包含一个main()方法,该方法自动连接MyConfiguration的实例。

运行并测试程序
当我们的应用程序实现CommandLineRunner时,启动时会自动调用run方法。你应该看到这样的东西:

Value of github.oauth2.key
-------------------------------
foobar
-------------------------------

Encrypted value
-------------------------------
vault:v1:2wgVE2PXiR9o55xbyur5KHJl8IwyGDkDU4l1SZScUq6BuqZYgTopwvc4
-------------------------------

Decrypted value
-------------------------------
Secure message
-------------------------------

Vault的机密后端方式与使用URI标识文档的文档存储相比,效果很好。文档是基于JSON的,允许对Vault 数据进行对象映射。

祝贺你!您设置了一个Vault 服务器,并编写了一个简单的应用程序,该应用程序使用Spring Vault强大的密码-来读取机密和加密数据,所有这些都不需要你非常麻烦地实现密钥管理、密码模式和填充。