Daniel Fernández opened SPR-8928 and commented
org.springframework.context.support.PropertySourcesPlaceholderConfigurer is overriding the "postProcessBeanFactory" method defined in org.springframework.beans.factory.config.PropertyResourceConfigurer in order to register the required chain of PropertySource objects that will be use for resolving properties. This makes sense and is OK.
But the problem is that the PropertySource object for the local properties (those coming from the "location" attribute and also from the "properties" property) is being created like this:
PropertySource<?> localPropertySource = new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, this.mergeProperties());
...whereas in the original "postProcessBeanFactory" method in PropertyResourceConfigurer these merged properties are post-processed by executing the "convertProperties" method:
Properties mergedProps = mergeProperties(); // Convert the merged properties, if necessary. convertProperties(mergedProps); // Let the subclass process the properties. processProperties(beanFactory, mergedProps);
This means that the new PropertySourcesPlaceholderConfigurer class never calls "convertProperties", and so disables one of the extension mechanisms of the old pre-3.1 PropertyPlaceholderConfigurer class: overriding the "convertProperty(...)" and "convertPropertyValue(...)" methods.
I am jasypt's author http://www.jasypt.org and I am creating a Spring3.1-compatible EncryptedPropertySourcesPlaceholderConfigurer, but this bug doesn't allow me to transparently apply property decryption at the "convertProperty" method :-(
Affects: 3.1 GA
Issue Links:
- #18574 convertPropertyValue (for reading encrypted values) not working ("is duplicated by")
- #13603 Allow the use of custom PropertySource annotations in @Configuration
classes
- SEC-3123 Encrypted property value support
- #15294 Add encryption support for PropertyPlaceholderConfigurer
- #17236 Backport encrypted property functionality from spring-cloud-config environment work
8 votes, 18 watchers
Comment From: spring-projects-issues
Chris Beams commented
Hi Daniel,
Thanks for the submission. Would you be willing to attach a simple test case that demonstrates the problem? There may still be time to fit this in for 3.1.1.
Comment From: spring-projects-issues
Scott C. commented
Chris,
I have the exact use case as Daniel. I suggest this needs to be implemented ASAP for at least 3 reasons:
1) This use case above. 2) In the JavaDoc for the convertPropertyValue method it states "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." -- this is an explicit design decision/extension Juergen stated, yet it is not longer viable due to this bug. There are plenty of people (I assume), who read that and assume it will work as written. 3) Finally, I think it is appropriate design to keep backward compatible (nearly at all costs) when you are intending to replace one (class) component with another in a framework used by millions of developers. Consistency (when viable) between the components makes it easier for all to: a) upgrade to new versions of a framework b) learning the framework c) testing both the actual framework and all the users of it
I could go on, but I think you get my point. :)
Overall, this is a great replacement for the old PFPC. I applaud the effort. I just think folks expect it to work within the framework as is.
Looking forward to hearing the comments.
Thanks!
Scott
Comment From: spring-projects-issues
Patrick Hayden commented
I have exactly the same issue as Daniel describes. I have created a class that extends PropertySourcesPlaceholderConfigurer and overrides convertProperty() to decrypt a property value that I would prefer not to put on the server in plain text. The problem is that the new convertProperty() implementation never gets called.
Comment From: spring-projects-issues
Andreas Toom commented
Hi,
I would like to add another vote for this issue. We are starting a new project with Spring Boot and we are using the Jasypt library mentioned above. When looking through the source code it seems that Spring 4.x does not allow for conversion of properties that are loaded in the Environment using a PropertySourcesPlaceholderConfigurer.
Spring should allow for a single point of conversion of values no matter where it is loaded from, i.e. command line, system property, environment etc.
/Andreas
Comment From: spring-projects-issues
Michael Gallagher commented
Here's the workaround I'm using, if anyone finds it helpful:
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
final StringValueResolver valueResolver) {
super.doProcessProperties(beanFactoryToProcess,
new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return convertPropertyValue(valueResolver.resolveStringValue(strVal));
}
}
);
}
Comment From: spring-projects-issues
Sam Brannen commented
Please note that this is related to the following issues.
- SEC-3123
-
13603
-
15294
-
17236
Comment From: spring-projects-issues
Alireza Fattahi commented
@Michael
Gallagher solution worked for me. Thanks!
Comment From: spring-projects-issues
Sima Salmani commented
@Michael
Gallagher
Hi
Thanks. It helped me a lot.
Comment From: spring-projects-issues
Chethan Bandi commented
yesterday I just stumbled on this with spring-boot 1.3.5.RELEASE in my project. I confirm this issue exists and mentioned workaround worked for me.
Comment From: spring-projects-issues
Jeremy Hettenhouser commented
The work around as written does mess with the
@Value("${...}")
annotations though. My own workaround is pretty ugly though. I use a method similar to jasypt in overriding merged properties and filtering there.
Comment From: spring-projects-issues
pushpendra-jain commented
Written one sample application to do add support for using Encrypted values here
https://github.com/pushpendra-jain/spring-examples/tree/master/PropertySourcesPlaceholderEncrypter
Basically instead of trying to invoke its convertProperty method overrided its processProperties method and getting the job done and code surely does not change any existing behavior.
Comment From: spring-projects-issues
Bulk closing outdated, unresolved issues. Please, reopen if still relevant.
Comment From: raduiacobescu
It took me ages to get to your implementation example @spring-issuemaster This must be added somewhere in a documentation