Spring Boot - 配置信息后处理
最近在做项目的过程中,PSS提出配置文件中类似数据库连接需要的用户名、密码等敏感信息需要加密处理(之前一直是明文的)。
为了快速完成任务,网上搜刮到jasypt包,也有相应的starter,使用方法可以参考blog
但是还是想具体弄清楚背后的实现。偶然看到Spring Boot中有个EnvironmentPostProcessor接口。看名字,它的实现类应该在配置文件加载完和Spring容器开始初始化之前起作用。这样的话,我们就可以实现该接口用来定制化配置信息,包括解密。
话不多说,show code,
@Component
public class DecryptAESConfigProcessor implements EnvironmentPostProcessor { private static short INDEX = 0;
private static String ITEM_FORMAT = "spring.config.decrypt-items[%d]";
private static Pattern PATTERN = Pattern.compile("AES\\((.+)\\)");
private static StringBuffer SB = new StringBuffer(); @Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
MutablePropertySources propertySources = environment.getPropertySources();
for (PropertySource propertySource: propertySources) {
if (propertySource instanceof OriginTrackedMapPropertySource){
INDEX = 0;
OriginTrackedMapPropertySource otmps = (OriginTrackedMapPropertySource)propertySource;
//System.out.println("property name = " + otmps.getName());
Map<String, Object> source = otmps.getSource();
String secretSalt = source.getOrDefault("spring.config.secret-salt", "").toString();
if (!"".equals(secretSalt)){
String salt = CommonUtil.decrypt(secretSalt, "sns");
while (INDEX > -1){
String item = String.format(ITEM_FORMAT, INDEX);
if (source.containsKey(item)){
String itemValue = source.get(item).toString();
String propertyValue = source.getOrDefault(itemValue, "").toString();
Matcher matcher = PATTERN.matcher(propertyValue);
boolean findAES = false;
while (matcher.find()){
//decrypt each AES()
findAES = true;
String decryptStr = CommonUtil.decrypt(matcher.group(1), salt);
matcher.appendReplacement(SB, decryptStr);
}
if (!findAES){
//decrypt entire item
source.put(itemValue, CommonUtil.decrypt(propertyValue, salt));
} else {
matcher.appendTail(SB);
source.put(itemValue, SB.toString());
}
SB.delete(0, SB.length());
INDEX++;
} else {
INDEX = -1;
}
}
}
}
} }
} 注意:需要将DecryptAESConfigProcessor声明到spring.factories中。 org.springframework.boot.env.EnvironmentPostProcessor=\
org.chris.springboot.config_encrypt.config.DecryptAESConfigProcessor

public class CommonUtil {
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
private static Cipher CIPHER;
private static KeyGenerator KEY_GENERATOR;
static {
try {
CIPHER = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
KEY_GENERATOR = KeyGenerator.getInstance(KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
/**
* Decrypt by AES
* @param content
* @param salt
* @return
*/
public static String decrypt(String content, String salt) {
if (Objects.nonNull(content)) {
try {
byte[] decrypted = Base64.getDecoder().decode(content.getBytes("UTF-8"));
CIPHER.init(Cipher.DECRYPT_MODE, getSecretKey(salt));
return new String(CIPHER.doFinal(decrypted));
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* Encrypt by AES
* @param content
* @param salt
* @return
*/
public static String encrypt(String content, String salt) {
if (Objects.nonNull(content)) {
try {
CIPHER.init(Cipher.ENCRYPT_MODE, getSecretKey(salt));
byte[] encrypted = CIPHER.doFinal(content.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encrypted);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* Generate encrypted salt
* @param salt
* @return
*/
private static SecretKeySpec getSecretKey(final String salt) {
KEY_GENERATOR.init(128, new SecureRandom(salt.getBytes()));
SecretKey secretKey = KEY_GENERATOR.generateKey();
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
}
}
最后,配置文件中需要有类似以下配置项


解密规则如下,
1. 采用AES加密解密;
2. 在配置文件中
(1) 通过spring.config.decrypt-items指定需要解密的配置
(2) 通过spring.config.secret-salt指定AES的key(最好加密)
3. 如果需要解密的配置项中存在AES()模式的字符串,将会解密 () 中的内容,否则解密整个配置项
Spring Boot - 配置信息后处理的更多相关文章
- Redis篇之操作、lettuce客户端、Spring集成以及Spring Boot配置
Redis篇之操作.lettuce客户端.Spring集成以及Spring Boot配置 目录 一.Redis简介 1.1 数据结构的操作 1.2 重要概念分析 二.Redis客户端 2.1 简介 2 ...
- Spring Boot 配置优先级顺序
一般在一个项目中,总是会有好多个环境.比如: 开发环境 -> 测试环境 -> 预发布环境 -> 生产环境 每个环境上的配置文件总是不一样的,甚至开发环境中每个开发者的环境可能也会有一 ...
- spring boot配置springMVC拦截器
spring boot通过配置springMVC拦截器 配置拦截器比较简单, spring boot配置拦截器, 重写preHandle方法. 1.配置拦截器: 2重写方法 这样就实现了拦截器. 其中 ...
- spring boot配置mybatis和事务管理
spring boot配置mybatis和事务管理 一.spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spri ...
- Spring Boot 配置元数据指南
1. 概览 在编写 Spring Boot 应用程序时,将配置属性映射到 Java bean 上是非常有用的.但是,记录这些属性的最好方法是什么呢? 在本教程中,我们将探讨 Spring Boot C ...
- spring boot 配置虚拟静态资源文件
我们实现的目的是:通过spring boot 配置静态资源访问的虚拟路径,可实现在服务器,或者在本地通过:http://ip地址:端口/资源路径/文件名 ,可直接访问文件 比如:我们本地电脑的:E: ...
- Spring Boot配置,读取配置文件
Spring Boot配置,读取配置文件 一.配置Spring Boot 1.1 服务器配置 1.2 使用其他Web服务器 1.3 配置启动信息 1.4 配置浏览器显示ico 1.5 Yaml语法 1 ...
- Spring Boot -- 配置切换指南
一般在一个项目中,总是会有好多个环境.比如: 开发环境 -> 测试环境 -> 预发布环境 -> 生产环境 每个环境上的配置文件总是不一样的,甚至开发环境中每个开发者的环境可能也会有一 ...
- spring boot 配置注入
spring boot配置注入有变量方式和类方式(参见:<spring boot 自定义配置属性的各种方式>),变量中又要注意静态变量的注入(参见:spring boot 给静态变量注入值 ...
随机推荐
- 洛谷—— P1022 计算器的改良
P1022 计算器的改良 题目背景 NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能.实验室将这个任务交给了 ...
- 反汇编引擎Capstone
反汇编引擎Capstone Capstone是Kali Linux自带的一款轻量级反汇编引擎.它可以支持多种硬件构架,如ARM.ARM64.MIPS.X86.该框架使用C语言实现,但支持C++.P ...
- Linux下将MySQL服务添加到服务器的系统服务中
Linux下将MySQL服务添加到服务器的系统服务中 Linux环境下将MySQL服务添加到服务器的系统服务中 1.了解MySQL程序路径 MySQL数据目录: /home/mysql/dataMyS ...
- TranslateAnimation详解 Android动画。
TranslateAnimation详解 Android JDK为我们提供了4种动画效果,分别是: AlphaAnimation,RotateAnimation, ScaleAnimation, Tr ...
- Visio中汇总两个箭头
RT,相似度和信任度矩阵融合,两个箭头,选中其中一个,可以选格式--线条--终点选无,或者在快捷那选线条.
- mybatis学习笔记(六)使用generator生成mybatis基础配置代码和目录结构
原文:http://blog.csdn.net/oh_mourinho/article/details/51463413 创建maven项目 <span style="font-siz ...
- nginx,wsgi,django的关系
http://blog.csdn.net/lihao21/article/details/52304119 wsgi用于连续 nginx和django,客户端发来的请求,先经过wsgi,然后再传给dj ...
- ios开发 Socket通信
Socket描述了一个IP.端口对.它简化了程序员的操作,知道对方的IP以及PORT就可以给对方发送消息,再由服务器端来处理发送的这些消息.所以,Socket一定包含了通信的双发,即客户端(Clien ...
- eclipse进行Debug的时候,发出“java breakpoint unable to install breakpoint”错误
错误情况图: 问题的解决方法: 直接点击忽略掉:Don't tell me again 来自网上的答案~~ I had the same error message in Eclipse 3.4.1, ...
- Makefile之文件搜索
Makefile之文件搜索 1.Makefile 文件中的"VPATH"变量 如果没有指明这个变量,make只会在当前目录下查找依赖文件和目标文件: 如果定义了这个变量,make会 ...