Spring提供的BeanFactoryPostProcessor及EnvironmentAware配合取到OriginTrackedMapPropertySource
在之前取到的map可以直接进行修改赋值
新版本的SpringBoot设置了unmodifiableMap,由于配置文件可以放多种类型,所以SpringBoot将配置文件中的value设置成了Object,对 应OriginTrackedValue中的value属性,其在设置时设置的为OriginTrackedCharSequence,OriginTrackedValue的静态内部类。
private final Object value;
value的值应该会修改吧
代码可以参考:
1 在配置文件中将要加密的属性提前加密好然后放入ENCRY[密文]
例如 spirng.redis.password=ENCRY[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
2 加入此类,对应的加解密随公司或个人方式修改
package cn.xxxx.encry;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Properties;
@Component
public class EnableEncryptionData implements BeanFactoryPostProcessor, Ordered,
EnvironmentAware, BeanPostProcessor {
public static final String DEFULT_PREFIX = "ENCRY[";
public static final String DEFULT_SUFFIX = "]";
private static final String RSA_PRIVATE_KEY_PROPERTY = "encryption.rsa.privateKey";
private ConfigurableEnvironment environment;
private String prevateKey = EncryptionUtils.privateKey;
private static final Properties properties = new Properties();
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
MutablePropertySources propertySources = environment.getPropertySources();
for (PropertySource<?> propertySource : propertySources) {
if (propertySource instanceof OriginTrackedMapPropertySource){
OriginTrackedMapPropertySource om = (OriginTrackedMapPropertySource)propertySource;
Map<String, Object> source = om.getSource();
source.forEach((k,v)->{
OriginTrackedValue originTrackedValue = (OriginTrackedValue) source.get(k);
String property = environment.getProperty(k);
if (hasPreAndSuf(property)){
try{
String relay = splitPreAndSuf(property,DEFULT_PREFIX,DEFULT_SUFFIX);
if (StringUtils.isEmpty(relay)){
return;
}
// 这里写你们自己的解密方法
String decrypt = EncryptionUtils.decrypt(relay,getPrivateKey(environment));
modify(originTrackedValue,"value",decrypt);
}catch (Exception e){
System.out.println(e.getMessage());
}
}
});
}
}
}
private String splitPreAndSuf(String property, String prefix, String suffix) {
try{
String substring = property.substring(6, (property.length()-1));
return substring;
}catch (Exception e){
System.out.println(e.getMessage());
}
return null;
}
private boolean hasPreAndSuf(String property) {
if (property.startsWith("ENCRY[") && property.endsWith("]")){
return true;
}
return false;
}
private String getPrivateKey(ConfigurableEnvironment environment) {
String commonPrivateKey = System.getProperty(RSA_PRIVATE_KEY_PROPERTY, "");
if (StringUtils.hasText(commonPrivateKey)){
this.prevateKey = commonPrivateKey;
return commonPrivateKey;
}
String pkv = environment.getProperty(RSA_PRIVATE_KEY_PROPERTY);
if (StringUtils.hasText(pkv)){
this.prevateKey = pkv;
return pkv;
}
String propertyValue = (String)properties.get(RSA_PRIVATE_KEY_PROPERTY);
if (StringUtils.hasText(propertyValue)){
this.prevateKey = propertyValue;
return propertyValue;
}
return prevateKey;
}
@Override
public int getOrder() {
return 0;
}
@Override
public void setEnvironment(Environment environment) {
this.environment= (ConfigurableEnvironment) environment;
}
public static void modify(Object object, String fieldName, Object newFieldValue) throws Exception {
Field field = object.getClass().getSuperclass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, newFieldValue);
field.setAccessible(false);
}
}
3 运行即可
上方代码只是模板,自己修改即可