Spring does allow for the method ''convertPropertyValue'' to be overridden but it only passes the value from the property file and you actually do not have any idea which property name it is associated with. So this makes it diffcult to know whether you need to perform any additional processing on it.
If you extend the PropertyPlaceholderConfigurer and override a couple of methods, you can get it to perform to solve the stated problem. The one drawback is that you must override and re-implement the ''convertProperties'' method which will detect an encrypted property and perform the decryption.
Caveat: this is really a description of how to extend Spring to allow for encrypted property values and not a discussion of encryption techniques
Assume that the requirements are to allow for encrypted values to be added as property values. For simplicity it is assumed that the same encryption algorithm is used to create the encrypted values as it is to decrypt or at least it is understood what the algorithm will be.
Below is an example of an extended PropertyPlaceholderConfigurer. It is just an example, it will not compile as there will certainly be decisions on the details of the encryption. Notice that the important overloaded method is convertProperties which looks for property names that begin with encrypted. to know which values to decrypt.
An example of an encrypted value would be:
encrypted.jdbc.password=*(&LHJFL#*(FELF(*%&^F=
public class PropertyPlaceholderConfigurer extends
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer {
private static final String ENCRYPTED = "encrypted.";
private MyFavoriteEncryptor encryptor = new MyFavoriteEncryptor();
@Override
protected void convertProperties(Properties props) {
Enumeration propertyNames = props.propertyNames();
while (propertyNames.hasMoreElements()) {
String propertyName = (String) propertyNames.nextElement();
String propertyValue = props.getProperty(propertyName);
String convertedValue = "";
if( propertyName.startsWith(ENCRYPTED) ) {
// just store the property name without the encrypted prepended value
// so encrypted.jdbc.password becomes jdbc.password
propertyName = propertyName.substring(ENCRYPTED.length());
convertedValue = decryptPropertyValue(propertyValue);
} else {
convertedValue = convertPropertyValue(propertyValue);
}
if (!ObjectUtils.nullSafeEquals(propertyValue, convertedValue)) {
props.setProperty(propertyName, convertedValue);
}
}
}
/**
*
* @param base64EncryptedValue base64 encoded value of the encrypted value from MyFavoriteEncryptor class
* @return cleartext value.
*/
protected String decryptPropertyValue(String base64EncryptedValue) {
String decryptedValue = null;
try {
byte[] decodedString = Base64.decode(base64EncryptedValue);
decryptedValue = encryptor.decryptString(decodedString);
} catch( Exception e ) {
throw new RuntimeException(e);
}
return decryptedValue;
}
public PropertyPlaceholderConfigurer() {
super();
}
}

1 comment:
test
Post a Comment