views:

52

answers:

1

Hi to everyone.

I develop a web application for Tomcat 6, and I'm face to face with a problem I don't know how to resolve. Let's consider the following small scenario. Imagine that it's required to authenticate users not just by user and password, the authentication is only granted if some extra conditions are true (e.g. user, password, and his IP address matches). As far I understood, Tomcat introduced the concept of realms. A simple JDBCRealm was enough for the application, because the user and password pair was checked only until the moment. Now it's required to check the IP address too. I have written a simple test class that extends the JDBCRealm class:

package security;

import org.apache.catalina.realm.JDBCRealm;
import org.apache.log4j.Logger;

import java.security.Principal;
import java.sql.Connection;

public class ApplicationRealm extends JDBCRealm {

    protected final Logger logger = Logger.getLogger(this.getClass());

    @Override
    public synchronized Principal authenticate(Connection connection, String userName, String credentials) {
        logger.info("custom realm test, the authentication will be failed just for testing");
        return null;
    }

}

And then I have tried to bind this realm class using the context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Realm className="security.ApplicationRealm" connectionName="${user}" connectionPassword="${password}"
        connectionURL="${url}${database}" debug="99" driverName="${driver}" roleNameCol="role" userCredCol="pw"
        userNameCol="login" userRoleTable="users_roles" userTable="users"/>
</Context>

The deployment of the web application succeeds, but when I try to access the login page, Tomcat returns a 404 page (I suspect the root of the problem is the className attribute in the Realm node):

HTTP Status 404 -
type Status report
message
description The requested resource () is not available.
Apache Tomcat/6.0.24

How can I bind a custom JDBCRealm descendant in context.xml? Maybe I'm totally wrong trying to use the JDBCRealm for this, but I can't see the correct solution anyway.

Thanks in advance.

A: 

Incorrect deployment of the realm was the cause of the problem. Moreover, a custom realm is not suitable here. The best way of checking the IP-address is writing a custom form authenticator that have access to the HTTP request. Changing the form authenticator in the web.xml, and deploying it allowed exactly what I needed. It also eliminates the requirement to check IP-address on every request, because secure resources are hidden behind the authorization "wall" - this means if the authorization is granted, it also means that the IP was valid. Thanks to JoseK for pointing a good solution. I was just confused a little with the concept of realms in Tomcat.

Lyubomyr Shaydariv