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

四、在配置文件中应用

相关推荐
人间凡尔赛几秒前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
码上有光2 分钟前
异常和智能指针
java·大数据·c++·servlet·异常·智能指针
吴声子夜歌10 分钟前
MongoDB 4.x——SpringBoot框架整合
数据库·spring boot·mongodb
IT_陈寒17 分钟前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境18 分钟前
提升 Python 代码健壮性的方法大盘点
后端·python
snow@li20 分钟前
Spring Boot:项目服务器完整部署教程(零基础可直接实操)
服务器·spring boot·后端
卷无止境1 小时前
Python 异常处理:从入门到工程实践
后端·python
AINative软件工程1 小时前
LLM 应用的熔断降级工程实践:Circuit Breaker 不只是重试的升级版
后端·llm·ai编程
学计算机的计算基1 小时前
操作系统内存管理全解:虚拟内存、页表、COW、malloc、OOM一篇搞定
java·笔记·算法