Allow fallback to ~/.vault-token file using Token authentication.

This assists in usability of spring cloud vault locally after authenticating to vault via the vault CLI.

Closes gh-609
Original pull request: gh-614
This commit is contained in:
Brant
2021-09-27 09:05:59 -04:00
committed by Mark Paluch
parent e016c1b6a8
commit 08577ad56a
2 changed files with 38 additions and 4 deletions

View File

@@ -11,6 +11,7 @@ Spring Cloud Vault supports token and AppId authentication.
Tokens are the core method for authentication within Vault.
Token authentication requires a static token to be provided using the
https://github.com/spring-cloud/spring-cloud-commons/blob/master/docs/src/main/asciidoc/spring-cloud-commons.adoc#the-bootstrap-application-context[Bootstrap Application Context].
As a fallback the token may also be retrieved from ~/.vault-token which is the default location used by the Vault CLI to cache a token.
NOTE: Token authentication is the default authentication method.
If a token is disclosed an unintended party gains access to Vault and can access secrets for the intended client.
@@ -26,9 +27,13 @@ spring.cloud.vault:
====
* `authentication` setting this value to `TOKEN` selects the Token authentication method
* `token` sets the static token to use
* `token` sets the static token to use. If missing or empty, then an attempt will be made to retrieve a token from ~/.vault-token.
See also: https://www.vaultproject.io/docs/concepts/tokens.html[Vault Documentation: Tokens]
See also:
* https://www.vaultproject.io/docs/concepts/tokens.html[Vault Documentation: Tokens]
* https://www.vaultproject.io/docs/commands/login[Vault Documentation: CLI login]
* https://www.vaultproject.io/docs/commands/token-helper[Vault Documentation: CLI default to ~/.vault-token]
[[vault.config.authentication.vault-agent]]
=== Vault Agent authentication

View File

@@ -16,6 +16,11 @@
package org.springframework.cloud.vault.config;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicReference;
import com.amazonaws.auth.AWSCredentials;
@@ -28,6 +33,7 @@ import org.springframework.cloud.vault.config.VaultProperties.AwsIamProperties;
import org.springframework.cloud.vault.config.VaultProperties.AzureMsiProperties;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import org.springframework.vault.authentication.AppIdAuthentication;
import org.springframework.vault.authentication.AppIdAuthenticationOptions;
@@ -66,6 +72,8 @@ import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.support.VaultToken;
import org.springframework.web.client.RestOperations;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Factory for {@link ClientAuthentication}.
*
@@ -138,8 +146,7 @@ class ClientAuthenticationFactory {
return pcfAuthentication(this.vaultProperties);
case TOKEN:
Assert.hasText(this.vaultProperties.getToken(), "Token (spring.cloud.vault.token) must not be empty");
return new TokenAuthentication(this.vaultProperties.getToken());
return tokenAuthentication(this.vaultProperties);
}
throw new UnsupportedOperationException(
@@ -398,6 +405,28 @@ class ClientAuthenticationFactory {
return new ClientCertificateAuthentication(options, this.restOperations);
}
private ClientAuthentication tokenAuthentication(VaultProperties vaultProperties) {
if (StringUtils.hasText(vaultProperties.getToken())) {
return new TokenAuthentication(vaultProperties.getToken());
}
else {
Path vaultTokenPath = Paths.get(System.getProperty("user.home"), ".vault-token");
if (Files.exists(vaultTokenPath)) {
try (InputStream inputStream = Files.newInputStream(vaultTokenPath)) {
String token = StreamUtils.copyToString(inputStream, UTF_8);
return new TokenAuthentication(token);
}
catch (IOException ex) {
throw new IllegalStateException("Could not retrieve vault token from ~/.vault-token", ex);
}
}
else {
throw new IllegalStateException(
"Cannot create authentication mechanism for TOKEN. This method requires either a Token (spring.cloud.vault.token) or File ~/.vault-token.");
}
}
}
private static class AwsCredentialProvider {
private static AWSCredentialsProvider getAwsCredentialsProvider() {