正如@Ryan 提到的,请在实施此解决方案之前阅读 Tomcat 的Tomcat 密码常见问题解答。您只是增加了默默无闻而不是安全性。
@Jerome Delattre 的答案适用于简单的 JDBC 数据源,但不适用于作为数据源构造的一部分连接的更复杂的数据源(例如 oracle.jdbc.xa.client.OracleXADataSource)。
这是在调用现有工厂之前修改密码的替代方法。下面是一个用于基本数据源的工厂和一个用于 Atomikos JTA 兼容 XA 数据源的工厂示例。
基本示例:
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 示例:
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());
}
}
}
更新参考中的密码值:
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;
}
}
}
}
一旦包含这些类的 .jar 文件位于 Tomcat 的类路径中,您就可以更新 server.xml 以使用它们。
<Resource factory="com.mycompany.MyEncryptedPasswordFactory" username="user" password="encryptedPassword" ...other options... />
<Resource factory="com.mycompany.MyEncryptedAtomikosPasswordFactory" type="com.atomikos.jdbc.AtomikosDataSourceBean" xaProperties.user="user" xaProperties.password="encryptedPassword" ...other options... />