避免在Tomcat中的JNDI数据源中使用明文密码

时间:2015-04-21 18:00:46

标签: spring tomcat datasource jndi hikaricp

我正在使用在tomcat服务器中配置的JNDI数据源。我想避免将密码存储为明文,并且我在使用的应用程序中有一个现有的加密逻辑,我想用它来加密数据库密码。

<Resource name="jdbc/testdb" auth="Container"
      factory="com.zaxxer.hikari.HikariJNDIFactory"
      type="javax.sql.DataSource"
      minimumIdle="5" 
      maximumPoolSize="50"
      connectionTimeout="300000"
      driverClassName="org.mariadb.jdbc.Driver"
      jdbcUrl="jdbc:mysql://localhost:3307/testdb"
      dataSource.implicitCachingEnabled="true" 
      connectionTestQuery="Select 1" />

考虑到这个用例以及可用的在线解决方案,我决定使用org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter来使用代码提供数据库的用户名和密码

<bean id="dataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/testdb" />
    </bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
   <property name="targetDataSource" ref="dataSource1"/>
   <property name="username" value="${dataSource.username}"/>
   <property name="password" value="#{passwordDecryptor.decryptedString}"/>
 </bean>

这种方法适用于我与MSSQL数据库的连接,但奇怪的是在MariaDB上失败并且错误&#34;访问被拒绝用户&#39; @&#39; localhost&#39; (使用密码:否)&#34;。我想知道这个问题是否与HikariCP连接池有关,因为同样适用于C3P0实现而没有任何问题。

此外,我想知道这是否是正确的方法,请建议是否可以改善以获得更好的性能。

1 个答案:

答案 0 :(得分:2)

好的,我一直在偷看,试一试:

<Resource name="jdbc/testdb" auth="Container"
    factory="org.apache.naming.factory.BeanFactory"
    type="com.zaxxer.hikari.HikariDataSource"
    minimumIdle="5" 
    maximumPoolSize="50"
    connectionTimeout="300000"
    driverClassName="org.mariadb.jdbc.Driver"
    jdbcUrl="jdbc:mysql://localhost:3307/testdb"
    connectionTestQuery="Select 1" />

有什么不同?我们没有使用com.zaxxer.hikari.HikariJNDIFactory。为什么?因为HikariJNDIFactory使用HikariDataSource(HikariConfig config)构造函数,它会立即实例化基础数据源,之后无法再更改配置。

使用BeanFactory,我们调用默认构造函数,它在第一次调用getConnection()之前不会实例化基础数据源,这意味着我们可以自由设置用户名/密码 JNDI查找。

在春天方面:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">

<jee:jndi-lookup id="dataSource"
   jndi-name="jdbc/testdb"
   cache="true"
   lookup-on-startup="true"
   expose-access-context="true">
     <property name="dataSourceProperties">
        <props>
           <prop key="user">${dataSource.username}</prop>
           <prop key="password">${passwordDecryptor.decryptedString}</prop>
        </props>
     </property>
</jee:jndi-lookup>

我相信这应该有效,或者非常接近它。我将对HikariCP做一个补充,也是为了尊重JNDI环境的传递,以便在<jee:environment>标签内使用<jee:jndi-lookup>来获得更清晰的解决方案。