Springboot自定义配置解密处理器

org.springframework.boot.env.EnvironmentPostProcessor是一个"环境后处理器",让你有机会在应用启动的早期阶段,动态地添加、修改或删除环境中的属性(Properties),比如来自配置文件 (application.yml)、系统属性、命令行参数等的值。

一、创建一个类实现 EnvironmentPostProcessor 接口

java 复制代码
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 系统环境后置处理器
 */
@Slf4j
public class DecryptEnvPostProcessor implements EnvironmentPostProcessor {

    private static final Set<String> ENCRYPTED_KEYS = Set.of(
            "spring.datasource.password"
    );

    private static final AES aes = SecureUtil.aes("Encrypt-20251106".getBytes());

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication application) {
        Map<String, Object> decryptedValues = new HashMap<>();
        for (PropertySource<?> source : env.getPropertySources()) {
            if (!(source instanceof EnumerablePropertySource<?> eps)) {
                continue;
            }
            for (String keyName : eps.getPropertyNames()) {
                if (!ENCRYPTED_KEYS.contains(keyName)) {
                    continue;
                }
                Object value = eps.getProperty(keyName);
                if (!(value instanceof String strValue)) {
                    continue;
                }
                //判断是否为加密值(用ENC()包裹)
                if (!strValue.startsWith("ENC(") || !strValue.endsWith(")")) {
                    continue;
                }
                String cipherText = strValue.substring(4, strValue.length() - 1);
                try {
                    //解密
                    String plainText = aes.decryptStr(cipherText);
                    decryptedValues.put(keyName, plainText);
                } catch (Exception e) {
                    log.error("解密配置项 [" + keyName + "] 失败,保持原密文: " + e.getMessage());
                }
            }
        }
        //将解密后的值添加到最高优先级的PropertySource中
        if (!decryptedValues.isEmpty()) {
            MapPropertySource decryptedPropertySource = new MapPropertySource("decryptedProperties", decryptedValues);
            env.getPropertySources().addFirst(decryptedPropertySource);
        }
    }
}

二、在 src/main/resources/META-INF/spring.factories 文件中进行声明

java 复制代码
org.springframework.boot.env.EnvironmentPostProcessor=com.**.config.DecryptEnvPostProcessor

三、生成密码

java 复制代码
    @Test
    public void test() {
        AES aes = SecureUtil.aes("Encrypt-20251106".getBytes());
        //加密
        String encryptHex = aes.encryptHex("123456");
        log.info("加密后 (Hex): " + encryptHex);
        //解密
        String decryptStr = aes.decryptStr(encryptHex);
        log.info("解密后: " + decryptStr);
    }

四、在配置文件中应用

相关推荐
坚持就完事了3 小时前
数据结构之树(Java实现)
java·算法
Monly213 小时前
Java:修改打包配置文件
java·开发语言
roman_日积跬步-终至千里3 小时前
【架构设计与实现】动态数据源切换:核心代码实现手册
java
毕设源码_廖学姐3 小时前
计算机毕业设计springboot招聘系统网站 基于SpringBoot的在线人才对接平台 SpringBoot驱动的智能求职与招聘服务网
spring boot·后端·课程设计
XiaoFan0123 小时前
免密批量抓取日志并集中输出
java·linux·服务器
顾北123 小时前
MCP服务端开发:图片搜索助力旅游计划
java·spring boot·dubbo
我命由我123453 小时前
Android 广播 - 静态注册与动态注册对广播接收器实例创建的影响
android·java·开发语言·java-ee·android studio·android-studio·android runtime
赛姐在努力.3 小时前
【拓扑排序】-- 算法原理讲解,及实现拓扑排序,附赠热门例题
java·算法·图论
yxc_inspire3 小时前
Java学习第二天
java·面向对象
毕设源码-赖学姐3 小时前
【开题答辩全过程】以 基于net超市销售管理系统为例,包含答辩的问题和答案
java