Simplify encryption autoconfig (#2065)
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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
|
||||
*
|
||||
* https://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.cloud.config.server.config;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
|
||||
import org.springframework.cloud.config.server.encryption.LocatorTextEncryptor;
|
||||
import org.springframework.cloud.config.server.encryption.TextEncryptorLocator;
|
||||
import org.springframework.cloud.context.encrypt.EncryptorFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.encrypt.Encryptors;
|
||||
import org.springframework.security.crypto.encrypt.TextEncryptor;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default text encryption auto-configuration.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 3.1.2
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureAfter(RsaEncryptionAutoConfiguration.class)
|
||||
@EnableConfigurationProperties
|
||||
public class DefaultTextEncryptionAutoConfiguration {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(DefaultTextEncryptionAutoConfiguration.class);
|
||||
|
||||
@Autowired
|
||||
ApplicationContext context;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public KeyProperties keyProperties() {
|
||||
return new KeyProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(TextEncryptor.class)
|
||||
@ConditionalOnBean(TextEncryptorLocator.class)
|
||||
public TextEncryptor defaultLocatorBasedTextEncryptor(TextEncryptorLocator locator) {
|
||||
return new LocatorTextEncryptor(locator);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(TextEncryptor.class)
|
||||
public TextEncryptor defaultTextEncryptor(KeyProperties key) {
|
||||
if (StringUtils.hasText(key.getKey())) {
|
||||
return new EncryptorFactory(key.getSalt()).create(key.getKey());
|
||||
}
|
||||
return Encryptors.noOpText();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,33 +17,20 @@
|
||||
package org.springframework.cloud.config.server.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
|
||||
import org.springframework.cloud.bootstrap.encrypt.KeyProperties.KeyStore;
|
||||
import org.springframework.cloud.bootstrap.encrypt.RsaProperties;
|
||||
import org.springframework.cloud.config.server.encryption.CipherEnvironmentEncryptor;
|
||||
import org.springframework.cloud.config.server.encryption.EnvironmentEncryptor;
|
||||
import org.springframework.cloud.config.server.encryption.KeyStoreTextEncryptorLocator;
|
||||
import org.springframework.cloud.config.server.encryption.LocatorTextEncryptor;
|
||||
import org.springframework.cloud.config.server.encryption.SingleTextEncryptorLocator;
|
||||
import org.springframework.cloud.config.server.encryption.TextEncryptorLocator;
|
||||
import org.springframework.cloud.context.encrypt.EncryptorFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.crypto.encrypt.Encryptors;
|
||||
import org.springframework.security.crypto.encrypt.TextEncryptor;
|
||||
import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
|
||||
import org.springframework.security.rsa.crypto.RsaAlgorithm;
|
||||
import org.springframework.security.rsa.crypto.RsaSecretEncryptor;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Auto configuration for text encryptors and environment encryptors (non-web stuff).
|
||||
* Auto-configuration for text encryptors and environment encryptors (non-web stuff).
|
||||
* Users can provide beans of the same type as any or all of the beans defined here in
|
||||
* application code to override the default behaviour.
|
||||
*
|
||||
@@ -54,14 +41,14 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties
|
||||
@Import(SingleTextEncryptorConfiguration.class)
|
||||
@AutoConfigureAfter(DefaultTextEncryptionAutoConfiguration.class)
|
||||
public class EncryptionAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public KeyProperties keyProperties() {
|
||||
return new KeyProperties();
|
||||
@ConditionalOnBean(TextEncryptor.class)
|
||||
@ConditionalOnMissingBean(TextEncryptorLocator.class)
|
||||
public SingleTextEncryptorLocator singleTextEncryptorLocator(TextEncryptor encryptor) {
|
||||
return new SingleTextEncryptorLocator(encryptor);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -76,57 +63,4 @@ public class EncryptionAutoConfiguration {
|
||||
return new CipherEnvironmentEncryptor(locator);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(TextEncryptor.class)
|
||||
public TextEncryptor defaultTextEncryptor(@Autowired(required = false) TextEncryptorLocator locator,
|
||||
KeyProperties key) {
|
||||
if (locator != null) {
|
||||
return new LocatorTextEncryptor(locator);
|
||||
}
|
||||
if (StringUtils.hasText(key.getKey())) {
|
||||
return new EncryptorFactory(key.getSalt()).create(key.getKey());
|
||||
}
|
||||
return Encryptors.noOpText();
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(RsaSecretEncryptor.class)
|
||||
@ConditionalOnProperty(prefix = "encrypt.key-store", value = "location", matchIfMissing = false)
|
||||
protected static class KeyStoreConfiguration {
|
||||
|
||||
@Autowired
|
||||
private KeyProperties key;
|
||||
|
||||
@Autowired
|
||||
private RsaProperties rsaProperties;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TextEncryptorLocator textEncryptorLocator() {
|
||||
KeyStore keyStore = key.getKeyStore();
|
||||
KeyStoreTextEncryptorLocator locator = new KeyStoreTextEncryptorLocator(
|
||||
new KeyStoreKeyFactory(keyStore.getLocation(), keyStore.getPassword().toCharArray(),
|
||||
key.getKeyStore().getType()),
|
||||
keyStore.getSecret(), keyStore.getAlias());
|
||||
RsaAlgorithm algorithm = this.rsaProperties.getAlgorithm();
|
||||
locator.setRsaAlgorithm(algorithm);
|
||||
locator.setSalt(this.rsaProperties.getSalt());
|
||||
locator.setStrong(this.rsaProperties.isStrong());
|
||||
return locator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnBean(TextEncryptor.class)
|
||||
@ConditionalOnMissingBean(TextEncryptorLocator.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class SingleTextEncryptorConfiguration {
|
||||
|
||||
@Bean
|
||||
public SingleTextEncryptorLocator textEncryptorLocator(TextEncryptor encryptor) {
|
||||
return new SingleTextEncryptorLocator(encryptor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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
|
||||
*
|
||||
* https://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.cloud.config.server.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
|
||||
import org.springframework.cloud.bootstrap.encrypt.RsaProperties;
|
||||
import org.springframework.cloud.config.server.encryption.KeyStoreTextEncryptorLocator;
|
||||
import org.springframework.cloud.config.server.encryption.TextEncryptorLocator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
|
||||
import org.springframework.security.rsa.crypto.RsaAlgorithm;
|
||||
import org.springframework.security.rsa.crypto.RsaSecretEncryptor;
|
||||
|
||||
/**
|
||||
* Auto-configuration for RSA encryption.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 3.1.2
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(prefix = "encrypt.key-store", value = "location")
|
||||
@ConditionalOnClass(RsaSecretEncryptor.class)
|
||||
@EnableConfigurationProperties
|
||||
public class RsaEncryptionAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public KeyProperties keyProperties() {
|
||||
return new KeyProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TextEncryptorLocator textEncryptorLocator(KeyProperties key, RsaProperties rsaProperties) {
|
||||
KeyProperties.KeyStore keyStore = key.getKeyStore();
|
||||
KeyStoreTextEncryptorLocator locator = new KeyStoreTextEncryptorLocator(
|
||||
new KeyStoreKeyFactory(keyStore.getLocation(), keyStore.getPassword().toCharArray(),
|
||||
key.getKeyStore().getType()),
|
||||
keyStore.getSecret(), keyStore.getAlias());
|
||||
RsaAlgorithm algorithm = rsaProperties.getAlgorithm();
|
||||
locator.setRsaAlgorithm(algorithm);
|
||||
locator.setSalt(rsaProperties.getSalt());
|
||||
locator.setStrong(rsaProperties.isStrong());
|
||||
return locator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -109,7 +109,9 @@ public class EncryptionController {
|
||||
Map<String, String> keys = helper.getEncryptorKeys(name, profiles, input);
|
||||
String textToEncrypt = helper.stripPrefix(input);
|
||||
String encrypted = helper.addPrefix(keys, encryptorLocator.locate(keys).encrypt(textToEncrypt));
|
||||
logger.info("Encrypted data");
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Encrypted data");
|
||||
}
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
@@ -128,21 +130,31 @@ public class EncryptionController {
|
||||
encryptor = getEncryptor(name, profiles, data);
|
||||
String input = stripFormData(helper.stripPrefix(data), type, true);
|
||||
String decrypted = encryptor.decrypt(input);
|
||||
logger.info("Decrypted cipher data");
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Decrypted cipher data");
|
||||
}
|
||||
return decrypted;
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalStateException e) {
|
||||
logger.error("Cannot decrypt key:" + name + ", value:" + data, e);
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Cannot decrypt key:" + name + ", value:" + data, e);
|
||||
}
|
||||
throw new InvalidCipherException();
|
||||
}
|
||||
}
|
||||
|
||||
private TextEncryptor getEncryptor(String name, String profiles, String data) {
|
||||
if (encryptorLocator == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Text encryptorLocator is null.");
|
||||
}
|
||||
throw new KeyNotInstalledException();
|
||||
}
|
||||
TextEncryptor encryptor = encryptorLocator.locate(helper.getEncryptorKeys(name, profiles, data));
|
||||
if (encryptor == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("TextEncryptor is null.");
|
||||
}
|
||||
throw new KeyNotInstalledException();
|
||||
}
|
||||
return encryptor;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Bootstrap components
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapConfiguration,\
|
||||
org.springframework.cloud.config.server.config.DefaultTextEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.RsaEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration
|
||||
|
||||
# Environment PostProcessor
|
||||
@@ -11,6 +13,8 @@ org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapApplicati
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.config.server.config.ConfigServerAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.DefaultTextEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.RsaEncryptionAutoConfiguration,\
|
||||
org.springframework.cloud.config.server.config.VaultEncryptionAutoConfiguration
|
||||
org.springframework.boot.diagnostics.FailureAnalyzer=\
|
||||
org.springframework.cloud.config.server.diagnostics.GitUriFailureAnalyzer
|
||||
|
||||
@@ -76,7 +76,7 @@ public class BootstrapConfigServerIntegrationTests {
|
||||
|
||||
@Test
|
||||
@Ignore // FIXME: configdata
|
||||
public void environmentBootstraps() throws Exception {
|
||||
public void environmentBootstraps() {
|
||||
assertThat(this.env.getProperty("info.foo", "")).isEqualTo("bar");
|
||||
assertThat(this.env.getProperty("config.foo", "")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user