Add property to disable adding invalid prefix when decryption fails (#2708)
Fixes #2632 Signed-off-by: Ryan Baxter <ryan.baxter@broadcom.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.config.server.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -44,6 +45,9 @@ import org.springframework.security.crypto.encrypt.TextEncryptor;
|
||||
@AutoConfigureAfter(DefaultTextEncryptionAutoConfiguration.class)
|
||||
public class EncryptionAutoConfiguration {
|
||||
|
||||
@Value("${spring.cloud.config.server.encrypt.prefixInvalidProperties:${spring.cloud.config.server.encrypt.prefix-invalid-properties:true}}")
|
||||
private boolean prefixInvalidProperties;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(TextEncryptor.class)
|
||||
@ConditionalOnMissingBean(TextEncryptorLocator.class)
|
||||
@@ -60,7 +64,9 @@ public class EncryptionAutoConfiguration {
|
||||
if (locator == null) {
|
||||
locator = new SingleTextEncryptorLocator(encryptor);
|
||||
}
|
||||
return new CipherEnvironmentEncryptor(locator);
|
||||
CipherEnvironmentEncryptor environmentEncryptor = new CipherEnvironmentEncryptor(locator);
|
||||
environmentEncryptor.setPrefixInvalidProperties(prefixInvalidProperties);
|
||||
return environmentEncryptor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.config.server.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.cloud.config.server.encryption.vault.VaultEnvironmentEncryptor;
|
||||
import org.springframework.cloud.config.server.environment.vault.SpringVaultEnvironmentRepository;
|
||||
@@ -34,10 +35,16 @@ import org.springframework.vault.core.VaultTemplate;
|
||||
@Profile("vault")
|
||||
public class VaultEncryptionAutoConfiguration {
|
||||
|
||||
@Value("${spring.cloud.config.server.encrypt.prefixInvalidProperties:${spring.cloud.config.server.encrypt.prefix-invalid-properties:true}}")
|
||||
private boolean prefixInvalidProperties;
|
||||
|
||||
@Bean
|
||||
public VaultEnvironmentEncryptor vaultEnvironmentEncryptor(
|
||||
SpringVaultEnvironmentRepository vaultEnvironmentRepository) {
|
||||
return new VaultEnvironmentEncryptor(vaultEnvironmentRepository.getKeyValueTemplate());
|
||||
VaultEnvironmentEncryptor vaultEnvironmentEncryptor = new VaultEnvironmentEncryptor(
|
||||
vaultEnvironmentRepository.getKeyValueTemplate());
|
||||
vaultEnvironmentEncryptor.setPrefixInvalidProperties(this.prefixInvalidProperties);
|
||||
return vaultEnvironmentEncryptor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ public class CipherEnvironmentEncryptor implements EnvironmentEncryptor {
|
||||
|
||||
private final TextEncryptorLocator encryptor;
|
||||
|
||||
private boolean prefixInvalidProperties = true;
|
||||
|
||||
private EnvironmentPrefixHelper helper = new EnvironmentPrefixHelper();
|
||||
|
||||
@Autowired
|
||||
@@ -74,8 +76,10 @@ public class CipherEnvironmentEncryptor implements EnvironmentEncryptor {
|
||||
.decrypt(this.helper.stripPrefix(value));
|
||||
}
|
||||
catch (Exception e) {
|
||||
value = "<n/a>";
|
||||
name = "invalid." + name;
|
||||
if (this.prefixInvalidProperties) {
|
||||
value = "<n/a>";
|
||||
name = "invalid." + name;
|
||||
}
|
||||
String message = "Cannot decrypt key: " + key + " (" + e.getClass() + ": " + e.getMessage()
|
||||
+ ")";
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -93,4 +97,8 @@ public class CipherEnvironmentEncryptor implements EnvironmentEncryptor {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setPrefixInvalidProperties(boolean prefixInvalidProperties) {
|
||||
this.prefixInvalidProperties = prefixInvalidProperties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ public class VaultEnvironmentEncryptor implements EnvironmentEncryptor {
|
||||
|
||||
private final VaultKeyValueOperations keyValueTemplate;
|
||||
|
||||
private boolean prefixInvalidProperties = true;
|
||||
|
||||
public VaultEnvironmentEncryptor(VaultKeyValueOperations keyValueTemplate) {
|
||||
this.keyValueTemplate = keyValueTemplate;
|
||||
}
|
||||
@@ -102,8 +104,10 @@ public class VaultEnvironmentEncryptor implements EnvironmentEncryptor {
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
value = "<n/a>";
|
||||
name = "invalid." + name;
|
||||
if (this.prefixInvalidProperties) {
|
||||
value = "<n/a>";
|
||||
name = "invalid." + name;
|
||||
}
|
||||
String message = "Cannot resolve key: " + key + " (" + e.getClass() + ": " + e.getMessage()
|
||||
+ ")";
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -121,4 +125,8 @@ public class VaultEnvironmentEncryptor implements EnvironmentEncryptor {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setPrefixInvalidProperties(boolean prefixInvalidProperties) {
|
||||
this.prefixInvalidProperties = prefixInvalidProperties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,4 +119,55 @@ public class CipherEnvironmentEncryptorTests {
|
||||
.isEqualTo(secret);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("params")
|
||||
public void shouldDecryptFailed(String salt, String key) {
|
||||
TextEncryptor textEncryptor = new EncryptorFactory(salt).create(key);
|
||||
CipherEnvironmentEncryptor encryptor = new CipherEnvironmentEncryptor(keys -> textEncryptor);
|
||||
encryptor.setPrefixInvalidProperties(true);
|
||||
// given
|
||||
String secret = randomUUID().toString();
|
||||
|
||||
// when
|
||||
Environment environment = new Environment("name", "profile", "label");
|
||||
String encrypted = "{cipher}" + new EncryptorFactory(salt).create("dummykey").encrypt(secret);
|
||||
environment.add(new PropertySource("a", Collections.<Object, Object>singletonMap(environment.getName(),
|
||||
new PropertyValueDescriptor(encrypted, "encrypted value"))));
|
||||
|
||||
// then
|
||||
assertThat(encryptor.decrypt(environment)
|
||||
.getPropertySources()
|
||||
.get(0)
|
||||
.getSource()
|
||||
.get("invalid." + environment.getName())).isEqualTo("<n/a>");
|
||||
assertThat(encryptor.decrypt(environment).getPropertySources().get(0).getSource().get(environment.getName()))
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("params")
|
||||
public void decryptFailedWithoutInvalidPrefix(String salt, String key) {
|
||||
TextEncryptor textEncryptor = new EncryptorFactory(salt).create(key);
|
||||
CipherEnvironmentEncryptor encryptor = new CipherEnvironmentEncryptor(keys -> textEncryptor);
|
||||
encryptor.setPrefixInvalidProperties(false);
|
||||
// given
|
||||
String secret = randomUUID().toString();
|
||||
|
||||
// when
|
||||
Environment environment = new Environment("name", "profile", "label");
|
||||
String encryptedSecret = new EncryptorFactory(salt).create("dummykey").encrypt(secret);
|
||||
String encrypted = "{cipher}" + encryptedSecret;
|
||||
environment.add(new PropertySource("a", Collections.<Object, Object>singletonMap(environment.getName(),
|
||||
new PropertyValueDescriptor(encrypted, "encrypted value"))));
|
||||
|
||||
// then
|
||||
assertThat(encryptor.decrypt(environment)
|
||||
.getPropertySources()
|
||||
.get(0)
|
||||
.getSource()
|
||||
.get("invalid." + environment.getName())).isNull();
|
||||
assertThat(encryptor.decrypt(environment).getPropertySources().get(0).getSource().get(environment.getName()))
|
||||
.isEqualTo(encryptedSecret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,6 +117,31 @@ public class VaultEnvironmentEncryptorTests {
|
||||
.isEqualTo("<n/a>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotPrefixInvalidPropertyWithNoKeyValue() {
|
||||
// given
|
||||
String accounts = "accounts/mypay";
|
||||
String value = "{vault}:" + accounts;
|
||||
|
||||
VaultKeyValueOperations keyValueTemplate = mock(VaultKeyValueOperations.class);
|
||||
|
||||
VaultEnvironmentEncryptor encryptor = new VaultEnvironmentEncryptor(keyValueTemplate);
|
||||
encryptor.setPrefixInvalidProperties(false);
|
||||
|
||||
// when
|
||||
Environment environment = new Environment("name", "profile", "label");
|
||||
environment
|
||||
.add(new PropertySource("a", Collections.<Object, Object>singletonMap(environment.getName(), value)));
|
||||
|
||||
// then
|
||||
Environment processedEnvironment = encryptor.decrypt(environment);
|
||||
|
||||
assertThat(processedEnvironment.getPropertySources().get(0).getSource().get("invalid." + environment.getName()))
|
||||
.isNull();
|
||||
assertThat(processedEnvironment.getPropertySources().get(0).getSource().get(environment.getName()))
|
||||
.isEqualTo(accounts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMarkAsInvalidPropertyWithNoEmptyValue() {
|
||||
// given
|
||||
|
||||
Reference in New Issue
Block a user