2010-11-16 73 views
4

好吧,我有這樣的數據庫連接在server.xml中Tomcat 5.5中的資源:如何延長C3P0 ComboPooledDataSource

<Resource name="jdbc/MyApp" auth="Container" type="com.mchange.v2.c3p0.ComboPooledDataSource" driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" maxPoolSize="100" minPoolSize="5" 
acquireIncrement="5"  
user="username" 
password="password" 
factory="org.apache.naming.factory.BeanFactory" 
jdbcUrl="jdbc:sqlserver://localhost:1433;databaseName=myDatabase;autoReconnect=true" /> 

有沒有人試圖擴大上述ComboPooledDataSource?問題是數據庫密碼是明文。想法是首先加密密碼並將加密的密鑰放入server.xml中。我有一個解密實用程序,所以我可以在嘗試連接數據庫之前解密密鑰。

我發現了一個針對org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory問題的示例解決方案,但是我沒有使用這個連接池。我正在使用C3P0。任何人在C3P0之前都曾嘗試過這一點?

+0

想知道你是否有辦法做到這一點 - 我有完全相同的要求。 – 2011-01-24 15:46:16

+0

解密的關鍵在哪裏?那也是加密的嗎?那麼解密的關鍵在哪裏?那也是加密的嗎?那麼解密的關鍵在哪裏?它是否被加密?那麼... – 2017-07-26 22:15:13

回答

0

您可以使用jasypt加密屬性文件,然後在數據源bean中使用加密屬性。

jasypt還支持彈簧,它很容易使用。 閱讀this瞭解更多詳情。

0

由於com.mchange.v2.c3p0.ComboPooledDataSource是 公開最終類,您不能擴展它。 我也在研究解決方法。將完成此線程更新。

+0

這對我很好。 – 2013-11-26 16:58:00

1

是的,你不能延伸com.mchange.v2.c3p0.ComboPooledDataSource,因爲它是公開的。以下是我已經實現的解決方法。

我擴展了org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy,並通過com.mchange.v2.c3p0.ComboPooledDataSource數據源作爲構造函數參數。

這裏是我的上述數據源的hibernate.cfg.xml配置:

<bean id="dataSource" class="MyDataSource"> 
     <constructor-arg ref="c3p0DataSource" /> 
    </bean> 

    <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
     destroy-method="close"> 
     <property name="driverClass" value="${jdbc.driver.className}" /> 
     <property name="jdbcUrl" value="${jdbc.url}" /> 
     <property name="user" value="${jdbc.username}" /> 
     <property name="password" value="${jdbc.password}" /> 
     <property name="acquireIncrement" value="${dataSource.acquireIncrement}" /> 
     <property name="acquireRetryAttempts" value="${dataSource.acquireRetryAttempts}" /> 
     <property name="acquireRetryDelay" value="${dataSource.acquireRetryDelay}" /> 
     <property name="autoCommitOnClose" value="${dataSource.autoCommitOnClose}" /> 
     <property name="breakAfterAcquireFailure" value="${dataSource.breakAfterAcquireFailure}" /> 
     <property name="checkoutTimeout" value="${dataSource.checkoutTimeout}" /> 
     <property name="debugUnreturnedConnectionStackTraces" 
      value="${dataSource.debugUnreturnedConnectionStackTraces}" /> 
     <property name="forceIgnoreUnresolvedTransactions" 
      value="${dataSource.forceIgnoreUnresolvedTransactions}" /> 
     <property name="idleConnectionTestPeriod" value="${dataSource.idleConnectionTestPeriod}" /> 
     <property name="initialPoolSize" value="${dataSource.initialPoolSize}" /> 
     <property name="maxAdministrativeTaskTime" value="${dataSource.maxAdministrativeTaskTime}" /> 
     <property name="maxConnectionAge" value="${dataSource.maxConnectionAge}" /> 
     <property name="maxIdleTime" value="${dataSource.maxIdleTime}" /> 
     <property name="maxIdleTimeExcessConnections" value="${dataSource.maxIdleTimeExcessConnections}" /> 
     <property name="maxPoolSize" value="${dataSource.maxPoolSize}" /> 
     <property name="maxStatements" value="${dataSource.maxStatements}" /> 
     <property name="maxStatementsPerConnection" value="${dataSource.maxStatementsPerConnection}" /> 
     <property name="minPoolSize" value="${dataSource.minPoolSize}" /> 
     <property name="numHelperThreads" value="${dataSource.numHelperThreads}" /> 
     <property name="propertyCycle" value="${dataSource.propertyCycle}" /> 
     <property name="testConnectionOnCheckin" value="${dataSource.testConnectionOnCheckin}" /> 
     <property name="testConnectionOnCheckout" value="${dataSource.testConnectionOnCheckout}" /> 
     <property name="unreturnedConnectionTimeout" value="${dataSource.unreturnedConnectionTimeout}" /> 
    </bean> 

Mine jdbc.properties file: 


jdbc.driver.className=com.microsoft.sqlserver.jdbc.SQLServerDriver 
jdbc.url=xxxxx 
jdbc.username=xxx 
jdbc.password=xxxxxxxxx #Encrytped password here 
jdbc.hibernate.dialect=org.hibernate.dialect.SQLServerDialect 
hibernate.show_sql=false 
hibernate.hbm2ddl.auto=update 

dataSource.acquireIncrement=3 
dataSource.acquireRetryAttempts=30 
dataSource.acquireRetryDelay=60000 
dataSource.autoCommitOnClose=false 
dataSource.breakAfterAcquireFailure=false 
dataSource.checkoutTimeout=0 
dataSource.debugUnreturnedConnectionStackTraces=false 
dataSource.forceIgnoreUnresolvedTransactions=false 
dataSource.idleConnectionTestPeriod=0 
dataSource.initialPoolSize=10 
dataSource.maxAdministrativeTaskTime=0 
dataSource.maxConnectionAge=0 
dataSource.maxIdleTime=0 
dataSource.maxIdleTimeExcessConnections=0 
dataSource.maxPoolSize=10 
dataSource.maxStatements=0 
dataSource.maxStatementsPerConnection=0 
dataSource.minPoolSize=10 
dataSource.numHelperThreads=3 
dataSource.propertyCycle=0 
dataSource.testConnectionOnCheckin=false 
dataSource.testConnectionOnCheckout=false 
dataSource.unreturnedConnectionTimeout=0 


Mine extended class where I decrypt the password before passing the datasource to transaction Proxy wrapper. 

import javax.sql.DataSource; 

import org.jasypt.util.text.BasicTextEncryptor; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; 

import com.csc.emms.common.EMMSConstraints; 
import com.mchange.v2.c3p0.ComboPooledDataSource; 

public class MyDataSource extends TransactionAwareDataSourceProxy 
{ 
    private static char[] appName = 
    { 
      'B', 'I', 'N', 'G', 'O', 'D', 'I', 'N', 'G', 'O' 
    }; 

    @Autowired 
    // Inject your class by constructor 
    MyDataSource(ComboPooledDataSource dataSource) 
    { 
     super.setTargetDataSource(decryptPassword(dataSource)); 
    } 

    private DataSource decryptPassword(ComboPooledDataSource dataSource) 
    { 
     dataSource.setPassword(decode(dataSource.getPassword())); 
     return dataSource; 
    } 

    private String decode(String encodedPassword) 
    { 
     BasicTextEncryptor decoder = new BasicTextEncryptor(); 
     decoder.setPasswordCharArray(appName); 
     return decoder.decrypt(encodedPassword); 
    } 

    private String encode(String password) 
    { 
     BasicTextEncryptor encoder = new BasicTextEncryptor(); 
     encoder.setPasswordCharArray(appName); 
     return encoder.encrypt(password); 
    } 
} 
Hope this resolved your issue. 
+0

這完全是毫無意義的。抱歉。最好的方式是通過默默無聞的安全。 5秒與反編譯器,我有你的密碼。 – 2017-07-26 22:15:54

0

不能擴展ComboPooledDataSource,但基本上可以通過擴展它的父類,AbstractComboPooledDataSource複製它。通過獲取source from Github或反編譯類文件,您可以真的,非常接近地複製它。結果看起來是這樣的:

import com.mchange.v2.c3p0.AbstractComboPooledDataSource; 

public final class YourC3p0DataSource extends AbstractComboPooledDataSource 
     implements Serializable, Referenceable { 

    public void setPassword(String encryptedPassword) { 
     try { 
      String decryptedPassword 
        = yourDecryption(encryptedPassword); 
      super.setPassword(decryptedPassword); 
     } catch (Exception e) { /* ... */ } 
    } 
    /* Increment a few other methods found in ComboPooledDataSource. */ 
}