我在我的spring-boot应用程序中使用Spring Cloud Config,我需要编写一些自定义代码来处理属性被标记为属性时从我的公司密码库中读取的属性。我知道spring cloud支持Hashicorp Vault,但这不是万一。
我不想对要从其他来源检索的特定属性进行硬编码,例如,我会为应用app1
创建一个属性文件,其中包含值为dev
的值spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
:
prod
但对于其他一些资料,例如spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=prod-user
spring.datasource.password=[[vault]]
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
,我会:
[[vault]]
所以我需要自定义属性保险库来拦截加载的属性,只要它找到返回的值等于spring.datasource.password
(或其他类型的标志),并从公司保险库查询。在这种情况下,我的自定义属性加载器将从公司密码库中找到属性Base64.encodeToString(("users name").getBytes(), 2);
的值。所有其他属性仍将按标准spring cloud配置客户端加载的值原样返回。
我想使用带注释的代码,没有XML配置。
答案 0 :(得分:0)
您可以实施自己的PropertySourceLocator并添加条目 目录META-INF中的spring.factories。
#spring.factories
org.springframework.cloud.bootstrap.BootstrapConfiguration=/
foo.bar.MyPropertySourceLocator
然后,您可以在公司密码库中引用密钥,就像春天的常规属性一样。
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=prod-user
spring.datasource.password=${lodaded.password.from.corporate.vault}
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
HasiCorp的实施:VaultPropertySourceLocatorSupport
答案 1 :(得分:0)
在尝试解决相同的问题时,我相信我已经开始尝试可以接受的解决方法。
这是我下面的解决方案。
public class JBossVaultEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
MutablePropertySources propertySources = environment.getPropertySources();
Map<String, String> sensitiveProperties = propertySources.stream()
.filter(propertySource -> propertySource instanceof EnumerablePropertySource)
.map(propertySource -> (EnumerablePropertySource<?>) propertySource)
.map(propertySource -> {
Map<String, String> vaultProperties = new HashMap<>();
String[] propertyNames = propertySource.getPropertyNames();
for (String propertyName : propertyNames) {
String propertyValue = propertySource.getProperty(propertyName).toString();
if (propertyValue.startsWith("VAULT::")) {
vaultProperties.put(propertyName, propertyValue);
}
}
return vaultProperties;
})
.reduce(new HashMap<>(), (m1, m2) -> {
m1.putAll(m2);
return m1;
});
Map<String, Object> vaultProperties = new HashMap<>();
sensitiveProperties.keySet().stream()
.forEach(key -> {
vaultProperties.put(key, VaultReader.readAttributeValue(sensitiveProperties.get(key)));
});
propertySources.addFirst(new MapPropertySource("vaultProperties", vaultProperties));
}