1. 概述

本文将介绍如何在 Spring Boot 应用中集成 Hashicorp Vault,用于管理敏感配置数据。

✅ 假设你已经对 Vault 有基本了解,并且本地已经有一个可用的测试环境。如果还没有,建议先阅读我们的 Vault 入门教程,快速掌握 Vault 的基础使用。

2. Spring Cloud Vault 是什么?

Spring Cloud Vault 是 Spring Cloud 生态中一个较新的组件,它允许应用程序以透明的方式访问 Vault 中存储的密钥信息

迁移至 Vault 非常简单:只需要引入相关依赖,并在配置文件中添加少量属性即可,无需修改任何业务代码!

这是因为它会作为一个高优先级的 PropertySource 注册到 Spring 的 Environment 中。

这意味着,当 Spring 需要加载配置时(如数据库连接信息、自定义的 @ConfigurationProperties 等),它会自动从 Vault 中获取对应值。

3. 在 Spring Boot 项目中引入 Spring Cloud Vault

要在基于 Maven 的 Spring Boot 项目中引入 spring-cloud-vault,我们可以通过对应的 starter 来完成:

<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>

📌 最新版的 Spring Cloud Vault Starter 可在 Maven Central 获取。

3.1. 基础配置

为了让 Spring Cloud Vault 正常工作,我们需要告诉它:

  • Vault 服务地址在哪?
  • 如何进行身份认证?

这些信息通常写在 application.ymlapplication.properties 文件中:

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

⚠️ 注意:上面这个配置没有包含认证信息。

如果你使用的是固定 Token 认证方式,可以将 Token 通过系统属性 spring.cloud.vault.token 或环境变量传入。这种方式非常适合与 Kubernetes ConfigMap、Docker Secrets 等云原生配置机制结合使用。

此外,Spring Vault 还需要为每种 Secret 类型单独配置支持模块。下面我们将分别介绍 Key/Value 和数据库凭证两种常见用法。

4. 使用 Generic Secrets Backend(Key/Value)

Vault 的 Generic Secret Backend 用于访问非版本化的键值对数据

如果你已经在 classpath 中包含了 spring-cloud-starter-vault-config,那么只需在 application.yml 中添加如下配置即可启用该功能:

spring:
  cloud:
    vault:
      generic:
        enabled: true
        application-name: fakebank

其中 application-name 是可选字段,如果不设置,默认会使用 spring.application.name 的值。

此时,所有存储在 secret/fakebank 路径下的键值对都可以像普通配置一样被读取。例如:

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

✅ 看到了吧?这段代码完全不知道 Vault 的存在 —— 这正是我们想要的效果!

你可以本地开发时使用静态配置,部署时切换成 Vault 动态配置,仅需修改一个开关即可。

4.1. 关于 Spring Profiles 的处理

如果当前环境中启用了 Profile,Spring Cloud Vault 会自动将其作为后缀追加到路径上查找 Secret。

同时,它还会尝试从默认应用路径中加载共享配置(无论是否带 Profile 后缀)。

⚠️ 使用共享配置要小心,确保不会泄露敏感信息!

举个例子,假设当前激活的是 production profile,应用名为 fakebank,则 Spring Vault 会依次查找以下路径中的配置项(优先级从高到低):

  1. secret/fakebank/production ✅ 最高优先级
  2. secret/fakebank
  3. secret/application/production
  4. secret/application ❌ 最低优先级

其中 application 是默认的应用名前缀,可以通过 spring.cloud.vault.generic.default-context 修改。

路径越具体,优先级越高。比如多个路径下都存在 key 为 foo 的配置,最终生效的将是优先级最高的那个。

5. 使用 Database Secret Backend(动态数据库凭证)

Database Backend 允许 Spring 应用使用由 Vault 自动生成的数据库用户凭证

Spring Vault 会把这些凭证注入到标准的 spring.datasource.usernamespring.datasource.password 属性中,供常规的 DataSource 使用。

⚠️ 在使用此功能之前,请确保已在 Vault 中正确配置了数据库角色和权限策略(参考 Vault 教程)。

要在 Spring 应用中使用 Vault 动态生成的数据库凭证,除了引入 spring-cloud-vault-config-databases 外,还需要对应的 JDBC 驱动,并在 application.yml 中添加以下配置:

spring:
  cloud:
    vault:
      database:
        enabled: true
        role: fakebank-accounts-rw

最关键的是 role 字段,它指定了 Vault 中已定义的数据库角色名称。Spring 启动时会请求 Vault 创建具有该角色权限的新用户凭证。

Vault 默认会在租约到期后自动撤销这些凭证权限。

✅ 不过别担心,Spring Vault 会自动续签租约,只要应用还在运行,这些凭证就一直有效。

下面是一个获取数据库连接的示例代码:

Connection c = datasource.getConnection();

再次强调:这段代码也完全感知不到 Vault 的存在 —— 所有集成都在 Environment 层完成,便于单元测试。

6. 总结

在这篇文章中,我们介绍了如何使用 Spring Cloud Vault 将 Vault 集成进 Spring Boot 应用,并演示了两个典型场景:

  • ✅ 使用 Key/Value 存储通用配置
  • ✅ 使用 Database Backend 实现动态数据库凭证

完整的示例项目(含依赖、集成测试及 Vault 初始化脚本)可以在 GitHub 上找到:https://github.com/eugenp/tutorials/tree/master/spring-cloud-modules/spring-cloud-vault


📌 小贴士:

  • 不要用“端点”翻译 “Endpoint”,在中文技术圈里“接口”更常见。
  • “annotation” 是“注解”,不是“标签”或“注释”。
  • 遇到 TLS 证书报错时,可以用 vault read -tls-skip-verify 绕过验证,但仅限测试环境使用。

原始标题:An Intro to Spring Cloud Vault