springboot配置文件密码类型配置项加密
实现EnvironmentPostProcessor接口,可以在项目启动初期对配置进行修改。
如下代码先获取配置文件的mysql、redis、mong等密码,然后在进行解密,最后将解密后的密码放回环境变量。
Ps:只取优先级高的配置
在resources/META-INF文件夹下新增spring.factories文件,内容如下
org.springframework.boot.env.EnvironmentPostProcessor=\
com.linewell.zhzf.api.gateway.framework.security.SafetyEncryptProcessor
新增类 SafetyEncryptProcessor
public class SafetyEncryptProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String symmetricKey = null;
String symmetricEncryptType = null;
HashMap<String, Object> map = new HashMap<>();
Boolean encryptValue = null;
// 根据配置判断配置文件密码是否加密
// 循环各配置文件
for (PropertySource<?> ps : environment.getPropertySources()) {
if (ps instanceof OriginTrackedMapPropertySource) {
// 配置文件都为OriginTrackedMapPropertySource类型
OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) ps;
// 循环单个文件的配置项
for (String name : source.getPropertyNames()) {
if (encryptValue == null && StringUtils.equalsIgnoreCase("security.is-password-encrypt", name)) {
Object value = source.getProperty(name);
encryptValue = (Boolean) value;
continue;
}
if (StringUtils.isEmpty(symmetricKey) && StringUtils.equalsIgnoreCase("security.symmetric-key", name)) {
Object value = source.getProperty(name);
symmetricKey = (String) value;
continue;
}
if (StringUtils.isEmpty(symmetricEncryptType) && StringUtils.equalsIgnoreCase("security.symmetric-encrypt-type", name)) {
Object value = source.getProperty(name);
symmetricEncryptType = (String) value;
continue;
}
if (this.isEncryption(name, map)) {
Object value = source.getProperty(name);
String str = (String) value;
map.put(name, str);
}
}
}
}
if (!encryptValue) {
// 配置文件密码非加密,直接返回
return;
}
// 将处理的数据放入环境变量,并处于第一优先级上 (这里一定要注意,覆盖其他配置)
if (!map.isEmpty()) {
for (Map.Entry<String, Object> m : map.entrySet()) {
map.put(m.getKey(), SecurityEncryptUtils.symmetricDecryption(String.valueOf(m.getValue()), symmetricKey, symmetricEncryptType));
}
environment.getPropertySources().addFirst(new MapPropertySource("prefixer", map));
}
}
private boolean isEncryption(String name, HashMap<String, Object> map) {
// 配置文件的密码需要经SM4Utils.encrypt 加密处理
if (!map.containsKey("spring.datasource.password") && StringUtils.equalsIgnoreCase("spring.datasource.password", name)) {
return true;
}
if (!map.containsKey("spring.datasource.password") && StringUtils.equalsIgnoreCase("spring.redis.password", name)) {
return true;
}
if (!map.containsKey("spring.datasource.password") && StringUtils.equalsIgnoreCase("spring.data.mongodb.password", name)) {
return true;
}
if (!map.containsKey("spring.datasource.password") && StringUtils.equalsIgnoreCase("dubbo.admin.root.password", name)) {
return true;
}
if (!map.containsKey("dubbo.admin.guest.password") && StringUtils.equalsIgnoreCase("dubbo.admin.guest.password", name)) {
return true;
}
return false;
}
}