Avoid commiting database passwords in your version control system.

Having the datasource password in my version control systems is an issue that has run after me since the beginning of the time. It is  classic that you are always postponing it in the development process untill somebody from the security team comes to your office and tells you "what the @#$ are these passwords doing in the svn/git???" To avoid this embarrasing situation you have different choices:

  1. Substitute the password value for a variable and fill it only at packaging time, e.g. using a script.
  2. Depending on your database vendor you can have different authentication methods, e.g. for an Oracle Database you could use kerberos, certificates...
  3. Keep the datasource configuration outside of the source code of your application. In Tomcat you have two ways of doing it:
    1. In $CATALINA_BASE/conf/[enginename]/hostname/application.xml
    2. Inside a Host element in the main conf/server.xml. I have chosen this last one for this post.

Configure the context element directly in the server.xml file

The idea is very simple, we will configure the datasource in the server.xml and declare it in our web.xml deployment descriptor. For this we will need to define the context of our application inside the server.xml.

Datasource configuration

It is out of the scope of this article to enter in all of the bits and pieces of the configuration. For this you can take a look at this excellent article of Filip Hanik.

Inside the Host element of the server.xml of your Tomcat installation ({$CATALINA_HOME}/conf):

Datasource configuration (server.xml)

<Context path="/YOUR_CONTEXT" privileged="true">
    <Resource auth="Container" driverClassName="oracle.jdbc.OracleDriver"
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        maxActive="50" maxIdle="10" maxWait="20000" minIdle="1"
        initialSize="1" name="jdbc/dev" password="YOUR_PASSWORD"
        testOnBorrow="true" type="javax.sql.DataSource"
        url="YOUR_URL" username="YOUR_USERNAME"
        validationQuery="select sysdate from dual" removeAbandoned="true"
        removeAbandonedTimeout="60" logAbandoned="true" />

Datasource declaration

In your web.xml deployment descriptor:

Datasource declaration (web.xml)

<resource-ref>
    <description>No passwords in my project please</description>
    <res-ref-name>jdbc/dev</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

How to use it?

Now we are ready to use our datasource. Below you can see two examples, in the first one I will show you how to get a connection using javax.sql.DataSource and in the second one we will declare it in a Hibernate SessionFactory

Getting java.sql.Connection via javax.sql.DataSource

getConnection()

private Connection getConnection() throws NamingException, SQLException {
    Context initContext = new InitialContext();
    Context envContext = (Context) initContext.lookup("java:/comp/env");
    DataSource dataSource = (DataSource) envContext.lookup("jdbc/dev");
    return dataSource.getConnection();
}

Above code uses Java Naming and Directory Interface (JNDI) in order to get the datasource.

Declaring your datasource in a Hibernate SessionFactory configuration

SessionFactory

<hibernate-configuration>
    <session-factory name="SessionFactory">
        <property name="hibernate.connection.datasource">java:/comp/env/jdbc/dev</property>
    </session-factory>
</hibernate-configuration>

Pros and cons of this solution

Like everything in this life this approach have advantanges and disadvantages.

 Advantages

  1. The username and password is outside your project.
  2. To leave the datasource configuration in the server side makes your application "more portable". E.g. if in the future you are planning to migrate to a different application server you just need to configure the datasource in that server. 
  3. It can help you to exploit the advantages offered by the different application server & driver vendors.  

Disadvantages

  1. In Tomcat you have to restart the server if you want to reload the context configuration.
  2. Tomcat will not be able to start if the application binaries are not present in the {$CATALINA_BASE}/webapps folder. Nevertheless this can be a desirable situation for certain systems. E.g. in portals systems, like Liferay, you do not want that the application server start without the main application it is on place.  

Tha's all folks! Have a happy coding day!

Luis

Links:

Add new comment

You are here