使用 PropertySourcesPlaceholderConfigurer 时如何解密 属性 值

How to decrypt a property value when using PropertySourcesPlaceholderConfigurer

我有一个包含 jdbc.password={enc}laksksjdjdj

等值的属性文件

使用 JDK 1.7 和 Spring 4.1.5 我的配置 class 看起来像这样

@PropertySources({
    @PropertySource("classpath:application.properties"),
    @PropertySource("classpath:env.properties")
})
@ComponentScan("com.acme")
@Configuration
public class SpringConfig
{
    @Autowired
    private ConfigurableEnvironment env;    

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
    {
        return new EncryptedPropertySourcesPlaceholderConfigurer();
    }
}

我想要实现的是将属性文件中的 any 值从加密值转换为实际值。有些值将被加密,有些则不会。这是我到目前为止所尝试的,当我在 convertProperties() 上放置断点时,props 参数始终为空。我无法理解这一点,因为我可以看到此时 this.environment 加载了文件中的所有属性。

public class EncryptedPropertySourcesPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer
{
    @Override 
    protected void convertProperties(Properties props)
    {
        Enumeration<?> propertyNames = props.propertyNames();

        while (propertyNames.hasMoreElements()) {

            String propertyName = (String) propertyNames.nextElement(); 
            String propertyValue = props.getProperty(propertyName); 

            // String convertedValue = <translate the value>;

            props.setProperty(propertyName, convertedValue);
        } 
    }

    @Override
    protected Properties mergeProperties() throws IOException {
        final Properties mergedProperties = super.mergeProperties();
        convertProperties(mergedProperties);
        return mergedProperties;
    }
}

有没有人能够使用 PropertySourcesPlaceholderConfigurer 实现此目的?我在使用 PropertyPlaceholderConfigurer 的旧应用程序中有类似的逻辑,但想使用较新的 Spring 配置。

我注意到 Jasypt 有一个类似的 EncryptablePropertySourcesPlaceholderConfigurer 但它的行为方式相同,所以我很困惑。

由于某些原因,使用 @PropertySources 注释无法按预期工作。

当调用 EncryptedPropertySourcesPlaceholderConfigurer.convertProperties() 时,自动装配的 ConfigurableEnvironment 不包含我的属性文件中的条目。根本没有对我列出的属性文件的引用。

为了解决这个限制,我删除了注释并在配置 class 中显式加载了这些资源。所以它现在看起来像这样

@ComponentScan("com.acme")
@Configuration
public class SpringConfig
{ 
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
    {
        EncryptedPropertySourcesPlaceholderConfigurer p = new EncryptedPropertySourcesPlaceholderConfigurer(new KeyfileDecryptor());
        p.setLocations(
                new ClassPathResource("application.properties"),
                new ClassPathResource("env.properties")
                );
        return p;
    }

    @Bean
    public DataSource dataSource(
            @Value("${jdbc.driverclassname}") String driverclassname,
            @Value("${jdbc.url}") String url,
            @Value("${jdbc.username}") String username,
            @Value("${jdbc.password}") String password)
    {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(driverclassname);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        return dataSource;
    }
}

此更改引入了自动装配 ConfigurableEnvironment 将是 null 的问题,因此我不得不更改为使用 @Value 注入,以便从中配置我的 dataSource属性。

现在一切都按预期工作,EncryptedPropertySourcesPlaceholderConfigurer.convertProperties() 从两个文件接收所有属性值。

编写了一个示例应用程序以在此处添加对使用加密值的支持

https://github.com/pushpendra-jain/spring-examples/tree/master/PropertySourcesPlaceholderEncrypter

基本上不是尝试调用其 convertProperty 方法而是覆盖其 processProperties 方法并完成工作,代码肯定不会改变任何现有行为。

有关步骤,请参阅 https://github.com/pushpendra-jain/spring-examples/blob/master/README.md