diff --git a/spring-vault-core/src/main/java/org/springframework/vault/config/ClientHttpRequestFactoryFactory.java b/spring-vault-core/src/main/java/org/springframework/vault/config/ClientHttpRequestFactoryFactory.java
index ee007e1b..0cf8e22b 100644
--- a/spring-vault-core/src/main/java/org/springframework/vault/config/ClientHttpRequestFactoryFactory.java
+++ b/spring-vault-core/src/main/java/org/springframework/vault/config/ClientHttpRequestFactoryFactory.java
@@ -132,7 +132,7 @@ public class ClientHttpRequestFactoryFactory {
return new SimpleClientHttpRequestFactory();
}
- private static SSLContext getSSLContext(SslConfiguration sslConfiguration)
+ static SSLContext getSSLContext(SslConfiguration sslConfiguration)
throws GeneralSecurityException, IOException {
KeyManager[] keyManagers = sslConfiguration.getKeyStore() != null ? createKeyManagerFactory(
diff --git a/spring-vault-core/src/main/java/org/springframework/vault/config/EnvironmentVaultConfiguration.java b/spring-vault-core/src/main/java/org/springframework/vault/config/EnvironmentVaultConfiguration.java
new file mode 100644
index 00000000..a21c70b6
--- /dev/null
+++ b/spring-vault-core/src/main/java/org/springframework/vault/config/EnvironmentVaultConfiguration.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.vault.config;
+
+import java.net.URI;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.springframework.vault.authentication.AppIdAuthentication;
+import org.springframework.vault.authentication.AppIdAuthenticationOptions;
+import org.springframework.vault.authentication.AppIdUserIdMechanism;
+import org.springframework.vault.authentication.AppRoleAuthentication;
+import org.springframework.vault.authentication.AppRoleAuthenticationOptions;
+import org.springframework.vault.authentication.AwsEc2Authentication;
+import org.springframework.vault.authentication.AwsEc2AuthenticationOptions;
+import org.springframework.vault.authentication.AwsEc2AuthenticationOptions.AwsEc2AuthenticationOptionsBuilder;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.authentication.ClientCertificateAuthentication;
+import org.springframework.vault.authentication.CubbyholeAuthentication;
+import org.springframework.vault.authentication.CubbyholeAuthenticationOptions;
+import org.springframework.vault.authentication.IpAddressUserId;
+import org.springframework.vault.authentication.MacAddressUserId;
+import org.springframework.vault.authentication.StaticUserId;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.client.VaultEndpoint;
+import org.springframework.vault.support.SslConfiguration;
+import org.springframework.vault.support.VaultToken;
+import org.springframework.web.client.RestOperations;
+
+/**
+ * Configuration using Spring's {@link org.springframework.core.env.Environment} to
+ * configure Spring Vault endpoint, SSL options and authentication options. This
+ * configuration class uses predefined property keys and is usually imported as part of an
+ * existing Java-based configuration. Configuration is obtained from other, existing
+ * property sources.
+ *
+ * Usage:
+ *
+ * Java-based configuration part:
+ *
+ *
+ *
+ * @Configuration
+ * @Import(EnvironmentVaultConfiguration.class)
+ * public class MyConfiguration {
+ * }
+ *
+ *
+ *
+ * Supplied properties:
+ *
+ *
+ *
+ * vault.uri=https://localhost:8200
+ * vault.token=00000000-0000-0000-0000-000000000000
+ *
+ *
+ *
+ * Property keys
+ *
+ * Authentication-specific properties must be provided depending on the authentication
+ * method.
+ *
+ * - Vault URI: {@code vault.uri}
+ * - SSL Configuration
+ *
+ * - Keystore resource: {@code vault.ssl.key-store} (optional)
+ * - Keystore password: {@code vault.ssl.key-store-password} (optional)
+ * - Truststore resource: {@code vault.ssl.trust-store} (optional)
+ * - Truststore password: {@code vault.ssl.trust-store-password} (optional)
+ *
+ *
+ * - Authentication method: {@code vault.authentication} (defaults to {@literal TOKEN},
+ * supported authentication methods are:
+ * {@literal TOKEN, APPID, APPROLE, AWS_EC2, CERT, CUBBYHOLE})
+ * - Token authentication
+ *
+ * - Vault Token: {@code vault.token}
+ *
+ * - AppId authentication
+ *
+ * - AppId: {@code vault.app-id.app-id}
+ * - UserId: {@code vault.app-id.user-id}. {@literal MAC_ADDRESS} and
+ * {@literal IP_ADDRESS} use {@link MacAddressUserId}, respective {@link IpAddressUserId}.
+ * Any other value is used with {@link StaticUserId}.
+ *
+ * - AppRole authentication
+ *
+ * - RoleId: {@code vault.app-role.role-id}
+ * - SecretId: {@code vault.app-role.secret-id} (optional)
+ *
+ * - AWS EC2 authentication
+ *
+ * - RoleId: {@code vault.aws-ec2.role-id}
+ * - Identity Document URL: {@code vault.aws-ec2.identity-document} (optional)
+ *
+ * - Client Certificate authentication
+ *
+ * - (no configuration options)
+ *
+ * - Cubbyhole authentication
+ *
+ * - Initial Vault Token: {@code vault.token}
+ *
+ *
+ *
+ * @author Mark Paluch
+ * @see org.springframework.core.env.Environment
+ * @see org.springframework.core.env.PropertySource
+ * @see VaultEndpoint
+ * @see AppIdAuthentication
+ * @see AppRoleAuthentication
+ * @see AwsEc2Authentication
+ * @see ClientCertificateAuthentication
+ * @see CubbyholeAuthentication
+ */
+@Configuration
+public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration
+ implements ApplicationContextAware {
+
+ private RestOperations cachedRestOperations;
+ private ApplicationContext applicationContext;
+
+ @Override
+ public RestOperations restOperations() {
+
+ if (this.cachedRestOperations != null) {
+ return this.cachedRestOperations;
+ }
+
+ this.cachedRestOperations = super.restOperations();
+ return this.cachedRestOperations;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+
+ this.applicationContext = applicationContext;
+ super.setApplicationContext(applicationContext);
+ }
+
+ @Override
+ public VaultEndpoint vaultEndpoint() {
+
+ String uri = getProperty("vault.uri");
+ if (uri != null) {
+ return VaultEndpoint.from(URI.create(uri));
+ }
+
+ throw new IllegalStateException("Vault URI (vault.uri) is null");
+ }
+
+ @Override
+ public SslConfiguration sslConfiguration() {
+
+ Resource keyStore = getResource("vault.ssl.key-store");
+ String keyStorePassword = getProperty("vault.ssl.key-store-password");
+ Resource trustStore = getResource("vault.ssl.trust-store");
+ String trustStorePassword = getProperty("vault.ssl.trust-store-password");
+
+ return new SslConfiguration(keyStore, keyStorePassword, trustStore,
+ trustStorePassword);
+ }
+
+ @Override
+ public ClientAuthentication clientAuthentication() {
+
+ String authentication = getEnvironment()
+ .getProperty("vault.authentication", AuthenticationMethod.TOKEN.name())
+ .toUpperCase().replace('-', '_');
+
+ AuthenticationMethod authenticationMethod = AuthenticationMethod
+ .valueOf(authentication);
+
+ switch (authenticationMethod) {
+
+ case TOKEN:
+ return tokenAuthentication();
+ case APPID:
+ return appIdAuthentication();
+ case APPROLE:
+ return appRoleAuthentication();
+ case AWS_EC2:
+ return awsEc2Authentication();
+ case CERT:
+ return new ClientCertificateAuthentication(restOperations());
+ case CUBBYHOLE:
+ return cubbyholeAuthentication();
+
+ default:
+ throw new IllegalStateException(String.format(
+ "Vault authentication method %s is not supported with %s",
+ authenticationMethod, getClass().getSimpleName()));
+ }
+ }
+
+ // -------------------------------------------------------------------------
+ // Implementation hooks and helper methods
+ // -------------------------------------------------------------------------
+
+ protected ClientAuthentication tokenAuthentication() {
+
+ String token = getProperty("vault.token");
+ Assert.hasText(token,
+ "Vault Token authentication: Token (vault.token) must not be empty");
+
+ return new TokenAuthentication(token);
+ }
+
+ protected ClientAuthentication appIdAuthentication() {
+
+ String appId = getEnvironment().getProperty("vault.app-id.app-id",
+ getProperty("spring.application.name"));
+ String userId = getProperty("vault.app-id.user-id");
+
+ Assert.hasText(appId,
+ "Vault AppId authentication: AppId (vault.app-id.app-id) must not be empty");
+ Assert.hasText(userId,
+ "Vault AppId authentication: UserId (vault.app-id.user-id) must not be empty");
+
+ AppIdAuthenticationOptions authenticationOptions = AppIdAuthenticationOptions
+ .builder().appId(appId) //
+ .userIdMechanism(getAppIdUserIdMechanism(userId)).build();
+
+ return new AppIdAuthentication(authenticationOptions, restOperations());
+ }
+
+ protected ClientAuthentication appRoleAuthentication() {
+
+ String roleId = getProperty("vault.app-role.role-id");
+ String secretId = getProperty("vault.app-role.secret-id");
+ Assert.hasText(roleId,
+ "Vault AppRole authentication: RoleId (vault.app-role.role-id) must not be empty");
+
+ AppRoleAuthenticationOptions.AppRoleAuthenticationOptionsBuilder builder = AppRoleAuthenticationOptions
+ .builder().roleId(roleId);
+
+ if (StringUtils.hasText(secretId)) {
+ builder = builder.secretId(secretId);
+ }
+
+ return new AppRoleAuthentication(builder.build(), restOperations());
+ }
+
+ protected AppIdUserIdMechanism getAppIdUserIdMechanism(String userId) {
+
+ if (userId.equalsIgnoreCase(AppIdUserId.IP_ADDRESS.name())) {
+ return new IpAddressUserId();
+ }
+
+ if (userId.equalsIgnoreCase(AppIdUserId.MAC_ADDRESS.name())) {
+ return new MacAddressUserId();
+ }
+
+ return new StaticUserId(userId);
+ }
+
+ protected ClientAuthentication awsEc2Authentication() {
+
+ String roleId = getProperty("vault.aws-ec2.role-id");
+ String identityDocument = getProperty("vault.aws-ec2.identity-document");
+ Assert.hasText(roleId,
+ "Vault AWS EC2 authentication: RoleId (vault.aws-ec2.role-id) must not be empty");
+
+ AwsEc2AuthenticationOptionsBuilder builder = AwsEc2AuthenticationOptions.builder()
+ .role(roleId);
+
+ if (StringUtils.hasText(identityDocument)) {
+ builder.identityDocumentUri(URI.create(identityDocument));
+ }
+
+ return new AwsEc2Authentication(builder.build(), restOperations(),
+ restOperations());
+ }
+
+ protected ClientAuthentication cubbyholeAuthentication() {
+
+ String token = getProperty("vault.token");
+ Assert.hasText(token,
+ "Vault Cubbyhole authentication: Initial token (vault.token) must not be empty");
+
+ CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions.builder() //
+ .wrapped() //
+ .initialToken(VaultToken.of(token)) //
+ .build();
+
+ return new CubbyholeAuthentication(options, restOperations());
+ }
+
+ private String getProperty(String key) {
+ return getEnvironment().getProperty(key);
+ }
+
+ private Resource getResource(String key) {
+
+ String value = getProperty(key);
+ return value != null ? applicationContext.getResource(value) : null;
+ }
+
+ enum AppIdUserId {
+ IP_ADDRESS, MAC_ADDRESS;
+ }
+
+ enum AuthenticationMethod {
+ TOKEN, APPID, APPROLE, AWS_EC2, CERT, CUBBYHOLE;
+ }
+}
diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppIdAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppIdAuthenticationUnitTests.java
new file mode 100644
index 00000000..ee3f7c32
--- /dev/null
+++ b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppIdAuthenticationUnitTests.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.vault.config;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.vault.authentication.AppIdAuthentication;
+import org.springframework.vault.authentication.ClientAuthentication;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Unit tests for {@link EnvironmentVaultConfiguration} with AppId authentication.
+ *
+ * @author Mark Paluch
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(properties = { "vault.uri=https://localhost:8123",
+ "vault.authentication=appid", "vault.app-id.user-id=IP_ADDRESS",
+ "vault.app-id.app-id=foo" })
+public class EnvironmentVaultConfigurationAppIdAuthenticationUnitTests {
+
+ @Configuration
+ @Import(EnvironmentVaultConfiguration.class)
+ static class ApplicationConfiguration {
+ }
+
+ @Autowired
+ private EnvironmentVaultConfiguration configuration;
+
+ @Test
+ public void shouldConfigureAuthentication() {
+
+ ClientAuthentication clientAuthentication = configuration.clientAuthentication();
+
+ assertThat(clientAuthentication).isInstanceOf(AppIdAuthentication.class);
+ }
+}
diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppRoleAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppRoleAuthenticationUnitTests.java
new file mode 100644
index 00000000..efb5c667
--- /dev/null
+++ b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAppRoleAuthenticationUnitTests.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.vault.config;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.vault.authentication.AppRoleAuthentication;
+import org.springframework.vault.authentication.ClientAuthentication;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Unit tests for {@link EnvironmentVaultConfiguration} with AppRole authentication.
+ *
+ * @author Mark Paluch
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(properties = { "vault.uri=https://localhost:8123",
+ "vault.authentication=approle", "vault.app-role.role-id=role",
+ "vault.app-role.secret-id=foo" })
+public class EnvironmentVaultConfigurationAppRoleAuthenticationUnitTests {
+
+ @Configuration
+ @Import(EnvironmentVaultConfiguration.class)
+ static class ApplicationConfiguration {
+ }
+
+ @Autowired
+ private EnvironmentVaultConfiguration configuration;
+
+ @Test
+ public void shouldConfigureAuthentication() {
+
+ ClientAuthentication clientAuthentication = configuration.clientAuthentication();
+
+ assertThat(clientAuthentication).isInstanceOf(AppRoleAuthentication.class);
+ }
+}
diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAwsEc2AuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAwsEc2AuthenticationUnitTests.java
new file mode 100644
index 00000000..efa11456
--- /dev/null
+++ b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationAwsEc2AuthenticationUnitTests.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.vault.config;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.vault.authentication.AwsEc2Authentication;
+import org.springframework.vault.authentication.ClientAuthentication;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Unit tests for {@link EnvironmentVaultConfiguration} with AppRole authentication.
+ *
+ * @author Mark Paluch
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(properties = { "vault.uri=https://localhost:8123",
+ "vault.authentication=aws-ec2", "vault.aws-ec2.role-id=role" })
+public class EnvironmentVaultConfigurationAwsEc2AuthenticationUnitTests {
+
+ @Configuration
+ @Import(EnvironmentVaultConfiguration.class)
+ static class ApplicationConfiguration {
+ }
+
+ @Autowired
+ private EnvironmentVaultConfiguration configuration;
+
+ @Test
+ public void shouldConfigureAuthentication() {
+
+ ClientAuthentication clientAuthentication = configuration.clientAuthentication();
+
+ assertThat(clientAuthentication).isInstanceOf(AwsEc2Authentication.class);
+ }
+}
diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationClientCertAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationClientCertAuthenticationUnitTests.java
new file mode 100644
index 00000000..683dca9a
--- /dev/null
+++ b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationClientCertAuthenticationUnitTests.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.vault.config;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.authentication.ClientCertificateAuthentication;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Unit tests for {@link EnvironmentVaultConfiguration} with AppRole authentication.
+ *
+ * @author Mark Paluch
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(properties = { "vault.uri=https://localhost:8123",
+ "vault.authentication=cert", "vault.aws-ec2.role-id=role" })
+public class EnvironmentVaultConfigurationClientCertAuthenticationUnitTests {
+
+ @Configuration
+ @Import(EnvironmentVaultConfiguration.class)
+ static class ApplicationConfiguration {
+ }
+
+ @Autowired
+ private EnvironmentVaultConfiguration configuration;
+
+ @Test
+ public void shouldConfigureAuthentication() {
+
+ ClientAuthentication clientAuthentication = configuration.clientAuthentication();
+
+ assertThat(clientAuthentication)
+ .isInstanceOf(ClientCertificateAuthentication.class);
+ }
+}
diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationCubbyholeAuthenticationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationCubbyholeAuthenticationUnitTests.java
new file mode 100644
index 00000000..e9ebf473
--- /dev/null
+++ b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationCubbyholeAuthenticationUnitTests.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.vault.config;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.authentication.CubbyholeAuthentication;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Unit tests for {@link EnvironmentVaultConfiguration} with AppRole authentication.
+ *
+ * @author Mark Paluch
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(properties = { "vault.uri=https://localhost:8123",
+ "vault.authentication=cubbyhole", "vault.token=my-token" })
+public class EnvironmentVaultConfigurationCubbyholeAuthenticationUnitTests {
+
+ @Configuration
+ @Import(EnvironmentVaultConfiguration.class)
+ static class ApplicationConfiguration {
+ }
+
+ @Autowired
+ private EnvironmentVaultConfiguration configuration;
+
+ @Test
+ public void shouldConfigureAuthentication() {
+
+ ClientAuthentication clientAuthentication = configuration.clientAuthentication();
+
+ assertThat(clientAuthentication).isInstanceOf(CubbyholeAuthentication.class);
+ }
+}
diff --git a/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationUnitTests.java b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationUnitTests.java
new file mode 100644
index 00000000..eef1db6b
--- /dev/null
+++ b/spring-vault-core/src/test/java/org/springframework/vault/config/EnvironmentVaultConfigurationUnitTests.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.vault.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.vault.authentication.ClientAuthentication;
+import org.springframework.vault.authentication.TokenAuthentication;
+import org.springframework.vault.support.SslConfiguration;
+import org.springframework.vault.support.VaultToken;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Unit tests for {@link EnvironmentVaultConfiguration}.
+ *
+ * @author Mark Paluch
+ */
+@RunWith(SpringRunner.class)
+@TestPropertySource(properties = { "vault.uri=https://localhost:8123",
+ "vault.token=my-token", "vault.ssl.key-store-password=key store password",
+ "vault.ssl.trust-store-password=trust store password" })
+public class EnvironmentVaultConfigurationUnitTests {
+
+ @Configuration
+ @Import(EnvironmentVaultConfiguration.class)
+ static class ApplicationConfiguration {
+ }
+
+ @Autowired
+ private EnvironmentVaultConfiguration configuration;
+
+ @Autowired
+ private ConfigurableEnvironment configurableEnvironment;
+
+ @Test
+ public void shouldConfigureEndpoint() {
+ assertThat(configuration.vaultEndpoint().getPort()).isEqualTo(8123);
+ }
+
+ @Test
+ public void shouldConfigureTokenAuthentication() {
+
+ ClientAuthentication clientAuthentication = configuration.clientAuthentication();
+
+ assertThat(clientAuthentication).isInstanceOf(TokenAuthentication.class);
+ assertThat(clientAuthentication.login()).isEqualTo(VaultToken.of("my-token"));
+ }
+
+ @Test
+ public void shouldConfigureSsl() {
+
+ Map map = new HashMap();
+ map.put("vault.ssl.key-store", "http://foo.bar");
+ map.put("vault.ssl.trust-store", "classpath:certificate.json");
+
+ MapPropertySource propertySource = new MapPropertySource("shouldConfigureSsl",
+ map);
+ configurableEnvironment.getPropertySources().addFirst(propertySource);
+
+ SslConfiguration sslConfiguration = configuration.sslConfiguration();
+
+ assertThat(sslConfiguration.getKeyStore()).isInstanceOf(UrlResource.class);
+ assertThat(sslConfiguration.getKeyStorePassword())
+ .isEqualTo("key store password");
+
+ assertThat(sslConfiguration.getTrustStore())
+ .isInstanceOf(ClassPathResource.class);
+ assertThat(sslConfiguration.getTrustStorePassword())
+ .isEqualTo("trust store password");
+
+ configurableEnvironment.getPropertySources().remove(propertySource.getName());
+ }
+}
diff --git a/src/main/asciidoc/reference/getting-started.adoc b/src/main/asciidoc/reference/getting-started.adoc
index 23b30efd..e9d36897 100644
--- a/src/main/asciidoc/reference/getting-started.adoc
+++ b/src/main/asciidoc/reference/getting-started.adoc
@@ -261,6 +261,11 @@ public class AppConfig extends AbstractVaultConfiguration {
`AbstractVaultConfiguration` or provided by your configuration.
====
+NOTE: Creating a custom configuration class might be cumbersome in some cases.
+Take a look at `EnvironmentVaultConfiguration` that allows configuration by using
+properties from existing property sources and Spring's `Environment`. Read more
+in <>.
+
[[vault.core.template.sessionmanagement]]
=== Session Management
@@ -309,6 +314,75 @@ Please note that providing `SslConfiguration` can be only
applied when either Apache Http Components or the OkHttp client
is on your class-path.
+
+[[vault.core.environment-vault-configuration]]
+== Using `EnvironmentVaultConfiguration`
+
+Spring Vault includes `EnvironmentVaultConfiguration` configure the Vault client from Spring's `Environment` and a set of predefined
+property keys. `EnvironmentVaultConfiguration` supports frequently applied configurations. Other configurations are supported by deriving from the most appropriate configuration class. Include `EnvironmentVaultConfiguration` with `@Import(EnvironmentVaultConfiguration.class)` to existing
+Java-based configuration classes and supply configuration properties through any of Spring's ``PropertySource``s.
+
+.Using EnvironmentVaultConfiguration with a property file
+====
+
+.Java-based configuration class
+[source,java]
+----
+@PropertySource("vault.properties")
+@Import(EnvironmentVaultConfiguration.class)
+public class MyConfiguration{
+}
+----
+
+.vault.properties
+[source,properties]
+----
+vault.uri=https://localhost:8200
+vault.token=00000000-0000-0000-0000-000000000000
+----
+====
+
+**Property keys**
+
+* Vault URI: `vault.uri`
+* SSL Configuration
+ ** Keystore resource: `vault.ssl.key-store` (optional)
+ ** Keystore password: `vault.ssl.key-store-password` (optional)
+ ** Truststore resource: `vault.ssl.trust-store` (optional)
+ ** Truststore password: `vault.ssl.trust-store-password` (optional)
+* Authentication method: `vault.authentication` (defaults to `TOKEN`, supported authentication methods are: `TOKEN`, `APPID`, `APPROLE`, `AWS_EC2`, `CERT`, `CUBBYHOLE`)
+
+
+**Authentication-specific property keys**
+
+**<>**
+
+* Vault Token: `vault.token`
+
+**<>**
+
+* AppId: `vault.app-id.app-id`
+* UserId: `vault.app-id.user-id`. `MAC_ADDRESS` and `IP_ADDRESS` use `MacAddressUserId`, respective `IpAddressUserId` user id mechanisms. Any other value is used with `StaticUserId`.
+
+**<>**
+
+* RoleId: `vault.app-role.role-id`
+* SecretId: `vault.app-role.secret-id` (optional)
+
+**<>**
+
+* RoleId: `vault.aws-ec2.role-id`
+* Identity Document URL: `vault.aws-ec2.identity-document` (optional)
+
+**<>**
+
+No configuration options.
+
+**<>**
+
+* Initial Vault Token: `vault.token`
+
+
[[vault.core.propertysupport]]
== Vault Property Source Support