5

I am working on a Spring Boot application that should be deployed to Azure. Using the following dependency I managed to use secrets from the KeyVault for sensitive application properties:

    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-keyvault-secrets-spring-boot-starter</artifactId>
        <version>2.1.6</version>
    </dependency>

With setting the poperty azure.keyvault.uri=https://my-vault.vault.azure.net and configuring Managed Service Identity I just inject the secret name from the KeyVault like this:

@Value("${ServerPassphrase}")
String serverPassphrase;

Now I have a database connection and the password has the usual key spring.datasource.password. Unfortunately dots are not allowed in secret names in Azure KeyVault. :-(

Is there a simple way to replace the dots with dashes which are allowed characters in KeyVault or do I have to write a custom property resolver as a wrapper?

Frank
  • 2,036
  • 1
  • 20
  • 32

3 Answers3

2

So after all, it seems there is no simple way to tell spring boot to use dashes instead of dots. I finally ended up writing a custom DataSource in my MainConfig as well as a custom ServletWebServerFactory to set all the ssl properties for tomcat. For the case that someone ends up here, looking for a solution to this or a similar problem I'll post some code snippets that might help.

Code for DataSource (I read all the common properties from application properties using the dot-notation, just username and password are read from KeyVault):

@Value("${db-user}")
String dbUser;

@Value("${db-password}")
String dbPwd;

@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource getDataSource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.username(dbUser);
    dataSourceBuilder.password(dbPwd);
    return dataSourceBuilder.build();
}

Code for ServletWebServerFactory (all the used values are injected as above using @Value-annotation):

@Bean
public ServletWebServerFactory servletContainer() {

    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    TomcatConnectorCustomizer tomcatConnectorCustomizer = connector -> {
        connector.setPort(port);
        connector.setScheme("https");
        connector.setSecure(true);

        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
        protocol.setSSLEnabled(true);
        protocol.setKeystoreType(keyStoreType);
        protocol.setKeystoreProvider(keyStoreProvider);
        protocol.setKeystoreFile(keyStorePath);
        protocol.setKeystorePass(keyStorePassword);
        protocol.setKeyAlias(keyAlias);
        protocol.setTruststoreFile(trustStorePath);
        protocol.setTruststorePass(trustStorePassword);
        protocol.setSSLVerifyClient(clientAuth);
    };

    tomcat.addConnectorCustomizers(tomcatConnectorCustomizer);
    return tomcat;
}

There where some other places where I had to use something similar, but as this was specially for our solution I won't post it here. I think you might get the idea how to solve things like this from the posted code.

Frank
  • 2,036
  • 1
  • 20
  • 32
1

In this tutorial, they don't need the trick with the properties file, the use '-' as '.' for the keyvault, and the API seem to automatically replace the '-' by '.'. Tested and working with version 2.3.2 of azure-keyvault-secrets-spring-boot-starter


In official documentation of "Azure Key Vault Secrets Spring boot starter" there is a section about this problem you have to use the not compliant properties in your properties file. But it's not working for me

spring.datasource.password=${spring-datasource-password}
Bertrand Cedric
  • 653
  • 6
  • 11
0

Secret names can only contain alphanumeric characters and dashes.

Secret name is only a name, what we need is the value of it. I am using dashes instead of dots.

@Value("${spring-datasource-password}")
private String dataSourcePassword;

enter image description here

Update:

I wondered if there is a simple way to tell spring to use dashes instead of dots so it won't be necessary to write extra code.

As far as I know, there is no such way.

Tony Ju
  • 14,891
  • 3
  • 17
  • 31
  • I already tried this, but it seems like the default datasource configuration of spring boot cannot read this property. Of course I could use a custom datasource but I wanted to avoid that. Furthermore this is not the only property where I want to store a secret and where springs convention is to use dots (for example: server.ssl.key-password), and I wondered if there is a simple way to tell spring to use dashes instead of dots so it won't be necessary to write extra code. – Frank Oct 09 '19 at 07:58
  • @Frank As far as I know, there is no such way in spring. – Tony Ju Oct 09 '19 at 09:44
  • Oh sorry, completely forgot about this. I finally ended up doing what I thought I might do: write a custom datasource and also a custom TomcatInitializer to make use of properties with dashes. – Frank Oct 21 '19 at 06:37
  • @Frank Since you issue has been resolved, can you accept it as answer or add your better answer? Then this issue can be closed. Thank you. – Tony Ju Oct 25 '19 at 01:43