springboot启动过程中读取配置文件并对属性值进行修改

应用场景:如对配置文件中的密文进行解密处理

废话不多说,直接上示例代码

import com.encry.JasypUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
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.Enviroment;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnviroment;
import org.springframework.core.Enviroment;
import org.springframework.core.MutablePropertySources;
import org.springframework.core.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Properties;


@Component
public class EnableEncryptionData implements BeanFactoryPostProcessor, BeanPostProcessor, Orderd, EnviromentAware{
	//以该前缀识别需要加密的文本
	public static final String prefix = "encry[";
	//以该后缀识别需要加密的文本
	public static final String suffix= "]";
	//启动时手动加参指定密钥进行解密,避免密钥显式地暴露在代码中,指定参数启动-Dencryption.privateKey=***,等号后面加上自己文本加密时的密钥
	private static final property_private_key = "encryption.privateKey";
	private String privateKey;
	private ConfigurableEnviroment enviroment;
	private static final Properties properties = new Properties();
	
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeanException{
		MutablePropertySources propertySources = enviroment.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 = enviroment.getProperty(k);
					if(hasPreAndSuf(property,prefix,suffix)){
						try{
							String relay = splitPreAndSuf(property,prefix,suffix);
							if(StringUtils.isEmpty(relay)){
								return;
							}
							//解密
							//自定义一个解密工具类,可以通过jasypt包进行编写,加密的文本也可以通过此包进行生成,生成之后再加上前后缀替换掉配置文件中需要加密的文本,如密码等
							String decrypt = JasyptUtil.decryptPwd(getPrivateKey(enviroment),relay);
							modify(originTrackedValue,"value",decrypt);
						}catch(Exception e){
							System.out.println(e.getMessage());
						}
					}
				});
			}
		}
	}

	@Override
	public int getOrder(){ return 0; }

	@Override
	public void setEnviroment(Enviroment enviroment){
		this.enviroment = (ConfigurableEnviroment)enviroment;
	}

	private String splitPreAndSuf(String prpperty,String prefix,String suffix){		
		try{
			String substring = property.substring(prefix.length(),property.length()-1);
			return substring;
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
		return null;
	}

	private boolean hasPreAndSuf(String property,String prefix,String suffix){
		if(property.startsWith(prefix) && property.endsWith(suffix)){
			return true;
		}
		return false;
	}

	private String getPrivateKey(ConfigurableEnviroment enviroment){
		String commonPrivateKey = System.getProperty(property_private_key,"");
		if(StringUtils.hasText(commonPrivateKey)){
			this.privateKey = commonPrivateKey;
			return commonPrivateKey;
		}
		String pkv = enviroment.getProperty(property_private_key);
		if(StringUtils.hasText(pkv)){
			this.privateKey = pkv;
			return pkv;
		}
		String propertyValue = (String)properties.get(property_private_key);
		if(StringUtils.hasText(propertyValue)){
			this.privateKey = propertyValue;
			return propertyValue;
		}
		return privateKey;
	}

	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);
	}
}

JasyptUtil工具类示例代码

import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnviromentStringPBEConfig;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.jasypt.util.text.BasicTextEncryptor;


public class JasyptUtil{

	private static final String ENCRYP_PREFIX = "ENC(";
    private static final String ENCRYP_SUFFIX = ")";
	
	/**
     * 判断是否是 prefix/suffix 包裹的属性
     *
     * @param value
     * @return
     */
    public static boolean isEncryptedValue(final String value) {
		boolean flag = false;
        if (value == null) {
            return flag;
        }
        final String val = value.trim();//去除空格及符号
		if(val.startsWith(ENCRYP_PREFIX) && val.endsWith(ENCRYP_SUFFIX)){
			flag = true;
		}
        return flag;
    }
	
	//生成加密结果
	public static String encryptPwd(String password, String value) {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(cryptor(password));
        return encryptor.encrypt(value);
    }
	
	//解密
	public static String decyptPwd(String password, String value) {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(cryptor(password));
        return encryptor.decrypt(isEncryptedValue(value) ? getOriginValue(value) : value);
    }
	
	/**
     * 获取前后缀包裹的值
     *
     * @param value
     * @return
     */
    private static String getOriginValue(final String value) {
        return value.substring(ENCRYPT_PREFIX.length(),
                (value.length() - ENCRYPT_SUFFIX.length()));
    }
	
	/**
     * @param password salt
     * @return
     */
    public static SimpleStringPBEConfig cryptor(String password) {
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(password);
        config.setAlgorithm(StandardPBEByteEncryptor.DEFAULT_ALGORITHM);
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName(null);
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setStringOutputType("base64");
        return config;
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值