Search code examples
javaspring-bootjnditomcat9

Springboot decrypt JNDI tomcat password


I have the following configuration in tomcat for JNDI. I have my password encrypted in the server.xml

<Resource auth="Container" 
          driverClassName="oracle.jdbc.driver.OracleDriver" 
          global="jdbc/dbsource" 
          maxIdle="30" 
          maxTotal="1000" 
          maxWaitMillis="100000" 
          name="jdbc/dbsource" 
          password=<<unencrypted password>> 
          type="javax.sql.DataSource" 
          url=<<dburl>> 
          username="user" />

I am running a springboot application and I have configured the JNDI name in the application.properties as follows

spring.datasource.jndi-name=java:comp/env/jdbc/dbsource

I am directly autowiring the JDBCTemplate to my Bean class to connect to Oracle db.

I want to encrypt my password in the tomcat server.xml. How do I override the auto configuration in spring boot to decrypt the password?


Solution

  • You have a bunch of options available. Below are just two.

    If you have access to the server.xml (assuming this is Tomcat) file, you can specify your own implementation of BasicDataSourceFactory - so this will be the factory that will initialize the Datasource. In your custom implementation you can leverage decryption code services to deal with the encrypted password.

    If you don't have access to server.xml one way would be proxying the target JNDI Datasource with UserCredentialsDataSourceAdapter.

    An adapter for a target JDBC DataSource, applying the specified user credentials to every standard getConnection() call, implicitly invoking getConnection(username, password) on the target. All other methods simply delegate to the corresponding methods of the target DataSource.

    So basically this could be your flow:

    1) Load the JNDI Datasource

    2) Cast the JNDI Datasource to Tomcat DataSource to be able to call getUsername() and getPassword()

    3) In UserCredentialsDataSourceAdapter, decrypt the password before invoking getConnection(username, password) - all the other datasource calls will be delegated to the original datasource, only the getConnection(username, password) will be proxied.