Setup your own Tomcat security realm

Recently I wanted to code my own security realm for fun. Without further ado, lets see how that works.

Coding the realm

Coding the realm is a snap because you can inherit from RealmBase. All you have to do is implement three methods: getName, getPassword and getPrincipal. The last two methods are the ones you should be interested in because they’ll get a user name as parameter and return either a password or a implementation of the Principal interface.

The servlet container will first make a call to getPassword. If authentication succeeded it’ll then call getPrincipal to check the user’s role. If the user hasn’t got a role which is allowed to access the inquired resource he’ll be refused to do so.

Let’s have a look at the code:

package org.christianschenk.testrealm;
 
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
 
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.realm.RealmBase;
 
public class MyRealm extends RealmBase {
 
  @Override
  protected String getName() {
    return this.getClass().getSimpleName();
  }
 
  @Override
  protected String getPassword(final String username) {
    return "test123";
  }
 
  @Override
  protected Principal getPrincipal(final String username) {
    final List<String> roles = new ArrayList<String>();
    roles.add("tomcat");
    return new GenericPrincipal(this, username, "test123", roles);
  }
}

As you might guess from the code every user name will be allowed as long as the password is test123. Furthermore the user will have the role tomcat.

Compile the code, put it in a JAR and copy the JAR to server/lib inside your Tomcat.

Configure the webapp

Next we’ll add a context to the Tomcat server and put the realm inside it. If the need arises the realm can also go into the Engine or Host element and thus have a broader scope. Finally we’ll configure the webapp (web.xml) and declare some security requirements.

Put the following context into conf/Catalina/localhost/realmtest.xml or inside the server.xml and adjust the docBase attribute:

<Context path="/realmtest" debug="0" reloadable="true"
         docBase="path/to/your/webapp/">
 
  <Realm className="org.christianschenk.testrealm.MyRealm" debug="0" />
</Context>

I want to restrict access to the whole webapp with Basic HTTP authentication and want users to have the role tomcat, so I put this into the webapp’s web.xml:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>The entire webapp</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>tomcat</role-name>
  </auth-constraint>
</security-constraint>
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>MyRealm</realm-name>
</login-config>
<security-role>
  <role-name>tomcat</role-name>
</security-role>

Testing and Conclusion

To test the setup start the Tomcat server and check catalina.out for errors. If everything went fine try to access your web application at /realmtest where you should be prompted to enter a user name and password. Type whatever user name you want and use test123 for the password: your attempt to log in will be successful. If you try to enter another password, access should be denied.

As we have seen it’s easy and fun to code and setup your own realm for the Tomcat server. Before reinventing the wheel have a look at the Realm Configuration Howto and check out the available realms. Probably it’s the JDBCRealm you’re looking for: it’ll fetch credentials and roles from a database. If this isn’t sufficient, go ahead and write your own realm.

10 thoughts on “Setup your own Tomcat security realm”

  1. Christian,

    I was looking for alternatives to Lambda Probe, and as yet have not found one, but I saw that in Jan you reccommended this to someone. For some reason the site is completely down and off air, but I was wondering and hoping that you might know a little about the datasource configuration. Is it possible to direct the data source config to the MySQL deamon instead of the Tomcat Instance ?

    If you cannot answer this, I will keep searching. Just that they seem to have dropped off the face of the earth without cause.

    Thanks in advance
    Lawrence

    PS: I have the latest probe.war file if that person still needs it.

  2. Once authenticated in the application, how do you access information about the user that is logged on? Is the Principal object stored as a session attribute or how else can you access it? Simple example, how would you get hold of the username on a JSP to do a DB query that uses that username as a parameter?

  3. Hi jeremy,
    as far as I know you’ll have to do HTTP-Authentication yourself, i.e. you’ll have to send the appropriate HTTP headers (e.g. WWW-Authenticate) yourself in a servlet and then investigate the response headers. This way you can store the username in the session.
    But since this isn’t very easy most people use Form-Based Authentication instead; this page is a good starting point. Here are some pros and cons about HTTP-Authentication.

  4. Hi

    I’m using a database realm and the login/security works great but I have one issue.

    After the user registers, I want the user to be automatically logged into the application. Any idea how can you automatically populate the Realm?

    If you want to see what I mean you can register free here for my Backlink Service

  5. Hi Kris,
    the documentation says:

    Administering the information in the users and user roles table is the responsibility of your own applications. Tomcat does not provide any built-in capabilities to maintain users and roles.

    I guess you’ve got an implementation that handles the registration process. During this process you should insert the new user into the corresponding database table that’s being used by the realm. Then have a look at the realm’s implementation and I’m pretty sure that it just places something in the session to authenticate the user – just do this after you registration process and the user should be logged in automatically.

  6. Pingback: Technical Related Notes » Blog Archive » links for 2010-06-10

  7. Hi Chris,

    oh this was such a nice simple explanation, im reading for an hour already about realm and how to configure and implement it (and where to put it), and from your post everything is crystal clear.
    Thanx

  8. Pingback: Tomcat Realm | boblog

Comments are closed.