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);
    }

四、在配置文件中应用

相关推荐
蒸蒸yyyyzwd2 小时前
cpp对象模型学习笔记1.1-2.8
java·笔记·学习
qq_297574673 小时前
【实战教程】SpringBoot 集成阿里云短信服务实现验证码发送
spring boot·后端·阿里云
程序员徐师兄3 小时前
Windows JDK11 下载安装教程,适合新手
java·windows·jdk11 下载安装·jdk11 下载教程
RANCE_atttackkk3 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
五岳4 小时前
DTS按业务场景批量迁移阿里云MySQL表实战(下):迁移管理平台设计与实现
java·应用·dts
韩立学长4 小时前
【开题答辩实录分享】以《智能大学宿舍管理系统的设计与实现》为例进行选题答辩实录分享
数据库·spring boot·后端
zhougl9964 小时前
Java 所有关键字及规范分类
java·开发语言
Python 老手5 小时前
Python while 循环 极简核心讲解
java·python·算法
java1234_小锋5 小时前
Java高频面试题:MyISAM索引与InnoDB索引的区别?
java·开发语言
Mr_Xuhhh5 小时前
MySQL函数详解:日期、字符串、数学及其他常用函数
java·数据库·sql