Issue
I need to connect to Vault from my spring boot microservice. To get the vault token, the service needs to login to vault by providing username and password. Spring-vault integration doesn't support this behaviour by default.
I came across this href="https://stackoverflow.com/questions/49651475/userpass-authentication-vault">SO question and tried the approach but it results in BeanDefinitionStoreException
, as the bean named clientAuthentication
is already defined.
Later I have referred this example and extend AbstractVaultConfiguration
. Now my configuration hierarchy looks like the below:
@Configuration(proxyBeanMethods = false)
public abstract class AbstractVaultConfiguration implements ApplicationContextAware {
public abstract VaultEndpoint vaultEndpoint();
public abstract ClientAuthentication clientAuthentication();
// other methods and bean definitions
}
@Configuration
public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration implements
ApplicationContextAware {
// other methods
}
public class VaultCustomConfig extends AbstractVaultConfiguration {
@Override
public VaultEndpoint vaultEndpoint() {
return VaultEndpoint.create("https://vault-dev.net", 443);
}
@Override
public ClientAuthentication clientAuthentication() {
//logic to fetch token
}
}
First two classes are provided by spring-vault. I have added the last one and also put entry in spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.test.configuration.VaultCustomConfig
The application is starting but getting 403 error. When I exclude EnvironmentVaultConfiguration
from auto configuration, getting exceptions that many beans are not created(ex-vaultTemplate
). I am able to contact vault API and fetch the token using RestTemplate
. The challenge is setting that token before the app tries to contact vault(through spring-vault support).
Instead of overriding vault configuration, I tried setting an environment variable named vault.token
which will be read by spring during start-up, but that is also not working(probably I missed something).
How can I override the built-in configuration and provide the token?
Solution
Spring reads vault token from this property spring.cloud.vault.token
. I have created a custom PropertySourceLocator
and added the token:
public class VaultCustomPropertySourceLocator implements PropertySourceLocator {
@Override
public PropertySource<?> locate(Environment environment) {
Properties props = new Properties();
props.setProperty("spring.cloud.vault.token", getVaultAuthToken());
PropertiesPropertySource ps = new PropertiesPropertySource("customPropsSource",props);
return ps;
}
private String getVaultAuthToken() {
// logic to fetch vault token
}
}
Answered By - Antony Vimal Raj
Answer Checked By - Terry (JavaFixing Volunteer)