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.
Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration.
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);
}
}
}
}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With