springboot 自定义配置文件加密规则
时间:2022-08-08
本文章向大家介绍springboot 自定义配置文件加密规则,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一般情况下,我们做项目的时候,中间件例如mysql,redis, zk 的账号密码一般都是写在配置文件里面的, 这样代码泄露的情况下, 就很不安全。
由第三方的加密的工具 jasypt 这种jar包。 这里我们仿写它来实现自己的配置文件加密规则。
jasypt 连接:https://github.com/ulisesbocchio/jasypt-spring-boot
具体的使用大家看我发的地址。
这里我们要用到ConfigurableEnviroment 这个类,我们来看一下源码
public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver {
void setActiveProfiles(String... var1);
void addActiveProfile(String var1);
void setDefaultProfiles(String... var1);
// resource 文件多个,这个可以是classpath ,file ,default 的
MutablePropertySources getPropertySources();
// 获取系统配置文件
Map<String, Object> getSystemProperties();
// 获取系统环境变量
Map<String, Object> getSystemEnvironment();
void merge(ConfigurableEnvironment var1);
}
首先我们要自己写一个类实现BeanFactoryPostProcessor ,和order 接口
public class PropertiesEncryptionConfig implements BeanFactoryPostProcessor, Ordered {
// 前缀的key
public static final String PREFIX_PROPERTY = "xxxxx.encrypt.prefix";
// 后缀的key
public static final String SUFFIX_PROPERTY = "xxxxx.encrypt.suffix";
// 私钥的key
public static final String RSA_PRIVATE_KEY_PROPERTY = "xxxxx.encrypt.privateKey";
// 前缀默认值
public static final String DEFAULT_PREFIX = "xxxxx[";
//后缀默认值
public static final String DEFAULT_SUFFIX = "]";
private static final Logger LOG = LoggerFactory.getLogger(PropertiesEncryptionConfig.class);
// 在通过@bean 注入进来
public ConfigurableEnvironment environment ;
public PropertiesEncryptionConfig(ConfigurableEnvironment environment) {
this.environment = environment;
}
private String prefix;
private String suffix;
private String privateKey;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
MutablePropertySources propertySources = environment.getPropertySources();
for (PropertySource<?> propertySource : propertySources) {
if (propertySource instanceof OriginTrackedMapPropertySource) {
// 只有这个才是加载properties 文件的,getsource 返回的就是map
OriginTrackedMapPropertySource om = (OriginTrackedMapPropertySource) propertySource;
Map<String, Object> source = om.getSource();
source.forEach((k, v) -> {
String property = environment.getProperty(k);
if (hasPreAndSuf(property)) {
LOG.info("开始处理 k = [{}]", k);
try {
String relay = splitPreAndSuf(property, this.prefix, this.suffix);
// 这里获取去掉前缀后缀的值 在通过自己的解密规则 ,
//这里 AesUtils 可以搞成注入模式, 这样使用的时候可以进行加密。自己写aes 的加密工具类
String decrypt = AesUtils.aesDecrypt(relay, getPrivateKey(environment));
source.put(k, decrypt);
}
catch (Exception e) {
LOG.error("配置文件加密异常错误信息: ", e);
}
}
});
}
}
}
private String getPrivateKey(ConfigurableEnvironment environment) throws Exception {
// 支持从系统环境变量 java -jar 运行的时候获取
this.privateKey = System.getProperty(RSA_PRIVATE_KEY_PROPERTY, "");
if (StringUtils.hasText(this.privateKey)) {
return this.privateKey;
}
// 支持从文件获取
this.privateKey = environment.getProperty(RSA_PRIVATE_KEY_PROPERTY);
if (StringUtils.hasText(this.privateKey)) {
return this.privateKey;
}
// 都没有就会报错
throw new Exception(" properties aes private key is null!");
}
// 判断一下,前缀后缀是否匹配
private boolean hasPreAndSuf(String property) {
return property.startsWith(getPrefix(environment)) && property.endsWith(getSuffix(environment));
}
// 去掉前缀后缀获取中间值
protected String splitPreAndSuf(String str, String prefix, String suffix) {
return str.replace(prefix, "").replace(suffix, "");
}
// 获取后缀,没有使用默认值
private String getSuffix(ConfigurableEnvironment environment) {
this.suffix = environment.getProperty(SUFFIX_PROPERTY);
if (StringUtils.hasLength(suffix)) {
return this.suffix;
}
this.suffix = DEFAULT_SUFFIX;
return DEFAULT_SUFFIX;
}
// 获取前缀,使用默认值
private String getPrefix(ConfigurableEnvironment environment) {
this.prefix = environment.getProperty(PREFIX_PROPERTY);
if (StringUtils.hasLength(prefix)) {
return this.prefix;
}
this.prefix = DEFAULT_PREFIX;
return DEFAULT_PREFIX;
}
/**
* 提高优先级
* @return
*/
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE -100;
}
}
@Configuration
public class EnablePropertiesEncryption {
@Bean
public PropertiesEncryptionConfig getPropertiesEncryption(ConfigurableEnvironment configurableEnvironment){
return new PropertiesEncryptionConfig(configurableEnvironment);
}
// 加密解密工具类 ,可以在spring单元测试使用@Autowired注入
@Bean
public AesUtils getAes(){
return new AesUtils();
}
}
这样我们就基本实现了jasypt 的功能。
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- nginx 修改配置文件使之支持pathinfo,且隐藏index.php
- 微信jssdk开发,PHP,必要步骤
- 微信JSSDK分享页面自定义当前链接最简单示例
- (一)python3 只需3小时带你轻松入门—— 编程尝试
- (二)python3 只需3小时带你轻松入门——基本变量
- (三)python3 只需3小时带你轻松入门—— 变量的简单运算
- (四)python3 只需3小时带你轻松入门—— 流程控制
- (五)python3 只需3小时带你轻松入门—— 逻辑运算符
- (六)python3 只需3小时带你轻松入门——循环
- (七)python3 只需3小时带你轻松入门——List与dict
- Rstudio支持可视化的Markdown编辑了?
- (八)python3 只需3小时带你轻松入门——List 与 dict 的常用操作
- (九)python3 只需3小时带你轻松入门——函数自定义
- (十)python3 只需3小时带你轻松入门——模块与包
- (十一)python3 只需3小时带你轻松入门——面向对象