5

I am trying to move from spring to micronaut. Some of the property values are encrypted, and we are currently using the spring-boot-jasypt, described below, to help decrypt the property values when injecting into the spring application.

However, I have not been able to find a way to add a property encryptor in micronaut framework to let me do the same. Does anyone know a way to do that in micronaut?

https://www.baeldung.com/spring-boot-jasypt

Ajeet Verma
  • 1,021
  • 1
  • 7
  • 25
fzhong
  • 51
  • 1

2 Answers2

2

The following approach works for me. Create @Context annotated Singleton which is will be created before all other beans. At the time of creation Environment is already initialised and all configuration properties are loaded. Next find all properties having started with special prefix defining encrypted value. Create new property source with decrypted values and put it into Environment as new PropertySource.

Code:

@Context
@Singleton
@Requires(property = "JASYPT_ENCRYPTOR_PASSWORD")
@Slf4j
public class JasyptConfigurationPropertiesDecryptor implements BeanInitializedEventListener<Environment>  {
    private static final String PREFIX = "ENC(";

    public JasyptConfigurationPropertiesDecryptor(DefaultEnvironment env, @Value("${JASYPT_ENCRYPTOR_PASSWORD}") String encPassword) {
        log.info("JasyptBootstrapDecryptor started");
        processConfigurationProperties(env, encPassword);
    }

    public void processConfigurationProperties(DefaultEnvironment env, String encPassword) {
        StandardPBEStringEncryptor encryptor = encryptor(encPassword);
        Map<String, Object> all = env.getAllProperties(StringConvention.RAW, MapFormat.MapTransformation.FLAT);
        Map<String, Object> decrypted = all.entrySet().stream()
                                           .filter(entry -> entry.getValue().toString().startsWith(PREFIX))
                                           .collect(collector(encryptor));

        env.addPropertySource(MapPropertySource.of("decrypted", decrypted));
    }

    private StandardPBEStringEncryptor encryptor(String encPassword) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword(encPassword);
        encryptor.setStringOutputType("base64");
        encryptor.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
        encryptor.setIvGenerator(new RandomIvGenerator());
        return encryptor;
    }

    @Nonnull
    private Collector<Map.Entry<String, Object>, ?, Map<String, Object>> collector(StandardPBEStringEncryptor encryptor) {
        return Collectors.toMap(Map.Entry::getKey, entry -> decrypt(entry, encryptor));
    }

    private String decrypt(Map.Entry<String, Object> entry, StandardPBEStringEncryptor encryptor) {
        log.info("Decrypt \"{}\" configuration property", entry.getKey());
        String encrypted = entry.getValue().toString().substring(PREFIX.length(), entry.getValue().toString().length() - 1);
        return encryptor.decrypt(encrypted);
    }

    @Override
    public Environment onInitialized(BeanInitializingEvent<Environment> event) {
        return event.getBean();
    }


}
0

I'm new to micronaut myself. But the best I found so far is to put encrypted properties into a separate file, load and decrypt them myself at start up and add them unencrypted to java system properties (or anywhere else where I know micronaut will find them). All this should be done before initializing or starting Micronaut context. Then I can refer to those properties from micronaut's configuration files using ${...} value placeholder notation.

More idiomatic approach seems to be to implement and register your own PropertySourceLoader, but it's much more effort and result is pretty much same - it still requires putting encrypted properties into a separate file.

If you want to keep encrypted properties where they are, the best I approach can find is to load all properties yourself and then supply them to micronaut as PropertySources. But that sort of throws away big chunk of micronaut's configuration support and in my books defeats the purpose.

Seva
  • 2,388
  • 10
  • 9