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.yml
或 application.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 会依次查找以下路径中的配置项(优先级从高到低):
secret/fakebank/production
✅ 最高优先级secret/fakebank
secret/application/production
secret/application
❌ 最低优先级
其中 application
是默认的应用名前缀,可以通过 spring.cloud.vault.generic.default-context
修改。
路径越具体,优先级越高。比如多个路径下都存在 key 为 foo
的配置,最终生效的将是优先级最高的那个。
5. 使用 Database Secret Backend(动态数据库凭证)
Database Backend 允许 Spring 应用使用由 Vault 自动生成的数据库用户凭证。
Spring Vault 会把这些凭证注入到标准的 spring.datasource.username
和 spring.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
绕过验证,但仅限测试环境使用。