An Intro to Spring Cloud Vault – Spring Cloud Vault的介绍

最后修改: 2018年 9月 15日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll show how we can use Hashicorp’s Vault in Spring Boot applications to secure sensitive configuration data.

在本教程中,我们将展示如何在Spring Boot应用程序中使用Hashicorp的Vault来保护敏感配置数据。

We assume here some Vault knowledge and that we have a test setup already up and running. If this isn’t the case, let’s take a moment to read our Vault Intro tutorial so we can get acquainted with its basics.

我们在此假设有一些Vault的知识,并且我们已经有一个测试设置并正在运行。如果不是这样,让我们花点时间阅读我们的Vault介绍教程,以便我们能够熟悉它的基础知识。

2. Spring Cloud Vault

2.Spring云库

Spring Cloud Vault is a relatively recent addition to the Spring Cloud stack that allows applications to access secrets stored in a Vault instance in a transparent way.

Spring Cloud Vault是Spring Cloud堆栈的一个相对较新的补充,允许应用程序以透明的方式访问存储在Vault实例中的秘密

In general, migrating to Vault is a very simple process: just add the required libraries and add a few extra configuration properties to our project and we should be good to go. No code changes are required!

一般来说,迁移到Vault是一个非常简单的过程:只需添加所需的库,并在我们的项目中添加一些额外的配置属性,我们就可以开始了。不需要修改代码!

This is possible because it acts as a high priority PropertySource registered in the current Environment.

这是可能的,因为它作为一个高优先级的属性源在当前环境中注册了。

As such, Spring will use it whenever a property is required. Examples include DataSource properties, ConfigurationProperties, and so on.

因此,Spring将在需要属性的时候使用它。例子包括DataSource属性、ConfigurationProperties等等。

3. Adding Spring Cloud Vault to a Spring Boot Project

3.将Spring Cloud Vault添加到Spring Boot项目中

In order to include the spring-cloud-vault library in a Maven-based Spring Boot project, we use the associated starter artifact, which will pull all required dependencies.

为了在基于Maven的Spring Boot项目中包含spring-cloud-vault库,我们使用相关的starter工件,它将提取所有必要的依赖。

Besides the main starter, we’ll also include the spring-vault-config-databases, which adds support for dynamic database credentials:

除了主要的starter,我们还将包括spring-vault-config-databases,它增加了对动态数据库凭证的支持。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-vault-config-databases</artifactId>
</dependency>

The latest version of the Spring Cloud Vault starter can be downloaded from Maven Central.

最新版本的Spring Cloud Vault启动器可以从Maven Central下载。

3.1. Basic Configuration

3.1.基本配置

In order to work properly, Spring Cloud Vault needs a way to determine where to contact the Vault server and how to authenticate itself against it.

为了正常工作,Spring Cloud Vault需要一种方法来确定在哪里联系Vault服务器以及如何对其进行认证。

We do this by providing the necessary information in the application.yml or application.properties:

我们通过在application.ymlapplication.properties中提供必要的信息来做到这一点。

spring:
  cloud:
    vault:
      uri: https://localhost:8200
      ssl:
        trust-store: classpath:/vault.jks
        trust-store-password: changeit
  config:
    import: vault:// 

The spring.cloud.vault.uri property points to Vault’s API address. Since our test environment uses HTTPS with a self-signed certificate, we also need to provide a keystore containing its public key.

spring.cloud.vault.uri属性指向Vault的API地址。由于我们的测试环境使用带有自签名证书的HTTPS,我们还需要提供一个包含其公钥的密钥库。

Note that this configuration has no authentication data. For the simplest case, where we use a fixed token, we can pass it through the system property spring.cloud.vault.token or an environment variable. This approach works well in conjunction with standard cloud configuration mechanisms, such as Kubernetes’ ConfigMaps or Docker secrets.

注意,该配置没有认证数据。对于最简单的情况,即我们使用一个固定的令牌,我们可以通过系统属性spring.cloud.vault.token或环境变量来传递它。这种方法与标准的云配置机制(如Kubernetes的ConfigMaps或Docker secrets)配合使用效果很好。

Spring Vault also requires extra configuration for each type of secret that we want to use in our application. The following sections describe how we can add support to two common secret types: key/value and database credentials.

Spring Vault还需要对我们想要在应用程序中使用的每种类型的秘密进行额外的配置。下面几节描述了我们如何为两种常见的秘密类型添加支持:键/值和数据库凭证。

4. Using the Generic Secrets Backend

4.使用 “通用秘密 “后端

We use the Generic Secret backend to access unversioned secrets stored as Key-Value pairs in Vault.

我们使用Generic Secret后端来访问unversioned存储在Vault中作为Key-Value对的秘密

Assuming we already have the spring-cloud-starter-vault-config dependency in our classpath, all we have to do is to add a few properties to the application.yml file:

假设我们在classpath中已经有了spring-cloud-starter-vault-config依赖项,我们所要做的就是在application.yml文件中添加一些属性。

spring:
  cloud:
    vault:
      # other vault properties omitted ...
      generic:
        enabled: true
        application-name: fakebank

The property application-name is optional in this case. If not specified, Spring will assume the value of the standard spring.application.name instead.

在这种情况下,属性application-name是可选的。如果不指定,Spring将假设标准的spring.application.name的值来代替。

We now can use all key/value pairs stored at secret/fakebank as any other Environment property. The following snippet shows how we can read the value of the foo key stored under this path:

我们现在可以将存储在secret/fakebank的所有键/值对作为任何其他Environment属性下面的片段显示了我们如何读取存储在此路径下的foo键的值。

@Autowired Environment env;
public String getFoo() {
    return env.getProperty("foo");
}

As we can see, the code itself knows nothing about Vault, which is a good thing! We can still use fixed properties in local tests and switch to Vault as we please by just enabling a single property in the application.yml.

正如我们所看到的,代码本身对Vault一无所知,这是一件好事我们仍然可以在本地测试中使用固定的属性,只要在应用程序.yml中启用一个属性,就可以随意切换到Vault。

4.1. A Note on Spring Profiles

4.1.关于Spring Profiles的说明

If available in the current Environment, Spring Cloud Vault will use the available profile names as a suffix appended to the specified base path where key/value pairs will be searched.

如果在当前环境中可用,Spring Cloud Vault 将使用可用的配置文件名称作为后缀,附加到将搜索键/值对的指定基本路径上

It will also look for properties under a configurable default application path (with and without a profile suffix) so we can have shared secrets in a single location. Use this feature with caution!

它还会在可配置的默认应用程序路径下寻找属性(有或没有配置文件后缀),因此我们可以在一个位置上拥有共享的秘密。谨慎地使用这个功能!

To summarize, if the production profile of out fakebank application is active, Spring Vault will look for properties stored under the following paths:

总而言之,如果出fakebank应用程序的production配置文件处于活动状态,Spring Vault将寻找存储在以下路径下的属性。

  1. secret/fakebank/production (higher priority)
  2. secret/fakebank
  3. secret/application/production
  4. secret/application (lower priority)

In the preceding list, application is the name that Spring uses as a default additional location for secrets. We can modify it using the spring.cloud.vault.generic.default-context property.

在前面的列表中,application是Spring用来作为秘密的默认附加位置的名称。我们可以使用spring.cloud.vault.generic.default-context属性修改它。

Properties stored under the most specific path will take precedence over the others. For instance, if the same property foo is available under paths above, then the precedence order would be:

存储在最具体路径下的属性将优先于其他属性。例如,如果同一个属性foo 在上述路径下可用,那么优先顺序将是。

5. Using the Database Secret Backend

5.使用数据库秘密后端

The Database backend module allows Spring applications to use dynamically generated database credentials created by Vault. Spring Vault injects those credentials under the standard spring.datasource.username and spring.datasource.password properties so they can be picked by regular DataSources.

数据库后端模块允许Spring应用程序使用由Vault创建的动态生成的数据库凭证。Spring Vault在标准的spring.datasource.usernamespring.datasource.password属性下注入这些凭证,因此它们可以被普通的DataSources所选中。

Please note that, before using this backend, we must create a database configuration and roles in Vault as described in our previous tutorial.

请注意,在使用该后端之前,我们必须按照我们之前的教程中的描述,在Vault中创建一个数据库配置和角色。

In order to use Vault generated database credentials in our Spring application, the spring-cloud-vault-config-databases must be present in the project’s classpath, along with the corresponding JDBC driver.

为了在我们的Spring应用程序中使用Vault生成的数据库凭证,spring-cloud-vault-config-databases必须出现在项目的classpath中,同时还有相应的JDBC驱动程序。

We also need to enable its use in our application by adding a few properties to our application.yml:

我们还需要在我们的application.yml中添加一些属性,以便在我们的应用程序中启用其使用:

spring:
  cloud:
    vault:
      # ... other properties omitted
      database:
        enabled: true
        role: fakebank-accounts-rw

The most important property here is the role property, which holds a database role name stored in Vault. During startup, Spring will contact Vault and request that it creates new credentials with the corresponding privileges.

这里最重要的属性是role属性,它持有存储在Vault中的数据库角色名称。在启动过程中,Spring将联系Vault并要求它创建具有相应权限的新凭证。

The vault will, by default, revoke the privileges associated with those credentials after the configured time-to-live.

默认情况下,保险库将在配置的生存时间后撤销与这些证书相关的权限。

Fortunately, Spring Vault will automatically renew the lease associated with the acquired credentials. By doing this, the credentials will stay valid as long our application is running.

幸运的是,Spring Vault将自动更新与所获凭证相关的租约。通过这样做,只要我们的应用程序在运行,凭证将保持有效。

Now, let´s see this integration in action. The following snippet gets a new database connection from a Spring-managed DataSource:

现在,让我们看看这个集成的实际效果。下面的片段从Spring管理的DataSource获得一个新的数据库连接。

Connection c = datasource.getConnection();

Once again, we can see that there is no sign of Vault usage in our code. All integration happens at the Environment level, so our code can easily be unit-tested as usual.

再一次,我们可以看到我们的代码中没有Vault使用的迹象。所有的集成都发生在环境级别,所以我们的代码可以像往常一样轻松地进行单元测试。

6. Conclusion

6.结语

In this tutorial, we’ve shown how to integrate Vault with Spring Boot using the Spring Vault library. We’ve covered two common use cases: generic key/value pairs and dynamic database credentials.

在本教程中,我们展示了如何使用Spring Vault库将Vault与Spring Boot集成。我们介绍了两种常见的使用情况:通用键/值对和动态数据库凭证。

A sample project containing all required dependencies, integrations tests and vault setup scripts is available over on GitHub.

一个包含所有必要的依赖项、集成测试和金库设置脚本的示例项目可在GitHub上获得。