Setting Datasource with encrypted password

73 Views Asked by At

I have the following datasource configurations in my application which works

application.yaml:

spring:
  datasource:
    batch:
      jdbcUrl: jdbc:mysql://localhost:33060/test
      username: root
      password: somepassowrd
      driver-class-name: com.mysql.cj.jdbc.Driver
      minimumIdle: 5
      maximumPoolSize: 15
      idleTimeout: 30000
      connectionTimeout: 30000
    reader:
      jdbcUrl: jdbc:mysql://localhost:3306/BL
      username: root
      password: someotherpassowrd
      driver-class-name: com.mysql.cj.jdbc.Driver
      minimumIdle: 5
      maximumPoolSize: 15
      idleTimeout: 30000
      connectionTimeout: 30000

DatasourceConfiguration class:

@Configuration
class DatasourceConfiguration() {
  @Bean(name = ["batchDatasource"])
  @ConfigurationProperties(prefix = "spring.datasource.batch")
  @BatchDataSource
  fun batchDataSource(): DataSource = HikariDataSource()

  @Bean(name = ["daoDatasource"])
  @ConfigurationProperties(prefix = "spring.datasource.reader")
  @Primary
  fun readerDataSource(): DataSource = HikariDataSource()
}

As said this works perfectly, but I now have a limitation that the passowrd in application.yaml is encrypted (hard limitation - can't change it).

How can I decrypt the password before creating the datasources?

I tried:

spring:
  datasource:
    batch:
      jdbcUrl: jdbc:mysql://localhost:33060/test
      username: root
      password: somepassowrd
      driver-class-name: com.mysql.cj.jdbc.Driver
      minimumIdle: 5
      maximumPoolSize: 15
      idleTimeout: 30000
      connectionTimeout: 30000
    reader:
      jdbcUrl: jdbc:mysql://localhost:3306/BL
      username: root
      password: someotherpassowrd
      driver-class-name: com.mysql.cj.jdbc.Driver
      minimumIdle: 5
      maximumPoolSize: 15
      idleTimeout: 30000
      connectionTimeout: 30000

DatasourceConfiguration class:

@Configuration
class DatasourceConfiguration() {
  @Bean(name = ["batchDatasource"])
  @ConfigurationProperties(prefix = "spring.datasource.batch")
  @BatchDataSource
  fun batchDataSource(@Value("${spring.datasource.batch.password}") encryptedPassword: String): DataSource = HikariDataSource()
    .apply(password = decryptPassword(encryptedPassword))

  @Bean(name = ["daoDatasource"])
  @ConfigurationProperties(prefix = "spring.datasource.reader")
  @Primary
  fun readerDataSource(@Value("${spring.datasource.reader.password}") encryptedPassword: String): DataSource = HikariDataSource()
    .apply(password = decryptPassword(encryptedPassword))
}

But it didn't work

1

There are 1 best solutions below

0
Lior Derei On

I was able to solve it with a small workaround: application.yaml:

spring:
  datasource:
    batch:
      jdbcUrl: jdbc:mysql://localhost:33060/test
      username: root
      // setting encrypted-password instead of password
      encrypted-password: somepassowrd
      driver-class-name: com.mysql.cj.jdbc.Driver
      minimumIdle: 5
      maximumPoolSize: 15
      idleTimeout: 30000
      connectionTimeout: 30000
    reader:
      jdbcUrl: jdbc:mysql://localhost:3306/BL
      username: root
      // setting encrypted-password instead of password
      encrypted-password: someotherpassowrd
      driver-class-name: com.mysql.cj.jdbc.Driver
      minimumIdle: 5
      maximumPoolSize: 15
      idleTimeout: 30000
      connectionTimeout: 30000

DatasourceConfiguration class:

@Configuration
class DatasourceConfiguration() {
  @Bean(name = ["batchDatasource"])
  @ConfigurationProperties(prefix = "spring.datasource.batch")
  @BatchDataSource
  fun batchDataSource(@Value("${spring.datasource.batch.encrypted-password}") encryptedPassword: String): DataSource = HikariDataSource()
    .apply(password = decryptPassword(encryptedPassword))

  @Bean(name = ["daoDatasource"])
  @ConfigurationProperties(prefix = "spring.datasource.reader")
  @Primary
  fun readerDataSource(@Value("${spring.datasource.reader.encrypted-password}") encryptedPassword: String): DataSource = HikariDataSource()
    .apply(password = decryptPassword(encryptedPassword))
}

Explanation: What I figured is that whatever I set in the apply is clause being overridden by the @ConfigurationProperties.

So instead of declaring a password property in the application.yaml, I set a different property - encrypted-password, so @ConfigurationProperties won't override the password.

This way I can take the encrypted-password, decrypt it and set it as password in the apply clause