对 Tomcat 的 jndi 配置信息加密
- 配置jndi
$ vi {basedir}/META-INF/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/">
<!-- 应用tomcat配置好的数据源 -->
<!--<ResourceLink name="jdbc/mydb" global="jdbc/mydb" type="javax.sql.DataSource"/>-->
<!-- 针对本应用配置数据源. 关键在 factory 属性 -->
<Resource name="jdbc/mydb"
auth="Container"
type="javax.sql.DataSource"
factory="path.to.your.EncryptedDataSourceFactory"
url="jdbc:mysql://fooUrl:3306/target_db"
driverClassName="com.mysql.jdbc.Driver"
username="username"
password="password"
maxActive="10"
maxIdle="1"
maxWait="100"/>
</Context>
- 写DataSourceFactory
import org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory;
public class EncryptedDataSourceFactory extends BasicDataSourceFactory {
// 这个类是处理加解密的类.
private Decryptor decryptor = Decryptor.getDecryptor();
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
if (obj instanceof Reference) {
setUsername((Reference) obj);
setPassword((Reference) obj);
}
return super.getObjectInstance(obj, name, nameCtx, environment);
}
private void setUsername(Reference ref) throws Exception {
findDecryptAndReplace("username", ref);
}
private void setPassword(Reference ref) throws Exception {
findDecryptAndReplace("password", ref);
}
private void findDecryptAndReplace(String refType, Reference ref) throws Exception {
int idx = find(refType, ref);
String cipherText = (String) ref.get(idx).getContent();
System.out.println("findDecryptAndReplace item: " + cipherText);
Pattern p = Pattern.compile("(?:enc\\()(.*)(?:\\))");
Matcher m = p.matcher(cipherText);
if (m.find()) {
String g = m.group(1);
String decrypted = decryptor.decryptCipherText(g);
replace(idx, refType, decrypted, ref);
}
}
private void replace(int idx, String refType, String newValue, Reference ref) throws Exception {
ref.remove(idx);
ref.add(idx, new StringRefAddr(refType, newValue));
}
private int find(String addrType, Reference ref) throws Exception {
Enumeration enu = ref.getAll();
for (int i = 0; enu.hasMoreElements(); i++) {
RefAddr addr = (RefAddr) enu.nextElement();
if (addr.getType().compareTo(addrType) == 0) {
return i;
}
}
throw new Exception("The \"" + addrType
+ "\" name/value pair was not found"
+ " in the Reference object. The reference Object is" + " "
+ ref.toString());
}
}
- 使用
Connection con = null;
try {
Context ic = new InitialContext();
String name = ic.getNameInNamespace();
Map env = ic.getEnvironment();
DataSource source = (DataSource) ic.lookup("java:comp/env/jdbc/mydb");
con = source.getConnection();
} catch (NamingException e) {
System.out.println("数据源没找到!");
e.printStackTrace();
} catch (SQLException e) {
System.out.println("获取数连接对象失败!");
e.printStackTrace();
}
return con;