首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何避免在DataSource的tomcat的server.xml资源定义中明文存储密码?

如何避免在DataSource的tomcat的server.xml资源定义中明文存储密码?
EN

Stack Overflow用户
提问于 2008-09-24 19:03:16
回答 7查看 79.5K关注 0票数 41

tomcat的server.xml中的资源定义如下所示...

<Resource
    name="jdbc/tox"
    scope="Shareable"
    type="javax.sql.DataSource"
    url="jdbc:oracle:thin:@yourDBserver.yourCompany.com:1521:yourDBsid"
    driverClassName="oracle.jdbc.pool.OracleDataSource"
    username="tox"
    password="toxbaby"
    maxIdle="3"
    maxActive="10"
    removeAbandoned="true"
    removeAbandonedTimeout="60"
    testOnBorrow="true"
    validationQuery="select * from dual"
    logAbandoned="true"
    debug="99"/>

密码是明文的。如何避免这种情况?

EN

回答 7

Stack Overflow用户

发布于 2008-12-10 11:28:56

正如前面所说的,加密密码只是将问题转移到其他地方。

不管怎么说,这很简单。只需为您的密钥等编写一个具有静态字段的类,并使用静态方法来加密、解密您的密码。在Tomcat的配置文件(server.xmlyourapp.xml...)中加密您的密码使用这个类。

要在Tomcat中“动态”解密密码,请扩展DBCP的BasicDataSourceFactory并在您的参考资料中使用此工厂。

它将如下所示:

    <Resource
        name="jdbc/myDataSource"
        auth="Container"
        type="javax.sql.DataSource"
        username="user"
        password="encryptedpassword"
        driverClassName="driverClass"
        factory="mypackage.MyCustomBasicDataSourceFactory"
        url="jdbc:blabla://..."/>

而对于自定义工厂:

package mypackage;

....

public class MyCustomBasicDataSourceFactory extends org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory {

@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
    Object o = super.getObjectInstance(obj, name, nameCtx, environment);
    if (o != null) {
        BasicDataSource ds = (BasicDataSource) o;
        if (ds.getPassword() != null && ds.getPassword().length() > 0) {
            String pwd = MyPasswordUtilClass.unscramblePassword(ds.getPassword());
            ds.setPassword(pwd);
        }
        return ds;
    } else {
        return null;
    }
}

希望这能有所帮助。

票数 43
EN

Stack Overflow用户

发布于 2015-06-16 07:39:44

Tomcat提供了专门解决您的问题的a Password FAQ。简而言之:将密码放在明文中并适当地锁定您的服务器。

该页面还提供了一些建议,说明如何使用模糊安全性来通过审核员的检查表。

票数 11
EN

Stack Overflow用户

发布于 2016-09-03 02:44:58

正如@Ryan提到的,在实现此解决方案之前,请阅读Tomcat的Tomcat Password FAQ。你只是增加了模糊性,而不是安全性。

@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... />
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/129160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档