对 Tomcat 的 jndi 配置信息加密

对 Tomcat 的 jndi 配置信息加密

  1. 配置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>
  1. 写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());
    }

}
  1. 使用
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;

转载于:https://my.oschina.net/CasparLi/blog/2209336

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值