In this article, we will
A security realm is a mechanism used for protecting Web application resources. It gives you the ability to protect a resource with a defined security constraint and then define the user roles that can access the protected resource. Tomcat
has this type of realm functionality built in. The component that provides this functionality is the
org.apache.catalina.Realm interface. It provides a mechanism by which a collection of usernames, passwords, and their associated roles can be integrated into Tomcat. If you download the Tomcat source, you will find this interface in the following location:
There are two Realm implementations provided in Tomcat 4. We will discuss each of these implementations in the following sections.
The first Realm implementation provided with Tomcat is a memory realm. The class that defines the memory realm is
MemoryRealm class uses a simple XML file as a container of users. The following code snippet contains a sample memory realm XML file:
<user name="tomcat" password="tomcat" roles="tomcat" />
<user name="role1" password="tomcat" roles="role1" />
<user name="both" password="tomcat" roles="tomcat,role1" />
Note: The default location of the MemoryRealms XML file is the
<tomcat_home>/conf/tomcat-users.xml. You can change the location of this file by substituting a new relative or absolute path in the pathname attribute of the
<realm>element described in the following section.
As you can see, there is nothing terribly complicated about this file. It has a root element of
<tomcat-users>, which contains n-number of the sub-element
<user> element contains all of the necessary information to validate a user. This information is contained in the attributes of the
<user> sub-element. Table 1 contains a description of each of the attributes required in the
|Table 1. The Attributes of the |
||The name attribute contains a string representing the username that will be used in the login form.|
||The password attribute contains a string representing the password that will be used in the login form.|
||The roles attribute contains the role or roles assigned to the named user. This is the value that must match the
Give Jim Goodwill your feedback and questions.
Also in Using Tomcat:
To actually see how a
MemoryRealm works, let's create a realm that protects a sample web application named
/onjava. At this point, if you have not already done so, take a look at my previous OnJava article, Deploying Web Applications to Tomcat. We will be using the
/onjava web application from it. The steps involved in setting up a new
MemoryRealm are described in the following list.
<tomcat_home>/conf/server.xml and uncomment the following line.
<Realm className="org.apache.catalina.realm.MemoryRealm" />
By un-commenting this
<realm> entry, you are making the
MemoryRealm the default realm implementation for the entire default container. If you cannot find this entry, add it directly under the
<tomcat_home>/webapps/onjava/WEB-INF/web.xml and add the following security constraint:
There are only two sub-elements that you need to focus upon. The first is the
<url-pattern> sub-element. This sub-element defines the URL pattern that will be protected by the resource. The entry you included protects the entire
/onjava Web application. The second sub-element,
<role-name>, defines the user role that can access the resource protected by the previously defined
<url-pattern>. In summary, this entire entry states that the
/onjava Web application can only be accessed by users with a defined role of
Add the following
<login-config> sub-element directly following the
<login-config> sub-element defines the authentication method for the defined realm. The possible values are
FORM. And the
<realm-name> sub-element names the Web resource that this
<login-config> maps to.
<tomcat_root>/conf/tomcat-users.xml and add the following
<user name="bob" password="password" roles="onjavauser" />
<user> sub-element you are adding will create a new user in the
MemoryRealm database with a name of
bob, a password of
password, and a role of
onjavauser. You should notice that the value of the roles attribute matches the value of the
<role-name> sub-element of the previously-defined
Now let's actually look at how your newly defined realm affects the
/onjava web application. Point your browser at the following URL:
If everything went according to plan you should see a dialog box similar to the one in Figure 1.
Go ahead and enter
bob for the User Name,
password for the Password, and press "OK." Again, if everything goes according to plan, you should see the login page of the
/onjava web application. You now have a Web application that is protected by a security realm that uses the Basic Authentication method to authenticate its users.
The second Realm implementation provided with Tomcat is a JDBC realm. The class that implements the JDBC realm is
JDBCRealm class is much like the
MemoryRealm discussed in the previous section, with the exception of where it stores its collection of users. A
JDBCRealm stores all of its users in a user-defined, JDBC-compliant database. There are several steps involved when setting up a JDBC realm, but once it is configured it is really simple to manage.
Before you begin configuring Tomcat to use a
JDBCRealm, you must first create a database to hold your collection of users. Our user database is going to contain three tables. The first table is the
users table. The
users table contains the user name and password for each of our users. Table 2 contains the description of the
|Table 2. The |
The second table in the users database is the
roles table. The
roles table contains all of the possible roles for the users defined in this database. The
roles table contains a single column,
role_name, that is a
varchar(12) string representing each role name.
The last table in the users database is the
user_roles table. The
user_roles table is a mapping table between the roles and users defined in this database. Table 3 contains the table definition for the
|Table 3. The |
The contents of each of the users database's tables are listed in Tables 4, 5, and 6.
|Table 4. The Contents of the |
|Table 5. The Contents of the |
|Table 6. The Contents of the |
Now that you have defined the
users database, you can actually create the physical database. Before you can create the
users database, you will need to download and install the MySQL server, which can be found at
http://www.mysql.com. You should also download the latest JDBC driver for MySQL, which can also be found at the previously mentioned Web site.
Note: For this example we are using MySQL. You can use any JDBC-compliant database server of your choosing.
After you have MySQL installed, you need to complete the following steps to create and configure a MySQL Users database:
mysql client found in the
Create the Users database, which will be explicitly named
tomcatusers, by executing the following command:
create database tomcatusers;
users table using the following command:
create table users
user_name varchar(15) not null primary key,
user_pass varchar(15) not null
roles table using the following command:
create table roles
role_name varchar(15) not null primary key
user_roles table using the following command:
create table users
user_name varchar(15) not null,
role_name varchar(15) not null,
primary key(user_name, role_name)
Insert the user data into the
users table, by executing the following commands:
insert into users values("bob", "password");
insert into users values("joe", "$joe$");
insert into users values("robert", "password");
insert into users values("tomcat", "password");
Insert the roles data into the
roles table with the following commands:
insert into roles values("onjavauser");
insert into roles values("manager");
insert into roles values("tomcat");
Insert the user roles data into the
user_roles table with the following commands:
insert into user_roles values("bob", "onjavauser");
insert into user_roles values("joe", "onjavauser");
insert into user_roles values("joe", "manager");
insert into user_roles values("robert", "onjavauser");
insert into user_roles values("tomcat", "tomcat");
Now that you have a container of users, let's configure Tomcat to use the JDBC container instead of the previously configured
MemoryRealm. The steps involved in configuring a
JDBCRealm are described in the following list.
<tomcat_home>/conf/server.xml and place comment tags around the previously uncommented
<!-- <Realm className="org.apache.catalina.realm.MemoryRealm" /> -->
Place the following code snippet directly below the previously referenced
<realm classname="org.apache.catalina.realm.JDBCRealm" debug="99"
usertable="users" usernamecol="user_name" usercredcol="user_pass"
Make sure that the JAR file containing the JDBC driver referenced by the
driverName attribute is placed in Tomcat's
CLASSPATH. If you are using the JDBC-ODBC bridge, the driver will already be in Tomcat's
CLASSPATH. You will also need to replace the user and password values with the appropriate values for your database installation. This new
<realm> entry defines a
JDBCRealm that leverages our database as its container of users. The attributes used in the
<realm> element, with additional optional attributes, are described in Table 7.
|Table 7. The Attributes of the |
||The fully qualified class name of the
||The name of the driver used to connect to the database containing the users.|
||The URL referencing the database containing the users.|
||The database table containing the user's information.|
|The column in the |
||The column in the |
||The database table containing the mapping between the
||The column in the |
To complete this configuration change, stop and restart the Tomcat server.
That is all there is to it; your Web application is now protected by a
JDBCRealm. To test this change, try logging in to the
/onjava Web application, entering a username from the
users table that has a role of
onjavauser. You should see a dialog similar to Figure 1 above.
James Goodwill is the co-Founder of Virtuas Solutions, LLC, a Colorado-based software consultancy.
Read more Using Tomcat columns.
Return to ONJava.com.
Copyright © 2009 O'Reilly Media, Inc.