Links User Guide Reference Apache Tomcat Development | Realm Configuration HOW-TO| Quick Start |
This document describes how to configure Tomcat to support container
managed security, by connecting to an existing "database" of usernames,
passwords, and user roles. You only need to care about this if you are using
a web application that includes one or more
<security-constraint> elements, and a
<login-config> element defining how users are required
to authenticate themselves. If you are not utilizing these features, you can
safely skip this document.
For fundamental background information about container managed security,
see the Servlet
Specification (Version 2.4), Section 12.
For information about utilizing the Single Sign On feature of
Tomcat (allowing a user to authenticate themselves once across the entire
set of web applications associated with a virtual host), see
here.
|
| Overview |
| What is a Realm? |
A Realm is a "database" of usernames and passwords that
identify valid users of a web application (or set of web applications), plus
an enumeration of the list of roles associated with each valid user.
You can think of roles as similar to groups in Unix-like operating
systems, because access to specific web application resources is granted to
all users possessing a particular role (rather than enumerating the list of
associated usernames). A particular user can have any number of roles
associated with their username.
Although the Servlet Specification describes a portable mechanism for
applications to declare their security requirements (in the
web.xml deployment descriptor), there is no portable API
defining the interface between a servlet container and the associated user
and role information. In many cases, however, it is desirable to "connect"
a servlet container to some existing authentication database or mechanism
that already exists in the production environment. Therefore, Tomcat
defines a Java interface (org.apache.catalina.Realm) that
can be implemented by "plug in" components to establish this connection.
Five standard plug-ins are provided, supporting connections to various
sources of authentication information:
- JDBCRealm - Accesses authentication information
stored in a relational database, accessed via a JDBC driver.
- DataSourceRealm - Accesses authentication
information stored in a relational database, accessed via a named JNDI
JDBC DataSource.
- JNDIRealm - Accesses authentication information
stored in an LDAP based directory server, accessed via a JNDI provider.
- UserDatabaseRealm - Accesses authentication
information stored in an UserDatabase JNDI resource, which is typically
backed by an XML document (
conf/tomcat-users.xml).
- MemoryRealm - Accesses authentication
information stored in an in-memory object collection, which is initialized
from an XML document (
conf/tomcat-users.xml).
- JAASRealm - Accesses authentication information
through the Java Authentication & Authorization Service (JAAS)
framework.
It is also possible to write your own Realm implementation,
and integrate it with Tomcat. To do so, you need to:
- Implement
org.apache.catalina.Realm,
- Place your compiled realm in $CATALINA_HOME/lib,
- Declare your realm as described in the "Configuring a Realm" section below,
- Declare your realm to the MBeans Descriptor.
|
|
| Common Features |
| Digested Passwords |
For each of the standard Realm implementations, the
user's password (by default) is stored in clear text. In many
environments, this is undesirable because casual observers of the
authentication data can collect enough information to log on
successfully, and impersonate other users. To avoid this problem, the
standard implementations support the concept of digesting
user passwords. This allows the stored version of the passwords to be
encoded (in a form that is not easily reversible), but that the
Realm implementation can still utilize for
authentication.
When a standard realm authenticates by retrieving the stored
password and comparing it with the value presented by the user, you
can select digested passwords by specifying the digest
attribute on your <Realm> element. The value for
this attribute must be one of the digest algorithms supported by the
java.security.MessageDigest class (SHA, MD2, or MD5).
When you select this option, the contents of the password that is
stored in the Realm must be the cleartext version of the
password, as digested by the specified algorithm.
When the authenticate() method of the Realm is called, the
(cleartext) password specified by the user is itself digested by the same
algorithm, and the result is compared with the value returned by the
Realm. An equal match implies that the cleartext version of the
original password is the same as the one presented by the user, so that this
user should be authorized.
To calculate the digested value of a cleartext password, two convenience
techniques are supported:
- If you are writing an application that needs to calculate digested
passwords dynamically, call the static
Digest() method of the
org.apache.catalina.realm.RealmBase class, passing the
cleartext password and the digest algorithm name as arguments. This
method will return the digested password.
- If you want to execute a command line utility to calculate the digested
password, simply execute
 |  |  |  | CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password}
|  |  |  |  |
and the digested version of this cleartext password will be returned to
standard output.
If using digested passwords with DIGEST authentication, the cleartext used
to generate the digest is different and the digest must use the MD5
algorithm. In the examples above {cleartext-password} must be
replaced with {username}:{realm}:{cleartext-password}. For
example, in a development environment this might take the form
testUser:Authentication required:testPassword. The value for
{realm} is taken from the <realm-name>
element of the web application's <login-config>. If
not specified in web.xml, the default value of Authentication
required is used.
Non-ASCII usernames and/or passwords are supported using
 |  |  |  | CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} -e {encoding} {input}
|  |  |  |  |
but care is required to ensure that the non-ASCII input is
correctly passed to the digester.
The digester returns {input}:{digest}. If the input appears
corrupted in the return, the digest will be invalid.
|
| Manager Application |
If you wish to use the Manager Application
to deploy and undeploy applications in a running Tomcat installation, you
MUST add the "manager-gui" role to at least one username in your selected
Realm implementation. This is because the manager web application itself uses a
security constraint that requires role "manager-gui" to access ANY request URI
within the HTML interface of that application.
For security reasons, no username in the default Realm (i.e. using
conf/tomcat-users.xml is assigned the "manager-gui" role.
Therefore, no one will be able to utilize the features of this application
until the Tomcat administrator specifically assigns this role to one or more
users.
|
| Realm Logging |
Debugging and exception messages logged by a Realm will
be recorded by the logging configuration associated with the container
for the realm: its surrounding Context,
Host, or
Engine.
|
|
| Standard Realm Implementations |
| JDBCRealm |
Introduction
JDBCRealm is an implementation of the Tomcat
Realm interface that looks up users in a relational database
accessed via a JDBC driver. There is substantial configuration flexibility
that lets you adapt to existing table and column names, as long as your
database structure conforms to the following requirements:
- There must be a table, referenced below as the users table,
that contains one row for every valid user that this
Realm
should recognize.
- The users table must contain at least two columns (it may
contain more if your existing applications required it):
- Username to be recognized by Tomcat when the user logs in.
- Password to be recognized by Tomcat when the user logs in.
This value may in cleartext or digested - see below for more
information.
- There must be a table, referenced below as the user roles table,
that contains one row for every valid role that is assigned to a
particular user. It is legal for a user to have zero, one, or more than
one valid role.
- The user roles table must contain at least two columns (it may
contain more if your existing applications required it):
- Username to be recognized by Tomcat (same value as is specified
in the users table).
- Role name of a valid role associated with this user.
Quick Start
To set up Tomcat to use JDBCRealm, you will need to follow these steps:
- If you have not yet done so, create tables and columns in your database
that conform to the requirements described above.
- Configure a database username and password for use by Tomcat, that has
at least read only access to the tables described above. (Tomcat will
never attempt to write to these tables.)
- Place a copy of the JDBC driver you will be using inside the
$CATALINA_HOME/lib directory.
Note that only JAR files are recognized!
- Set up a
<Realm> element, as described below, in your
$CATALINA_BASE/conf/server.xml file.
- Restart Tomcat if it is already running.
Realm Element Attributes
To configure JDBCRealm, you will create a <Realm>
element and nest it in your $CATALINA_BASE/conf/server.xml file,
as described above. The attributes for the
JDBCRealm are defined in the Realm configuration
documentation.
Example
An example SQL script to create the needed tables might look something
like this (adapt the syntax as required for your particular database):
 |  |  |  |
create table users (
user_name varchar(15) not null primary key,
user_pass varchar(15) not null
);
create table user_roles (
user_name varchar(15) not null,
role_name varchar(15) not null,
primary key (user_name, role_name)
);
|  |  |  |  |
Example Realm elements are included (commented out) in the
default $CATALINA_BASE/conf/server.xml file. Here's an example
for using a MySQL database called "authority", configured with the tables
described above, and accessed with username "dbuser" and password "dbpass":
 |  |  |  |
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/authority?user=dbuser&password=dbpass"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
|  |  |  |  |
Additional Notes
JDBCRealm operates according to the following rules:
- When a user attempts to access a protected resource for the first time,
Tomcat will call the
authenticate() method of this
Realm. Thus, any changes you have made to the database
directly (new users, changed passwords or roles, etc.) will be immediately
reflected.
- Once a user has been authenticated, the user (and his or her associated
roles) are cached within Tomcat for the duration of the user's login.
(For FORM-based authentication, that means until the session times out or
is invalidated; for BASIC authentication, that means until the user
closes their browser). The cached user is not saved and
restored across sessions serialisations. Any changes to the database
information for an already authenticated user will not be
reflected until the next time that user logs on again.
- 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.
|
| DataSourceRealm |
Introduction
DataSourceRealm is an implementation of the Tomcat
Realm interface that looks up users in a relational database
accessed via a JNDI named JDBC DataSource. There is substantial configuration
flexibility that lets you adapt to existing table and column names, as long
as your database structure conforms to the following requirements:
- There must be a table, referenced below as the users table,
that contains one row for every valid user that this
Realm
should recognize.
- The users table must contain at least two columns (it may
contain more if your existing applications required it):
- Username to be recognized by Tomcat when the user logs in.
- Password to be recognized by Tomcat when the user logs in.
This value may in cleartext or digested - see below for more
information.
- There must be a table, referenced below as the user roles table,
that contains one row for every valid role that is assigned to a
particular user. It is legal for a user to have zero, one, or more than
one valid role.
- The user roles table must contain at least two columns (it may
contain more if your existing applications required it):
- Username to be recognized by Tomcat (same value as is specified
in the users table).
- Role name of a valid role associated with this user.
Quick Start
To set up Tomcat to use DataSourceRealm, you will need to follow these steps:
- If you have not yet done so, create tables and columns in your database
that conform to the requirements described above.
- Configure a database username and password for use by Tomcat, that has
at least read only access to the tables described above. (Tomcat will
never attempt to write to these tables.)
- Configure a JNDI named JDBC DataSource for your database. Refer to the
JNDI DataSource Example HOW-TO
for information on how to configure a JNDI named JDBC DataSource.
- Set up a
<Realm> element, as described below, in your
$CATALINA_BASE/conf/server.xml file.
- Restart Tomcat if it is already running.
Realm Element Attributes
To configure DataSourceRealm, you will create a <Realm>
element and nest it in your $CATALINA_BASE/conf/server.xml file,
as described above. The attributes for the
DataSourceRealm are defined in the Realm
configuration documentation.
Example
An example SQL script to create the needed tables might look something
like this (adapt the syntax as required for your particular database):
 |  |  |  |
create table users (
user_name varchar(15) not null primary key,
user_pass varchar(15) not null
);
create table user_roles (
user_name varchar(15) not null,
role_name varchar(15) not null,
primary key (user_name, role_name)
);
|  |  |  |  |
Here is an example for using a MySQL database called "authority", configured
with the tables described above, and accessed with the JNDI JDBC DataSource with
name "java:/comp/env/jdbc/authority".
 |  |  |  |
<Realm className="org.apache.catalina.realm.DataSourceRealm"
dataSourceName="jdbc/authority"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
|  |  |  |  |
Additional Notes
DataSourceRealm operates according to the following rules:
- When a user attempts to access a protected resource for the first time,
Tomcat will call the
authenticate() method of this
Realm. Thus, any changes you have made to the database
directly (new users, changed passwords or roles, etc.) will be immediately
reflected.
- Once a user has been authenticated, the user (and his or her associated
roles) are cached within Tomcat for the duration of the user's login.
(For FORM-based authentication, that means until the session times out or
is invalidated; for BASIC authentication, that means until the user
closes their browser). The cached user is not saved and
restored across sessions serialisations. Any changes to the database
information for an already authenticated user will not be
reflected until the next time that user logs on again.
- 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.
|
| JNDIRealm |
Introduction
JNDIRealm is an implementation of the Tomcat
Realm interface that looks up users in an LDAP directory
server accessed by a JNDI provider (typically, the standard LDAP
provider that is available with the JNDI API classes). The realm
supports a variety of approaches to using a directory for
authentication.
Connecting to the directory
The realm's connection to the directory is defined by the
connectionURL configuration attribute. This is a URL
whose format is defined by the JNDI provider. It is usually an LDAP
URL that specifies the domain name of the directory server to connect
to, and optionally the port number and distinguished name (DN) of the
required root naming context.
If you have more than one provider you can configure an
alternateURL. If a socket connection can not be
made to the provider at the connectionURL an
attempt will be made to use the alternateURL.
When making a connection in order to search the directory and
retrieve user and role information, the realm authenticates itself to
the directory with the username and password specified by the
connectionName and
connectionPassword properties. If these properties
are not specified the connection is anonymous. This is sufficient in
many cases.
Selecting the user's directory entry
Each user that can be authenticated must be represented in the
directory by an individual entry that corresponds to an element in the
|
|
|