Как я могу использовать SpringBoot для получения учетных данных БД из Vault?

У меня есть приложение springboot, которое использует следующие версии:

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

Я использовал пользовательский класс, как описано здесь (ответ от @Arun): Настройка Spring Cloud Vault Config для загрузки из расположения, отличного от /secret

Кажется, он даже не собирает конфигурации хранилища. У меня есть 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.

Что я делаю не так?


person Dany    schedule 06.07.2020    source источник
comment
похоже, что путь для учетных данных в хранилище отсутствует в вашем bootstrap.yml   -  person storm_buster    schedule 09.07.2020
comment
да, пытался использовать пользовательский VaultConfigurer, как определено в упомянутом сообщении SO, вместо того, чтобы определять его в начальной загрузке. в итоге определил бэкэнд kv.   -  person Dany    schedule 10.07.2020


Ответы (2)


Вы пропустили аннотации на 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();
  }
}
person J J    schedule 06.07.2020
comment
Я пробовал @ConfigurationProperties непосредственно в классе DatabaseConfig.java, а также в классе DatabaseCredentials.java, который затем использовал, как показано в моем ОП выше (автопровод, затем config.username). Ни один из них не работал. Я получаю это обратно как ошибку: 2020-07-06 17:25:46,482 DEBUG pool.PoolBase - HikariPool-1 - Failed to create/setup connection: FATAL: password authentication failed for user "username" - person Dany; 07.07.2020
comment
Спасибо за обновление, но это то, что у меня было. Фактически, приведенный вами пример - это то, что я привел в исходном посте. Но, как я уже сказал, когда приложение запускается, оно DatabaseCredentials пусто. - person Dany; 07.07.2020
comment
Это не совсем то же самое - person J J; 07.07.2020
comment
У меня есть две версии класса DatabaseConfig.java, перечисленные выше. Извините, кроме тега @Profile.., я не вижу, что отличается от моей первой версии. - person Dany; 07.07.2020

Spring Cloud Vault предоставляет информацию DEBUG, которая помогла мне разобраться в проблеме. В итоге я определил путь с помощью kv вместо пользовательского компонента VaultConfigurer.

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 Vault не шел по вложенным путям для секретов и искал там файл со всеми учетными данными.

Итак, я удалил dev папку и заменил ее dev файлом с такими записями, как:

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

Я могу получить учетные данные из хранилища, используя только класс DatabaseConfig.java и не используя DatabaseCredentials.java с аннотацией @ConfigurationProperties.

person Dany    schedule 07.07.2020