Add optional decryption to bootstrap config server

Fixes gh-434
This commit is contained in:
Dave Syer
2017-06-26 16:58:25 +01:00
parent e6a42aab95
commit 0da1397153
26 changed files with 144 additions and 7 deletions

View File

@@ -15,17 +15,22 @@
*/
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;
/**
@@ -39,9 +44,27 @@ import org.springframework.util.StringUtils;
* @author Roy Clarkson
*/
@Configuration
public class ConfigServerBootstrapConfiguration {
@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;
}
@ConditionalOnProperty("spring.cloud.config.server.bootstrap")
@EnableConfigurationProperties(ConfigServerProperties.class)
@Import(EnvironmentRepositoryConfiguration.class)
protected static class LocalPropertySourceLocatorConfiguration {

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2012-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.encryption;
import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.security.crypto.encrypt.TextEncryptor;
/**
* @author Dave Syer
*
*/
public class LocatorTextEncryptor implements TextEncryptor {
private EnvironmentPrefixHelper helper = new EnvironmentPrefixHelper();
private TextEncryptorLocator locator;
private BeanFactory beanFactory;
public LocatorTextEncryptor(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public String encrypt(String text) {
Map<String, String> keys = helper.getEncryptorKeys("configserver", "default",
text);
return getLocator().locate(keys).encrypt(helper.stripPrefix(text));
}
private TextEncryptorLocator getLocator() {
if (locator == null) {
locator = beanFactory.getBean(TextEncryptorLocator.class);
}
return locator;
}
@Override
public String decrypt(String encryptedText) {
Map<String, String> keys = helper.getEncryptorKeys("configserver", "default",
encryptedText);
return getLocator().locate(keys).decrypt(helper.stripPrefix(encryptedText));
}
}

View File

@@ -1,6 +1,8 @@
# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapConfiguration
org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapConfiguration,\
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration,\
org.springframework.cloud.config.server.config.SingleEncryptorAutoConfiguration
# Application listeners
org.springframework.context.ApplicationListener=\

View File

@@ -20,7 +20,7 @@ import static org.junit.Assert.assertFalse;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConfigServerApplication.class, properties = "spring.cloud.bootstrap.name:enable-bootstrap",
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@ActiveProfiles({"test", "encrypt"})
public class BootstrapConfigServerIntegrationTests {
@LocalServerPort
@@ -29,9 +29,12 @@ public class BootstrapConfigServerIntegrationTests {
@Value("${info.foo}")
private String foo;
@Value("${config.foo}")
private String config;
@BeforeClass
public static void init() throws IOException {
ConfigServerTestUtils.prepareLocalRepo();
ConfigServerTestUtils.prepareLocalRepo("encrypt-repo");
}
@Test
@@ -46,6 +49,7 @@ public class BootstrapConfigServerIntegrationTests {
@Test
public void environmentBootstraps() throws Exception {
assertEquals("bar", foo);
assertEquals("foo", config);
}
}

View File

@@ -3,5 +3,11 @@ spring:
config:
server:
git:
uri: file:./target/repos/config-repo
bootstrap: true
uri: file:./target/repos/encrypt-repo
bootstrap: true
encrypt:
key-store:
location: classpath:server.jks
password: letmein
secret: changeme

View File

@@ -0,0 +1,9 @@
info:
foo: bar
---
spring:
profiles: encrypt
config:
foo: '{cipher}{key:mytestkey}AQCohs2V6P8/UiG6a4TF/CZTCBdt5Q7wvNvcyf6vs2ByK2ZYSM77Nu0sOAduxUpMbVwJ/syecmkIXR+hU3EfT2uqPieA7/v5n33ppqIQ9JAt5JggdYIGe+wX25zU3DTXOOJdAAMzNX+zjOVyCh0QtmJf/kFslg6NqQq0E+kSg3zBi3AnkKj5BLnLIxkjxzKA4mnDXpSm7ekLZZP2iQSYSW/82AC7UOLLzTqwInMI3tJLW1e9Ne+LDsjmSxA+nkK9zhidtXPwb/SPaNF74cJCEf9mgzzKYwJlwqChLzJt8UQ1jHwRc8B6FufmizUHSp27nxdtVB4HMqh3nNsMCy137Ces58T09ZS/y/cYNRxcFbp78MHFHUqAgbC0B/p5t6h4XbQ='

View File

@@ -0,0 +1 @@
foo: bar

View File

@@ -0,0 +1 @@
Add encrypted property

View File

@@ -0,0 +1,2 @@
7df4a26d5437d9d4090cd5809967f870444cde8f not-for-merge branch 'raw' of dsyer@localhost:/home/dsyer/dev/platform/config/spring-platform-config-server/target/test-classes/config-repo
7df4a26d5437d9d4090cd5809967f870444cde8f not-for-merge tag 'foo' of dsyer@localhost:/home/dsyer/dev/platform/config/spring-platform-config-server/target/test-classes/config-repo

View File

@@ -0,0 +1 @@
ref: refs/heads/master

View File

@@ -0,0 +1,5 @@
[core]
repositoryformatversion = 0
filemode = true
logallrefupdates = true
[branch "raw"]

View File

@@ -0,0 +1,3 @@
1 1
7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0
1

View File

@@ -0,0 +1,7 @@
0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Dave Syer <dsyer@gopivotal.com> 1406860717 -0700
7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Ryan Baxter <rbaxter@pivotal.io> 1481905383 -0500 checkout: moving from raw to master
9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905407 -0500 checkout: moving from master to raw
7df4a26d5437d9d4090cd5809967f870444cde8f 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905544 -0500 checkout: moving from raw to composite
7df4a26d5437d9d4090cd5809967f870444cde8f 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905552 -0500 checkout: moving from composite to raw
7df4a26d5437d9d4090cd5809967f870444cde8f 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Dave Syer <dsyer@pivotal.io> 1498491043 +0100 checkout: moving from raw to master
9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc Dave Syer <dsyer@pivotal.io> 1498491468 +0100 commit: Add encrypted property

View File

@@ -0,0 +1 @@
0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Ryan Baxter <rbaxter@pivotal.io> 1481905474 -0500 branch: Created from raw

View File

@@ -0,0 +1,2 @@
0000000000000000000000000000000000000000 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 Dave Syer <dsyer@gopivotal.com> 1406860776 -0700 branch: Created from 9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0
9f01fb972bc9617e4ea59f5c8ee3ceb5ff515cd0 ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc Dave Syer <dsyer@pivotal.io> 1498491468 +0100 commit: Add encrypted property

View File

@@ -0,0 +1 @@
0000000000000000000000000000000000000000 7df4a26d5437d9d4090cd5809967f870444cde8f Dave Syer <dsyer@gopivotal.com> 1406860717 -0700

View File

@@ -0,0 +1,4 @@
x<01><>M
<EFBFBD>0<10>]<5D><14>$<24><><EFBFBD>o<> <09><> <0B> 1z{<7B>7p<37><16>{<1F><><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>Ze<06><>P<05>+G<><47>D<EFBFBD>v<08>GJ<47>8i#<23><><EFBFBD>6pIb
<EFBFBD><EFBFBD><EFBFBD> ZV<5A><56>K<EFBFBD>&摸[<5B>FMQ

View File

@@ -0,0 +1 @@
7df4a26d5437d9d4090cd5809967f870444cde8f

View File

@@ -0,0 +1 @@
ad5e0cb7036ed11ddd4b7be6ed86ad3565c8a3fc

View File

@@ -0,0 +1 @@
7df4a26d5437d9d4090cd5809967f870444cde8f

View File

@@ -0,0 +1 @@
7df4a26d5437d9d4090cd5809967f870444cde8f