diff --git a/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java b/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java index ba7b0c48..c94f45a4 100644 --- a/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java +++ b/spring-vault-core/src/main/java/org/springframework/vault/config/AbstractVaultConfiguration.java @@ -15,10 +15,14 @@ */ package org.springframework.vault.config; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.http.client.ClientHttpRequestFactory; @@ -41,7 +45,9 @@ import org.springframework.vault.support.SslConfiguration; * @author Mark Paluch */ @Configuration -public abstract class AbstractVaultConfiguration { +public abstract class AbstractVaultConfiguration implements ApplicationContextAware { + + private ApplicationContext applicationContext; /** * @return Vault endpoint coordinates for HTTP/HTTPS communication, must not be @@ -164,6 +170,28 @@ public abstract class AbstractVaultConfiguration { return new VaultTemplate(vaultClientFactory(), sessionManager()); } + /** + * Return the {@link Environment} to access property sources during Spring Vault + * bootstrapping. Requires {@link #setApplicationContext(ApplicationContext) + * ApplicationContext} to be set. + * + * @return the {@link Environment} to access property sources during Spring Vault + * bootstrapping. + */ + protected Environment getEnvironment() { + + Assert.state(applicationContext != null, + "ApplicationContext must be set before accessing getEnvironment()"); + + return applicationContext.getEnvironment(); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.applicationContext = applicationContext; + } + /** * Wrapper for {@link ClientHttpRequestFactory} to not expose the bean globally. */ diff --git a/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java b/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java index ad3443d0..745804e6 100644 --- a/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java +++ b/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java @@ -18,16 +18,12 @@ package org.springframework.vault.demo; import java.util.HashMap; import java.util.Map; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySources; -import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import org.springframework.vault.annotation.VaultPropertySource; import org.springframework.vault.authentication.ClientAuthentication; @@ -82,20 +78,11 @@ public class SecurePropertyUsage { @VaultPropertySource({ "secret/secure-introduction" }) @Configuration @ComponentScan - static class Config extends VaultIntegrationTestConfiguration implements - ApplicationContextAware { - - private Environment environment; + static class Config extends VaultIntegrationTestConfiguration { @Override public ClientAuthentication clientAuthentication() { - return new TokenAuthentication(environment.getProperty("vault.token")); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - environment = applicationContext.getEnvironment(); + return new TokenAuthentication(getEnvironment().getProperty("vault.token")); } } diff --git a/src/main/asciidoc/reference/authentication.adoc b/src/main/asciidoc/reference/authentication.adoc index f4cc587e..37a24f33 100644 --- a/src/main/asciidoc/reference/authentication.adoc +++ b/src/main/asciidoc/reference/authentication.adoc @@ -26,25 +26,18 @@ OS access levels. ---- @PropertySource("configuration.properties"), @Configuration -static class Config extends VaultIntegrationTestConfiguration implements - ApplicationContextAware { - - private Environment environment; +public class Config extends AbstractVaultConfiguration { @Override public ClientAuthentication clientAuthentication() { - return new TokenAuthentication(environment.getProperty("vault.token")); + return new TokenAuthentication(getEnvironment().getProperty("vault.token")); } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - environment = applicationContext.getEnvironment(); - } } ---- ==== +NOTE: Spring allows multiple ways to obtain `Environment`. When using `VaultPropertySource`, injection via `@Autowired Environment environment` will not provide the `Environment` as the environment bean is still in construction and autowiring comes at a later stage. Your configuration class should rather implement `ApplicationContextAware` and obtain the `Environment` from `ApplicationContext`. + See https://github.com/spring-projects/spring-vault/blob/master/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java[`SecurePropertyUsage.java`] for a sample on referencing properties in components and other property sources.