Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decrypt properties used in @ConfigurationProperties beans?

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.

like image 797
Centinul Avatar asked Apr 29 '15 12:04

Centinul


People also ask

What are the ways in which spring boot can read configuration?

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.


1 Answers

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);
            }
        }
    }
}}
like image 171
leoismyname Avatar answered Oct 25 '22 19:10

leoismyname