springboot自定义配置文件密码加密解密
最近在搭建微服务框架封装基础工具包的时候用到了很多有关spring boot配置文件相关的知识,今天讲一下我在研究spring boot 配置文件属性加密解密过程中的收获。相关文档查看进行思路构建通过spring boot 官方文档查询到了:Customize the Environment or ApplicationContext Before It Starts 在启动环境或Applicat
最近在搭建微服务框架封装基础工具包的时候用到了很多有关spring boot配置文件相关的知识,今天讲一下我在研究spring boot 配置文件属性加密解密过程中的收获。
相关文档查看进行思路构建
通过spring boot 官方文档查询到了:
Customize the Environment or ApplicationContext Before It Starts 在启动环境或ApplicationContext之前定制它
一个SpringApplication 拥有用于对上下文或环境应用自定义的ApplicationListeners 和ApplicationContextInitializers。
Spring boot引导会从META-INF/ Spring .factories中加载大量这样的定制,以供内部使用。
这里有多种注册其他自定义的方法:
- 编程的方式,通过在SpringApplication 启动之前调用addListeners 和addInitializers方法进行注册。
- 声明式,通过设置context.initializer.classes or context.listener.classes的配置。
- 声明式,通过添加一个META-INF/spring.factories文件 ,打包成jar让应用程序当作库调用。
SpringApplication 发送一个事件ApplicationEvents去监听(在上下文创建之前),然后为ApplicationContext发布的事件注册侦听器。
还可以通过EnvironmentPostProcessor在刷新应用程序上下文之前定制Environment 。
每个实现都应该注册到文件META-INF/spring.factories中,如下示例:org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
该实例可以加载任意模块并且添加到Environment,例如,下面的示例从类路径加载一个YAML配置文件:
public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Resource path = new ClassPathResource("com/example/myapp/config.yml");
PropertySource<?> propertySource = loadYaml(path);
environment.getPropertySources().addLast(propertySource);
}
private PropertySource<?> loadYaml(Resource path) {
if (!path.exists()) {
throw new IllegalArgumentException("Resource " + path + " does not exist");
}
try {
return this.loader.load("custom-resource", path).get(0);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
}
}
}
查询到的一些教程:EnvironmentPostProcessor in Spring Boot
思路
我们可以通过自定义Environment,来在应用程序上下问创建之前,获取配置文件的属性信息进行相应的操作,来达到我们想要的配置文件加密解密效果。
自定义实现
创建一个项目文件在里面添加一个类SafetyEncryptProcessor通过实现EnvironmentPostProcessor的postProcessEnvironment方法,然后将EnvironmentPostProcessor注册到文件META-INF/spring.factories,然后让其他应用程序依赖,这样我们可以实现对配置文件相应配置的修改,简单示例如下:
项目目录结构
package com.tools.encrypt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import java.util.HashMap;
/**
* @author Mr.Deng
* @date 2020/8/6 18:00
* <p>Copyright: Copyright (c) 2020</p>
*/
public class SafetyEncryptProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
HashMap<String, Object> map = new HashMap<>();
for (PropertySource<?> ps : environment.getPropertySources()) {
if (ps instanceof OriginTrackedMapPropertySource) {
OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) ps;
for (String name : source.getPropertyNames()) {
Object value = source.getProperty(name);
System.out.println("value ======= " + value);
if (value instanceof String) {
String str = (String) value;
if (str.startsWith("mpen:")) { //mpen: 需要处理的value的前缀
map.put(name, "123456"); //此处的12345可自定义为对value的处理
}
}
}
}
}
// 将处理的数据放入环境变量,并处于第一优先级上 (这里一定要注意,覆盖其他配置)
if (!map.isEmpty()) {
environment.getPropertySources().addFirst(new MapPropertySource("prefixer", map));
}
}
}
META-INF/spring.factories配置
org.springframework.boot.env.EnvironmentPostProcessor=\
com.tools.encrypt.SafetyEncryptProcessor
pom引入jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.tools</groupId>
<artifactId>cloud-tools-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>cloud-common-encrypt</artifactId>
<name>cloud-common-encrypt</name>
<modelVersion>4.0.0</modelVersion>
<description>配置文件加解密</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
调用应用程序
- 引入pom
<dependency>
<groupId>com.tools</groupId>
<artifactId>cloud-common-encrypt</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
- 配置文件使用
my:
name: mpen:abcdefg
- 然后运行调用引用程序
就可以查看到my.name的配置属性的值读出来是123456,而不是配置文件里面写的** mpen:abcdefg**了。
总结
当然这里只是提到了思路和简单的实现,然而密码加密的实现可以参考自定义实现 对value进行解密处理,然后添加加密模块,或者添加自定义自动配置,进行相关的密钥的配置来使得配置文件加密的密文更加的安全。
这些都是自己的见解,如有什么不足之处,欢迎留言交流,谢谢阅读:)
更多推荐
所有评论(0)