springboot~继承EnvironmentPostProcessor实现对敏感配置的处理 ...

农民  金牌会员 | 2023-10-19 21:20:52 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 897|帖子 897|积分 2691

配置文件中的敏感信息,如密码,账号这些都应该是秘文的,在程序获取时,再将它们动态解密,这样保证了配置信息的安全;在springboot中,有个resources\META-INF\spring.factories文件,他帮我们完成了自动装配,开发过starter包的同学应该不会陌生,而在这个文件里,我们也可以添加自定义的环境拦截器,对环境变量,配置信息等进行处理。
执行时机

EnvironmentPostProcessor 的实现类在 Spring Boot 应用程序启动过程中的早期阶段被加载和执行。具体来说,它们在 Spring Boot 的应用程序上下文创建之前执行。
加载 EnvironmentPostProcessor 的实现类的过程如下:

  • Spring Boot 应用程序启动时,首先会加载并创建一个初始的环境(ConfigurableEnvironment)。
  • 在初始化环境后,Spring Boot 会扫描 classpath 中的 META-INF/spring.factories 文件,以查找并加载配置在其中的 EnvironmentPostProcessor 实现类。
  • 一旦找到这些实现类,它们将被实例化和执行。在这个阶段,你可以在应用程序环境加载之前进行一些自定义的配置或修改。
这使得 EnvironmentPostProcessor 成为一个非常早期的扩展点,允许你在应用程序环境初始化之前介入,并根据需要修改属性源、配置属性等。这对于在应用程序启动时执行高级的自定义配置非常有用。
starter中的注册

spring.factories 是 Spring Boot 中的一个特殊配置文件,用于自动装配(auto-configuration)和其他 Spring Boot 特性的配置。在 spring.factories 文件中,你可以指定各种 Spring Boot 自动配置和其他扩展的类,包括 EnvironmentPostProcessor。
EnvironmentPostProcessor 是 Spring Boot 的一个扩展点,用于在 Spring 应用程序的环境(Environment)加载之后进行额外的自定义配置。具体来说,EnvironmentPostProcessor 允许你在 Spring Boot 应用程序启动时修改环境属性,这对于一些高级配置需求非常有用。
通过在 spring.factories 中配置 EnvironmentPostProcessor,你可以实现一些高级的环境配置,例如根据特定条件动态修改属性值,或者加载外部配置源。这为应用程序提供了更大的灵活性,允许你在应用程序启动之前对环境进行精细的调整。
  1. # Auto Configure
  2. org.springframework.boot.env.EnvironmentPostProcessor=\
  3.   com.lind.common.env.MpwEnvironmentPostProcessor
复制代码
自定义EnvironmentPostProcessor类,对敏感字符进行解密
  1. /**
  2. * 处理配置中的敏感信息,读配置时完成解密操作.
  3. *
  4. * @author lind
  5. * @date 2023/10/9 8:33
  6. * @since 1.0.0
  7. */
  8. public class EnvironmentPostProcessorDemo implements EnvironmentPostProcessor {
  9.         static final String MPW = "mpw.key";
  10.         static Logger logger = LoggerFactory.getLogger(EnvironmentPostProcessorDemo.class);
  11.         public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
  12.                 String mpwKey = null;
  13.                 for (PropertySource<?> ps : (Iterable<PropertySource<?>>) environment.getPropertySources()) {
  14.                         if (ps instanceof SimpleCommandLinePropertySource) { // jvm启动时命令行参数
  15.                                 SimpleCommandLinePropertySource source = (SimpleCommandLinePropertySource) ps;
  16.                                 mpwKey = source.getProperty(MPW);
  17.                                 break;
  18.                         }
  19.                         if (ps instanceof OriginTrackedMapPropertySource) {// application.yml
  20.                                 OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) ps;
  21.                                 if (source.containsProperty(MPW))
  22.                                         mpwKey = source.getProperty(MPW).toString();
  23.                                 break;
  24.                         }
  25.                 }
  26.                 if (StringUtils.isNotBlank(mpwKey)) {
  27.                         HashMap<String, Object> map = new HashMap<>();
  28.                         for (PropertySource<?> ps : (Iterable<PropertySource<?>>) environment.getPropertySources()) {
  29.                                 if (ps instanceof OriginTrackedMapPropertySource) {
  30.                                         OriginTrackedMapPropertySource source = (OriginTrackedMapPropertySource) ps;
  31.                                         for (String name : source.getPropertyNames()) {
  32.                                                 Object value = source.getProperty(name);
  33.                                                 if (value instanceof String) {
  34.                                                         String str = (String) value;
  35.                                                         if (str.startsWith("mpw:")) {
  36.                                                                 String decrypt = AESNetUtils.decrypt(str.substring(4), mpwKey);
  37.                                                                 map.put(name,decrypt );
  38.                                                         }
  39.                                                 }
  40.                                         }
  41.                                 }
  42.                         }
  43.                         if (MapUtils.isNotEmpty(map))
  44.                                 environment.getPropertySources()
  45.                                                 .addFirst((PropertySource) new MapPropertySource("custom-encrypt", map));
  46.                 }
  47.         }
  48. }
复制代码
使用


  • application.yml
  1. mpw:
  2.   key: lind123456123456
  3. author:
  4.   name: mpw:vpTzfVrH5eEbsFmSJO9bSw==
  5.   nationality: mpw:vFLIjoQXy4Pzo1/hOm8hWw==
复制代码

  • 单元测试代码
  1. @Test
  2. public void mpwTest() {
  3.         // AESNetUtils.encrypt("中国人", "lind123456123456");//vFLIjoQXy4Pzo1/hOm8hWw==
  4.         System.out.println(SpringContextUtils.getEnvironment().getProperty("author.name"));
  5.         System.out.println(SpringContextUtils.getEnvironment().getProperty("author.nationality"));
  6. }
  7.        
复制代码

  • 测试结果


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农民

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表