All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ulisesbocchio.jasyptspringboot.EnableEncryptablePropertySourcesPostProcessor Maven / Gradle / Ivy

There is a newer version: 3.0.5
Show newest version
package com.ulisesbocchio.jasyptspringboot;

import org.jasypt.encryption.StringEncryptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.CommandLinePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.ArrayList;
import java.util.List;

/**
 * 

{@link BeanFactoryPostProcessor} that wraps all {@link PropertySource} defined in the {@link Environment} * with {@link EncryptablePropertySourceWrapper} and defines a default {@link StringEncryptor} for decrypting properties * that can be configured through the same properties it wraps.

*

*

It takes the lowest precedence so it does not interfere with Spring Boot's own post processors

* * @author Ulises Bocchio */ public class EnableEncryptablePropertySourcesPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered { private static final Logger LOG = LoggerFactory.getLogger(EnableEncryptablePropertySourcesPostProcessor.class); private ConfigurableEnvironment environment; private InterceptionMode interceptionMode; public EnableEncryptablePropertySourcesPostProcessor(ConfigurableEnvironment environment, InterceptionMode interceptionMode) { this.environment = environment; this.interceptionMode = interceptionMode; } private PropertySource makeEncryptable(PropertySource propertySource, ConfigurableListableBeanFactory registry) { StringEncryptor encryptor = registry.getBean(StringEncryptor.class); PropertySource encryptablePropertySource = interceptionMode == InterceptionMode.PROXY ? proxyPropertySource(propertySource, encryptor) : instantiatePropertySource(propertySource, encryptor); LOG.info("Converting PropertySource {}[{}] to {}", propertySource.getName(), propertySource.getClass().getName(), encryptablePropertySource.getClass().getSimpleName()); return encryptablePropertySource; } @SuppressWarnings("unchecked") private PropertySource proxyPropertySource(PropertySource propertySource, StringEncryptor encryptor) { //Silly Chris Beams for making CommandLinePropertySource getProperty and containsProperty methods final. Those methods //can't be proxied with CGLib because of it. So fallback to wrapper for Command Line Arguments only. if (propertySource instanceof CommandLinePropertySource) { return instantiatePropertySource(propertySource, encryptor); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setTargetClass(propertySource.getClass()); proxyFactory.setProxyTargetClass(true); proxyFactory.setTarget(propertySource); proxyFactory.addAdvice(new EncryptablePropertySourceMethodInterceptor(encryptor)); return (PropertySource) proxyFactory.getProxy(); } @SuppressWarnings("unchecked") private PropertySource instantiatePropertySource(PropertySource propertySource, StringEncryptor encryptor) { PropertySource encryptablePropertySource; if (propertySource instanceof MapPropertySource) { encryptablePropertySource = (PropertySource) new EncryptableMapPropertySourceWrapper((MapPropertySource) propertySource, encryptor); } else if (propertySource instanceof EnumerablePropertySource) { encryptablePropertySource = new EncryptableEnumerablePropertySourceWrapper((EnumerablePropertySource) propertySource, encryptor); } else { encryptablePropertySource = new EncryptablePropertySourceWrapper(propertySource, encryptor); } return encryptablePropertySource; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { LOG.info("Post-processing PropertySource instances"); MutablePropertySources propSources = environment.getPropertySources(); List encryptablePropSources = new ArrayList(); for (PropertySource ps : propSources) { if(!(ps instanceof EncryptablePropertySource)) { PropertySource eps = makeEncryptable(ps, beanFactory); encryptablePropSources.add(eps); } } for(PropertySource eps : encryptablePropSources) { propSources.replace(eps.getName(), eps); } } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } }