我如何使用 Spring Boot 从 Vault 获取数据库凭证?

How can I use SpringBoot to pick up DB credentials from Vault?

我有一个 springboot 应用程序使用这些版本:

SpringBoot: 2.3.1
SpringCloud: Hoxton.SR5 
SpringData: Neumann-SR1

我使用了这里描述的自定义 class(@Arun 的回答):

它似乎甚至没有获取保险库配置。 我有一个 bootstrap.yml 具有以下内容:

spring:
  cloud:
    # Vault configurations
    vault:
      generic:
        enabled: false
      uri: https://${URI}
      authentication: TOKEN
      token: ${VAULT_TOKEN}

    config:
      discovery:
        enabled: true

我正在尝试在本地提出,所以我的 application.yml 如下:

spring:
  datasource:
    url: jdbc:postgresql://localhost:8157/postgres

这是我尝试将 vault 中的值注入我的数据源的地方:

@Profile(value = {"local", "dev", "stg", "prd"})
@Configuration
public class DatabaseConfig {

  @Autowired
  DatabaseCredentials config;

  @Bean
  @Primary
  public DataSource dataSource() {

    return DataSourceBuilder
        .create()
        .username(config.getUsername())
        .url(config.getUrl())
        .password(config.getPassword())
        .driverClassName("org.postgresql.Driver")
        .build();
  }
}

当应用程序启动时,DatabaseCredentials 是空的。

我做的另一种方法是这样的:

public class DatabaseConfig {
  
  @Value("${ccm.database.username}")
  String username;

  @Value("${ccm.database.password}")
  String password;

  @Value("${spring.datasource.url}")
  String url;

  @Bean
  @Primary
  public DataSource dataSource() {
    
    return DataSourceBuilder
        .create()
        .username(username)
        .url(url)
        .password(password)
        .driverClassName("org.postgresql.Driver")
        .build();
  }
}

这也是空的,说找不到 ccm.database.username 的值。

我做错了什么?

您缺少 DatabaseConfig.java

上的注释

会是这样的。

@Component
@ConfigurationProperties("ccm.database")

于是就变成了

@ConfigurationProperties("ccm.database")
@Component
public class DatabaseCredentials {
  
  @Value("${ccm.database.username}")
  String username;

  @Value("${ccm.database.password}")
  String password;

  @Value("${spring.datasource.url}")
  String url;

  // Getters and setters for all properties go here
}

访问配置

@Configuration
public class DatabaseConfig {

  @Autowired
  DatabaseCredentials config;

  @Bean
  @Primary
  public DataSource dataSource() {

    return DataSourceBuilder
        .create()
        .username(config.getUsername())
        .url(config.getUrl())
        .password(config.getPassword())
        .driverClassName("org.postgresql.Driver")
        .build();
  }
}

Spring Cloud Vault 为您提供调试信息,帮助我找出问题所在。我最终用 kv 而不是自定义 VaultConfigurer bean 定义了路径。

kv:
  enabled: true
  backend: tcds/kv/app-name
  application-name: ccm

这将创建如下路径:tcds/kv/app-name/ccm/${PROFILE}
我假设这条路径下的所有秘密都会被拾取,我最初在 tcds/kv/app-name/ccm/dev.
路径下有多个 文件夹 例如:../ccm/dev/database../ccm/dev/other-creds.

但是,spring 保管库似乎没有进入秘密的嵌套路径,而是在寻找一个 文件,其中包含所有凭据。

所以,我删除了 dev 文件夹 并将其替换为 dev 文件 ,其中包含以下条目如:

{
  "database.username": "blah",
  "database.password": "moreblah",
  "other-creds.user": "dummy"
}

我可以通过单独使用 DatabaseConfig.java class 来从保管库获取凭据,而不必将 DatabaseCredentials.java@ConfigurationProperties 注释一起使用。

Spring 云支持从 vault 导入标准 spring 引导配置。

使用两个依赖进行自动配置:

  • org.springframework.cloud:spring-cloud-starter-vault-config

  • org.springframework.cloud:spring-cloud-vault-config-databases

参见: https://medium.com/digitalfrontiers/manage-your-database-accounts-with-spring-cloud-vault-config-48cecb837a36