Reputation: 884
I'm using Spring Boot 1.2.3
and I'd like to understand if it's possible to decrypt a property value before its injected into a bean annotated with @ConfigurationProperties
.
Suppose I have the following in an application.properties
file:
appprops.encryptedProperty=ENC(ENCRYPTEDVALUE)
and a sample application like so:
package aaa.bb.ccc.propertyresearch;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import javax.annotation.PostConstruct;
@SpringBootApplication
@EnableConfigurationProperties(PropertyResearchApplication.ApplicationProperties.class)
public class PropertyResearchApplication {
public static void main(String[] args) {
SpringApplication.run(PropertyResearchApplication.class, args);
}
@ConfigurationProperties("appprops")
public static class ApplicationProperties {
private String encryptedProperty;
@PostConstruct
public void postConstruct() throws Exception {
System.out.println("ApplicationProperties --> appprops.encryptedProperty = " + encryptedProperty);
}
public String getEncryptedProperty() {
return encryptedProperty;
}
public void setEncryptedProperty(String encryptedProperty) {
this.encryptedProperty = encryptedProperty;
}
}
}
In the past I've used a custom PropertySourcesPlaceholderConfigurer
to achieve this but it requires setting up a structure like the following:
@Component
public class ApplicationProperties {
@Value("${appprops.enrcyptedProperty}")
private String encryptedProperty;
@PostConstruct
public void postConstruct() throws Exception {
System.out.println("ApplicationProperties --> appprops.encryptedProperty = " + encryptedProperty);
}
public String getEncryptedProperty() {
return encryptedProperty;
}
}
While that in and of itself is not bad I'd like to see if I can leverage the niceties of @ConfigurationProperties
with encrypted properties.
Upvotes: 6
Views: 5061
Reputation: 1970
PropertyResourceConfigurer has a convertPropertyValue method which you can override for this purpose.
public class EncryptedPropertySourcedPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer {
@Override
protected String convertPropertyValue(String originalValue) {
if(originalValue.startswith("ENC") {
return decrypt(originalValue.subString(4, originalValue.length() - 1);
}
return originalValue;
}
}
Upvotes: 0
Reputation: 407
Just drop the following file in your spring project and implement custom decrypt method.
@Component
public class CmtEncryptedPropertyConfigurer extends PropertySourcesPlaceholderConfigurer {
private ConfigurableEnvironment environment;
@Override
public void setEnvironment(Environment environment) {
super.setEnvironment(environment);
this.environment = (ConfigurableEnvironment) environment;
}
@Override
protected void loadProperties(Properties props) throws IOException {
this.localOverride = true;
for (PropertySource<?> propertySource : environment.getPropertySources()) {
if (propertySource instanceof EnumerablePropertySource) {
String[] propertyNames = ((EnumerablePropertySource) propertySource).getPropertyNames();
for (String propertyName : propertyNames) {
String propertyValue = propertySource.getProperty(propertyName).toString();
// put logic to see if decryption required for thsi name/value
// decrypt here
String decryptedValue = decrypt(propertyValue);
// set value here
props.setProperty(propertyName, decryptedValue);
}
}
}
}}
Upvotes: 3
Reputation: 974
you can use org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer
can be add following Spring configuration in spring context xml file.
<context:property-placeholder location="classpath:application.properties"/>
<bean class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="location" value="classpath:application.properties" />
</bean>
<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="password" value="password" />
</bean>
Upvotes: 0