Расшифровка весенних свойств - PullRequest
10 голосов
/ 06 мая 2019

У нас есть несколько унаследованных весенних приложений, которые еще не переведены на весеннюю загрузку или весеннее облако, а также весенние загрузочные приложения. Я работаю над созданием компонента Spring, который будет автоматически расшифровывать свойства Spring при загрузке среды, если значение свойства зашифровано и имеет префикс. Свойства могут быть в файлах .properties (для устаревших приложений) или в файлах .yaml (более новые весенние загрузочные приложения).

Компонент должен иметь возможность дешифровать любое свойство пружины независимо от источника и должен работать с любой версией пружины, не привязанной к загрузке пружины. Компонент также должен прозрачно дешифровать свойства. Он должен прочитать парольную фразу из файла свойств, поэтому файл парольной фразы необходимо загрузить в начале.

У нас есть собственный ecrypt / decrypt и мы не хотим использовать jaspyt.

То, что пытались до сих пор:

Мне понравился этот подход к созданию ApplicationListener, но он связан с весенней загрузкой (ApplicationEnvironmentPreparedEvent). С событиями Spring, такими как ContextRefreshed или ContextStart, я не вижу, как я могу получить ConfigurableApplicationContext / ConfigurableEnvironment. Кто-нибудь создал Listener для шифрования / дешифрования без весенней загрузки / облака?

Я также создал собственный ApplicationContextInitializer и добавил его в context-param web.xml, но, похоже, это не работает. Когда я отлаживаю в нем, я не думаю, что это загрузка / чтение свойств из моего файла app.properties.

       @Component
    public class DecryptingPropertyContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
       public void initialize( ConfigurableApplicationContext applicationContext ) {
          ConfigurableEnvironment environment = applicationContext.getEnvironment();
          for ( PropertySource<?> propertySource : environment.getPropertySources() ) {
             Map<String, Object> propertyOverrides = new LinkedHashMap<>();
             decodePasswords( propertySource, propertyOverrides );
             if ( !propertyOverrides.isEmpty() ) {
                PropertySource<?> decodedProperties = new MapPropertySource( "decoded " + propertySource.getName(),
                      propertyOverrides );
                environment.getPropertySources().addBefore( propertySource.getName(), decodedProperties );
             }
          }
       }

        private void decodePasswords(PropertySource<?> source, Map<String, Object> propertyOverrides) {
          if ( source instanceof EnumerablePropertySource ) {
             EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) source;
             for ( String key : enumerablePropertySource.getPropertyNames() ) {
                Object rawValue = source.getProperty( key );
                if ( rawValue instanceof String ) {
                   //decrypt logic here
propertyOverrides.put( key, decryptedValue );
                }
             }
          }
        }
    }

Кто-нибудь должен был сделать что-то подобное или есть идеи получше? Есть ли способ, которым я могу слушать события приложения и затем обрабатывать? Ценю вашу помощь

1 Ответ

2 голосов
/ 17 мая 2019

Вы можете написать свой собственный PropertiesFactoryBean и переопределить createProperties для расшифровки зашифрованных значений:

public class DecryptingPropertiesFactoryBean extends PropertiesFactoryBean {
  @Override
  protected Properties createProperties() throws IOException {
    final Properties encryptedProperties = super.createProperties();
    final Properties decryptedProperties = decrypt(encryptedProperties);
    return decryptedProperties;
  }
}

и PropertySourcesPlaceholderConfigurer bean-компонента, используя следующие свойства:

@Configuration
public class PropertiesConfiguration {

  @Bean
  public static DecryptingPropertiesFactoryBean propertyFactory() {
    final DecryptingPropertiesFactoryBean factory = new DecryptingPropertiesFactoryBean();
    final Resource[] propertyLocations = new Resource[] {
        new FileSystemResource(new File("path/to/file.properties"))
    };
    factory.setLocations(propertyLocations);
    return factory;
  }

  @Bean
  public static Properties properties() throws Exception {
    return propertyFactory().getObject();
  }

  @Bean
  public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    final PropertySourcesPlaceholderConfigurer bean = new PropertySourcesPlaceholderConfigurer();
    bean.setIgnoreResourceNotFound(true);
    bean.setIgnoreUnresolvablePlaceholders(false);
    bean.setProperties(properties());
    return bean;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...