Tomcat Realm: Tutorial & Examples
What is Tomcat Realm?
Definition: Tomcat Realms is an interface for connecting Catalina to a existing database of usernames, passwords and roles to handle application authentication. You can manage your user access and their roles. Roles are grouping of users based on permissions you wish to grant to any group of users. There are many different implementation types of Realm I will go over a few of them in this article. Tomcat Realm can be used with our Tomcat Web Hosting for example.
How Tomcat Realm Works
You may ask yourself how Tomcat realm works. A Tomcat 6 Realm allows one to integrate Catalina into environments where usernames/passwords are maintained and then using that information one can implement Container Managed Security. Tomcat 7 and 8 Realms are used to implement Container Managed Security but it’s limited to web applications and one is supposed to be using <security-constraint> elements, and a <login-config> element within their web application’s web.xml in order to implement them.
Tomcat Realm Implementation Types
There are several different implementation types of Tomcat Realm. Implementaion 1 to 6 each uses a driver, while 7 and 8 uses combination of implementation type 1 to 6.
JDBCRealm is derived from Tomcat’s Realm interface that connects Catalina to a relational database via a JDBC driver such as MySQL Connector to look up usernames, passwords and user roles. Changes to the database are immediate keeping authentications current and up to date. When user first accesses a protected resource, Tomcat will call the authenticate() method so that any existing changes will be immediately reflected. User authentication is then cached for the duration of the session. Configuration flexibility is included to let you adapt it to your existing table and column names as long as you adhere to the following requirements:
- Must be ‘users’ table and contain at least 2 columns, username and password.
- Table for user roles containing a valid role per row with columns for username and rolename.
Heres a simple example:
create table users ( username varchar(20) not null primary key, userpass varchar(20) not null ); create table user_roles ( username varchar(20) not null, rolename varchar(20) not null, primary key (username, rolename) );
You can find example of this Tomcat Realm configuration in your tomcat/conf/server.xml installation.
Below is example using JDBC Realm to configure your MySQL database connection.
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="org.gjt.mm.mysql.Driver" connectionURL="jdbc:mysql://mysql_hostname/users?user=dbuser&password=dbpass" userTable="users" userNameCol="user_name" userCredCol="userpass" userRoleTable="userroles" roleNameCol="rolename"/>
DataSourceRealm is also a part of the Tomcat Realm interface that connected Catalina to a relational database but via a JNDI named based JDBC DataSource. This method has similar flexibility and requirements as JDBCRealm but has some advantages over its counter part. For example the JDBCRealm can only connect to a single database which limits you to one authentication at a time. The Datasource Realm allows simultaneous realm based authentications including connection pooling.
Here is an example for using a MySQL database called “authority” that references the JNDI JDBC DataSource “java:/comp/env/jdbc/authority”.
<Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/authority" userTable="users" userNameCol="username" userCredCol="userpass" userRoleTable="userroles" roleNameCol="rolename"/>
The UserDatabase Realm used the flat file based database that comes with Apache Tomcat installation: $CATALINA_BASE/conf/tomcat-users.xml. The users, their passwords and their roles may all be editing dynamically, typically via JMX. Changes may be saved and will be reflected in the xml file. However file can be edited directly but Tomcat must be restarted for changes to reflect.
The default installation of Tomcat is configured with a UserDatabaseRealm nested inside the <Engine> element, so that it applies to all virtual hosts and web applications. The default contents of theconf/tomcat-users.xml file is:
<tomcat-users> <user name="tomcat" password="tomcat" roles="tomcat" /> <user name="role1" password="tomcat" roles="role1" /> <user name="both" password="tomcat" roles="tomcat,role1" /> </tomcat-users>
JNDIRealm interface connects Catalina to an LDAP directory server. This Realm solution supports a variety of approaches to using a LDAP for authentication.
The Memory Based Realm is a simple Realm implementation reads user information from an xml format, and represents it as a collection of Java objects in memory. However this is not designed for production use. Like User DatabaseRealm it also utilizes the flat file database $CATALINA_BASE/conf/tomcat-users.xml. However file can be edited directly but Tomcat must be -estarted for changes to reflect.
JAAS (Java Authentication & Authorization Service) framework is part of Java security architecture which is included in Java 2 SE API. JAASRealm uses JAAS Framework to authenticate users. With JAASRealm one can use any security realm in combination with Tomcat’s CMA Here is an example of how your server.xml snippet should look.
<Realm className="org.apache.catalina.realm.JAASRealm" appName="MyFooRealm" userClassNames="org.foobar.realm.FooUser" roleClassNames="org.foobar.realm.FooRole"/>
CombinedRealm gives a developer ability to combine different realms (stated above) and use them as a single authentication gateway. Realms are nested under CombinedRealm element and gets priority over each other based on their listing. This provides ability to authenticate using different realm methods(implementations) in a single realm and provides failover and fallback mechanism.
Here is an example of how your server.xml snippet should look to use a UserDatabase Realm and a DataSource Realm.
<Realm className="org.apache.catalina.realm.CombinedRealm" > <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/authority" userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles" roleNameCol="role_name"/> </Realm>
LockOutRealm is an extension of CombinedRealm which enables one to thwart bruteforce attacks and Denial of service attacks. To achieve this it locks out a user with too many failed login attempts and limiting the list of users with such attempts. Just like CombinedRealm realms are nested under LockOutRealm element and gets priority over each other based on their listing.
Here is a Tomcat Realm example of how your server.xml snippet should look to add lock out functionality to a UserDatabase Realm.
<Realm className="org.apache.catalina.realm.LockOutRealm" > <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm>