Skip to content

Instantly share code, notes, and snippets.

@efenderbosch
Created January 12, 2015 14:39
Show Gist options
  • Save efenderbosch/6839a7864d520766d240 to your computer and use it in GitHub Desktop.
Save efenderbosch/6839a7864d520766d240 to your computer and use it in GitHub Desktop.
Encryptable YAML for Spring Boot
public class EncryptablePropertiesPropertySource extends MapPropertySource {
@SuppressWarnings({ "unchecked", "rawtypes" })
public EncryptablePropertiesPropertySource(String name, Properties source) {
super(name, (Map) source);
}
protected EncryptablePropertiesPropertySource(String name, Map<String, Object> source) {
super(name, source);
}
@Override
public Object getProperty(String name) {
if (StringUtils.startsWithIgnoreCase(name, "encrypted") && !"encrypted.key".equalsIgnoreCase(name)) {
String key = (String) super.getProperty("encrypted.key");
String encrypted = (String) super.getProperty(name);
try {
return CryptoUtil.decrypt(key, encrypted);
} catch (GeneralSecurityException e) {
throw new PropertyDecryptionException(name, e);
}
}
return super.getProperty(name);
}
}
/**
* this is loaded by specifying
* org.springframework.boot.env.PropertySourceLoader in
* META-INF/spring.factories
*/
public class EncryptedYamlPropertySourceLoader extends YamlPropertySourceLoader implements PriorityOrdered {
@Override
public PropertySource<?> load(String name, Resource resource, String profile) throws IOException {
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
Processor processor = new Processor(resource, profile);
Map<String, Object> source = processor.process();
if (!source.isEmpty()) {
return new EncryptablePropertiesPropertySource(name, source);
}
}
return null;
}
/**
* {@link YamlProcessor} to create a {@link Map} containing the property
* values. Similar to {@link YamlPropertiesFactoryBean} but retains the
* order of entries.
*/
private static class Processor extends YamlProcessor {
public Processor(Resource resource, String profile) {
if (profile == null) {
setMatchDefault(true);
setDocumentMatchers(new SpringProfileDocumentMatcher());
} else {
setMatchDefault(false);
setDocumentMatchers(new SpringProfileDocumentMatcher(profile));
}
setResources(new Resource[] { resource });
}
public Map<String, Object> process() {
final Map<String, Object> result = new LinkedHashMap<>();
process(new MatchCallback() {
@Override
public void process(Properties properties, Map<String, Object> map) {
result.putAll(getFlattenedMap(map));
}
});
return result;
}
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment