Catch Exception from Tomcat DataSourceRealm Authenticator

15 apr, 2013 | techniek | 0 Comments

One a recent project we used Tomcat to run a JSON WebService Layer on that transferred data to several client applications. We kept authentication simple by reverting to the Tomcat DataSourceRealm implementation. This implementation derives user account information from a simple set of tables in an underlying database. It worked fine just when we started testing the behaviour in a database down situation, it seemed that this authenticator started giving Authentication Failed on the moment that it could not reach the database. Semantically this is a correct error but we needed our clients to be able to discern between incorrect username/password and a system situation. For this, I wrote a simple override of the standard DataSourceRealm that I want to share:

package nl.plance.tomcat.plugins;

import java.sql.Connection;
import org.apache.catalina.realm.DataSourceRealm;

 * Class that overrides the default Tomcat DataSourceRealm
 * and throws a runtime exception when no connection could be
 * fetched.
 * This results in an HTTP-500 error returned to client instead
 * of an authentication failed error which is undesired in this situation.
 * Use the class by setting the className attribute in the Realm definition in
 * the context.xml.
public class MyDataSourceRealm extends DataSourceRealm {

    public Principal authenticate(String username, String credentials) {

        // No user or no credentials
        // Can't possibly authenticate, don't bother the database then
        if (username == null || credentials == null) {
            return null;

        Connection dbConnection = null;

        // Ensure that we have an open database connection
        dbConnection = open();
        if (dbConnection == null) {
           System.out.println("Database could not be reached");
           throw new RuntimeException("Database could not be reached");

        // Acquire a Principal object for this user
        Principal principal = authenticate(dbConnection, username, credentials);


        return principal;

Activate it by putting it in the className attribute of the Real configuration in context.xml.



Would you like to share your thoughts?

Would you like to share your thoughts?

Geef een reactie

@2021 Plance. All rights reserved.