Fix encryptor configuration to prevent infinite loop

This commit is contained in:
Dave Syer
2017-06-27 13:08:02 +01:00
parent 4db8f48233
commit 8df2051fef
5 changed files with 47 additions and 98 deletions

View File

@@ -15,29 +15,25 @@
*/
package org.springframework.cloud.config.server.bootstrap;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.config.server.config.ConfigServerProperties;
import org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration;
import org.springframework.cloud.config.server.encryption.LocatorTextEncryptor;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.util.StringUtils;
/**
* Bootstrap configuration to fetch external configuration from a (possibly remote)
* {@link EnvironmentRepository}. Off by default because it can delay startup, but can be
* enabled with <code>spring.cloud.config.server.bootstrap=true</code>. This would be
* useful, for example, if the config server were embedded in another app that wanted to
* Bootstrap configuration to fetch external configuration from a (possibly
* remote) {@link EnvironmentRepository}. Off by default because it can delay
* startup, but can be enabled with
* <code>spring.cloud.config.server.bootstrap=true</code>. This would be useful,
* for example, if the config server were embedded in another app that wanted to
* be configured from the same repository as all the other clients.
*
* @author Dave Syer
@@ -45,25 +41,7 @@ import org.springframework.util.StringUtils;
*/
@Configuration
@ConditionalOnProperty("spring.cloud.config.server.bootstrap")
public class ConfigServerBootstrapConfiguration implements BeanPostProcessor {
@Autowired
private BeanFactory beanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof TextEncryptor && !(bean instanceof LocatorTextEncryptor)) {
return new LocatorTextEncryptor(beanFactory);
}
return bean;
}
public class ConfigServerBootstrapConfiguration {
@EnableConfigurationProperties(ConfigServerProperties.class)
@Import(EnvironmentRepositoryConfiguration.class)
@@ -80,15 +58,14 @@ public class ConfigServerBootstrapConfiguration implements BeanPostProcessor {
@Bean
public EnvironmentRepositoryPropertySourceLocator environmentRepositoryPropertySourceLocator() {
return new EnvironmentRepositoryPropertySourceLocator(this.repository,
this.client.getName(), this.client.getProfile(), getDefaultLabel());
return new EnvironmentRepositoryPropertySourceLocator(this.repository, this.client.getName(),
this.client.getProfile(), getDefaultLabel());
}
private String getDefaultLabel() {
if (StringUtils.hasText(this.client.getLabel())) {
return this.client.getLabel();
}
else if (StringUtils.hasText(this.server.getDefaultLabel())) {
} else if (StringUtils.hasText(this.server.getDefaultLabel())) {
return this.server.getDefaultLabel();
}
return null;

View File

@@ -26,6 +26,8 @@ import org.springframework.cloud.bootstrap.encrypt.KeyProperties.KeyStore;
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;
@@ -37,9 +39,9 @@ import org.springframework.security.rsa.crypto.RsaSecretEncryptor;
import org.springframework.util.StringUtils;
/**
* 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.
* 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.
*
* @author Bartosz Wojtkiewicz
* @author Rafal Zukowski
@@ -56,8 +58,14 @@ public class EncryptionAutoConfiguration {
@Autowired
private KeyProperties key;
@Autowired(required = false)
private TextEncryptorLocator locator;
@Bean
public TextEncryptor nullTextEncryptor() {
public TextEncryptor defaultTextEncryptor() {
if (locator != null) {
return new LocatorTextEncryptor(locator);
}
if (StringUtils.hasText(this.key.getKey())) {
return new EncryptorFactory().create(this.key.getKey());
}
@@ -66,18 +74,31 @@ public class EncryptionAutoConfiguration {
}
@Bean
@ConditionalOnMissingBean
@Configuration
@ConditionalOnProperty(value = "spring.cloud.config.server.encrypt.enabled", matchIfMissing = true)
public EnvironmentEncryptor environmentEncryptor(
TextEncryptorLocator textEncryptorLocator) {
return new CipherEnvironmentEncryptor(textEncryptorLocator);
protected static class EncryptorConfiguration {
@Autowired(required = false)
private TextEncryptorLocator locator;
@Autowired
private TextEncryptor encryptor;
@Bean
@ConditionalOnMissingBean
public EnvironmentEncryptor environmentEncryptor() {
TextEncryptorLocator locator = this.locator;
if (locator == null) {
locator = new SingleTextEncryptorLocator(encryptor);
}
return new CipherEnvironmentEncryptor(locator);
}
}
@Configuration
@ConditionalOnClass(RsaSecretEncryptor.class)
@ConditionalOnProperty(value = "encrypt.keyStore.location", matchIfMissing = false)
@EnableConfigurationProperties(KeyProperties.class)
@ConditionalOnProperty(value = "encrypt.key-store.location", matchIfMissing = false)
protected static class KeyStoreConfiguration {
@Autowired
@@ -87,8 +108,8 @@ public class EncryptionAutoConfiguration {
@ConditionalOnMissingBean
public TextEncryptorLocator textEncryptorLocator() {
KeyStore keyStore = this.key.getKeyStore();
KeyStoreTextEncryptorLocator locator = new KeyStoreTextEncryptorLocator(new KeyStoreKeyFactory(
keyStore.getLocation(), keyStore.getPassword().toCharArray()),
KeyStoreTextEncryptorLocator locator = new KeyStoreTextEncryptorLocator(
new KeyStoreKeyFactory(keyStore.getLocation(), keyStore.getPassword().toCharArray()),
keyStore.getSecret(), keyStore.getAlias());
locator.setRsaAlgorithm(this.key.getRsa().getAlgorithm());
locator.setSalt(this.key.getRsa().getSalt());

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2015 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.cloud.config.server.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.config.server.encryption.SingleTextEncryptorLocator;
import org.springframework.cloud.config.server.encryption.TextEncryptorLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.encrypt.TextEncryptor;
@Configuration
@AutoConfigureAfter(EncryptionAutoConfiguration.class)
public class SingleEncryptorAutoConfiguration {
@Autowired(required = false)
private TextEncryptor encryptor;
@Bean
@ConditionalOnMissingBean
public TextEncryptorLocator textEncryptorLocator() {
return new SingleTextEncryptorLocator(this.encryptor);
}
}

View File

@@ -18,7 +18,6 @@ package org.springframework.cloud.config.server.encryption;
import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.security.crypto.encrypt.TextEncryptor;
/**
@@ -31,10 +30,8 @@ public class LocatorTextEncryptor implements TextEncryptor {
private TextEncryptorLocator locator;
private BeanFactory beanFactory;
public LocatorTextEncryptor(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
public LocatorTextEncryptor(TextEncryptorLocator locator) {
this.locator = locator;
}
@Override
@@ -45,9 +42,6 @@ public class LocatorTextEncryptor implements TextEncryptor {
}
private TextEncryptorLocator getLocator() {
if (locator == null) {
locator = beanFactory.getBean(TextEncryptorLocator.class);
}
return locator;
}

View File

@@ -1,8 +1,7 @@
# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapConfiguration,\
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration,\
org.springframework.cloud.config.server.config.SingleEncryptorAutoConfiguration
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration
# Application listeners
org.springframework.context.ApplicationListener=\
@@ -11,5 +10,4 @@ org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapApplicati
# Autoconfiguration
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.SingleEncryptorAutoConfiguration
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration