Search code examples
javaspringspring-4

How to use Spring 4 convertPropertyValue (for reading encrypted values)?


We are using spring 4 place holder feature

<context:property-placeholder location="classpath:/configs/*.properties,classpath:/configs/specific/*-config.properties" />

The property files:

##sample.properties
user=admin
password=123

We try to encrypt the password in the property file. So the property file will be

##sample.properties
user=admin
password=ENC(RE%%$XC)

I found that the spring has forecast this. As mentioned in http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/PropertyResourceConfigurer.html the convertPropertyValue method has been documented as:

Convert the given property value from the properties source to the value which should be applied.

The default implementation simply returns the original value. Can be overridden in subclasses, for example to detect encrypted values and decrypt them accordingly.

But I don't know how to use it ?! I tried to define a new bean:

    <bean class="foo.bar.security.DecryptPropertyConfigurer">
    <property name="locations">
        <list>
            <value>classpath:/configs/*.properties</value>
            <value>classpath:/configs/bsi/*-config.properties</value>
        </list>
    </property>  
    </bean>

And

public class DecryptPropertyConfigurer extends PropertySourcesPlaceholderConfigurer {

    @Override
    protected String convertPropertyValue(String originalValue){
        //if value is between ENC() then decrypt it
        //return originalValue or decrypted value;
    }

}

When I set break point at convertPropertyValue it seems that it is never called.

The http://romiawasthy.blogspot.com/2012/02/encryptdecrpt-properties-in-spring.html contains some good info but did not help me.


Solution

  • This seems to be a bug in spring https://jira.spring.io/browse/SPR-8928. As a commented workaround there, one can use doProcessProperties as

    protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, final StringValueResolver valueResolver) {
    
        super.doProcessProperties(beanFactoryToProcess,
                new StringValueResolver() {
                    @Override
                    public String resolveStringValue(String strVal) {
                        return convertPropertyValue(valueResolver.resolveStringValue(strVal));
                    }
                }
        );
    }
    

    Credits to Michael Gallag