The resource definition in tomcat\'s server.xml looks something like this...
As @Ryan mentioned, please read Tomcat's Tomcat Password FAQ before implementing this solution. You are only adding obscurity not security.
@Jerome Delattre's answer will work for simple JDBC data sources, but not for more complicated ones that connect as part of the datasource construction (e.g. oracle.jdbc.xa.client.OracleXADataSource).
This is alternative approach that modifies the password prior to calling the existing factory. Below is an example of a factory for a basic datasource and one for an Atomikos JTA compatible XA datasource.
Basic Example:
public class MyEncryptedPasswordFactory extends BasicDataSourceFactory {
@Override
public Object getObjectInstance(Object obj, Name name, Context context, Hashtable, ?> environment)
throws Exception {
if (obj instanceof Reference) {
Reference ref = (Reference) obj;
DecryptPasswordUtil.replacePasswordWithDecrypted(ref, "password");
return super.getObjectInstance(obj, name, context, environment);
} else {
throw new IllegalArgumentException(
"Expecting javax.naming.Reference as object type not " + obj.getClass().getName());
}
}
}
Atomikos Example:
public class MyEncryptedAtomikosPasswordFactory extends EnhancedTomcatAtomikosBeanFactory {
@Override
public Object getObjectInstance(Object obj, Name name, Context context, Hashtable, ?> environment)
throws NamingException {
if (obj instanceof Reference) {
Reference ref = (Reference) obj;
DecryptPasswordUtil.replacePasswordWithDecrypted(ref, "xaProperties.password");
return super.getObjectInstance(obj, name, context, environment);
} else {
throw new IllegalArgumentException(
"Expecting javax.naming.Reference as object type not " + obj.getClass().getName());
}
}
}
Updating password value in Reference:
public class DecryptPasswordUtil {
public static void replacePasswordWithDecrypted(Reference reference, String passwordKey) {
if(reference == null) {
throw new IllegalArgumentException("Reference object must not be null");
}
// Search for password addr and replace with decrypted
for (int i = 0; i < reference.size(); i++) {
RefAddr addr = reference.get(i);
if (passwordKey.equals(addr.getType())) {
if (addr.getContent() == null) {
throw new IllegalArgumentException("Password must not be null for key " + passwordKey);
}
String decrypted = yourDecryptionMethod(addr.getContent().toString());
reference.remove(i);
reference.add(i, new StringRefAddr(passwordKey, decrypted));
break;
}
}
}
}
Once the .jar file containing these classes are in Tomcat's classpath you can update your server.xml to use them.