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

四、在配置文件中应用

相关推荐
NAGNIP1 小时前
多个 GitHub 账户SSH 密钥配置全攻略
后端
NAGNIP1 小时前
Windows命令行代码自动补全详细步骤
后端
.鸣2 小时前
set和map
java·学习
追逐时光者2 小时前
精选 8 款 .NET 开源、前后端分离的快速开发框架,提高开发生产效率!
后端·.net
ha_lydms2 小时前
5、Spark函数_s/t
java·大数据·python·spark·数据处理·maxcompute·spark 函数
用户47949283569152 小时前
性能提升 4000%!我是如何解决 运营看板 不能跨库&跨库查询慢这个难题的
数据库·后端·postgresql
黄河滴滴3 小时前
java系统变卡变慢的原因是什么?从oom的角度分析
java·开发语言
侠客行03173 小时前
Mybatis二级缓存实现详解
java·mybatis·源码阅读
老华带你飞3 小时前
农产品销售管理|基于java + vue农产品销售管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
Edward111111114 小时前
tomcat_servlet
java·servlet·tomcat