我们混合了一些尚未迁移到 spring-boot 或 spring cloud 的遗留 Spring 应用程序以及 Spring Boot 应用程序。我正在创建一个 Spring 组件,如果属性值已加密且具有前缀,则该组件将在加载环境时自动解密 spring 属性。属性可以位于 .properties 文件(对于旧版应用程序)或 .yaml 文件(较新的 Spring Boot 应用程序)中。
该组件应该能够解密任何 spring 属性,无论其来源如何,并且应该适用于任何 spring 版本,并且不依赖于 spring boot。该组件还应该透明地解密属性。它应该从属性文件中读取密码,因此需要在开始时加载密码文件。
我们有自己的加密/解密,不想使用 jasypt。
到目前为止尝试过的事情:
I liked this https://github.com/lukashinsch/spring-properties-decrypter/blob/master/src/main/java/eu/hinsch/spring/propertiesdecrypter/DecryptingPropertiesApplicationListener.java创建 ApplicationListener 的方法,但这与 spring boot(ApplicationEnvironmentPreparedEvent) 相关。对于像 ContextRefreshed 或 ContextStart 这样的 Spring 事件,我不知道如何获得 ConfigurableApplicationContext/ConfigurableEnvironment。有人在没有 spring boot/cloud 的情况下创建了用于加密/解密的监听器吗?
我还创建了一个自定义 ApplicationContextInitializer,并将其添加到 web.xml 的上下文参数中,但这似乎不起作用。当我调试它时,我不认为它正在从我的 app.properties 文件加载/读取属性。
@Component
public class DecryptingPropertyContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize( ConfigurableApplicationContext applicationContext ) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
for ( PropertySource<?> propertySource : environment.getPropertySources() ) {
Map<String, Object> propertyOverrides = new LinkedHashMap<>();
decodePasswords( propertySource, propertyOverrides );
if ( !propertyOverrides.isEmpty() ) {
PropertySource<?> decodedProperties = new MapPropertySource( "decoded " + propertySource.getName(),
propertyOverrides );
environment.getPropertySources().addBefore( propertySource.getName(), decodedProperties );
}
}
}
private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) {
if ( source instanceof EnumerablePropertySource ) {
EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source;
for ( String key : enumerablePropertySource.getPropertyNames() ) {
Object rawValue = source.getProperty( key );
if ( rawValue instanceof String ) {
//decrypt logic here
propertyOverrides.put( key, decryptedValue );
}
}
}
}
}
有人必须做类似的事情或者有更好的想法吗?有没有办法可以监听应用程序事件然后进行处理?
感谢你的帮助