A Realm provides authentication and role-based authorization for Tomcat web applications. It acts as the bridge between a user store (flat file, database, LDAP directory, or JAAS module) and Tomcat’s container-managed security. Realms are configured inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/apache/tomcat/llms.txt
Use this file to discover all available pages before exploring further.
conf/server.xml by placing a <Realm> element inside a <Server>, <Engine>, <Host>, or <Context> element — the placement determines which applications share the Realm and at what scope credentials are looked up.
Realm Placement
A<Realm> element can be nested at four different levels of the server.xml container hierarchy. Child containers inherit the parent Realm unless they define their own.
| Placement | Scope |
|---|---|
Inside <Engine> | Shared by all virtual hosts and web applications in the Engine unless overridden at a lower level. This is the most common placement. |
Inside <Host> | Shared by all web applications deployed to that specific virtual host. Overrides any Engine-level Realm for that host. |
Inside <Context> | Used only by that single web application. Overrides Engine- and Host-level Realms. |
Inside <Server> | Available as a global Realm for management applications (rare). |
conf/server.xml ships with the Realm placed inside the <Engine> element, wrapped by a LockOutRealm for brute-force protection:
MemoryRealm
MemoryRealm reads user credentials and role assignments from an XML file at startup. By default it reads conf/tomcat-users.xml, matching the pathname field in the source:
conf/tomcat-users.xml structure:
The file ships with all user and role entries commented out. No active users exist in a fresh Tomcat installation. Remove the comment delimiters and replace the <must-be-changed> placeholders with real (hashed) passwords before first use:
UserDatabaseRealm
UserDatabaseRealm authenticates against a JNDI UserDatabase resource defined in <GlobalNamingResources>. Unlike MemoryRealm, the UserDatabase resource can be edited at runtime through the Manager application and changes are immediately available.
The default server.xml ships with this configuration:
resourceName attribute must match the name attribute of the <Resource> element in <GlobalNamingResources>.
DataSourceRealm
DataSourceRealm authenticates users stored in a relational database accessed via a JDBC DataSource. It is the preferred Realm for applications that already manage users in a database.
Required attributes:
| Attribute | Description |
|---|---|
dataSourceName | JNDI name of the javax.sql.DataSource resource |
userTable | Table containing user credentials |
userNameCol | Column holding the username |
userCredCol | Column holding the (hashed) password |
userRoleTable | Table mapping users to roles |
roleNameCol | Column holding the role name in userRoleTable |
localDataSource | true to look up the DataSource in the web application’s context rather than globally (default false) |
server.xml configuration:
<Resource> or inside the application’s <Context>.
JNDIRealm
JNDIRealm authenticates users against an LDAP or Active Directory server using the Java Naming and Directory Interface (JNDI) API. As described in the Javadoc, each authenticatable user is represented by an element in the directory context accessed via the connectionURL property.
Key attributes:
| Attribute | Description |
|---|---|
connectionURL | LDAP server URL, e.g. ldap://ldap.example.com:389 |
userPattern | DN pattern with {0} substituted by the username (simple bind approach) |
userBase | Base DN for user searches (alternative to userPattern) |
userSearch | LDAP filter for user searches, e.g. (uid={0}) |
userSubtree | true to search the entire subtree (default false) |
roleBase | Base DN to search for roles |
roleName | LDAP attribute holding the role name, e.g. cn |
roleSearch | LDAP filter to find roles, e.g. (member={0}) |
connectionName | DN used to bind for searching (leave empty for anonymous) |
connectionPassword | Password for connectionName |
userPassword | LDAP attribute holding the password (if empty, LDAP bind is used for authentication) |
Use
ldaps:// or configure StartTlsRequest via the useTls attribute to encrypt the LDAP connection. Sending bind passwords over plain LDAP is a security risk.JAASRealm
JAASRealm delegates authentication to a Java Authentication and Authorization Service (JAAS) LoginModule. This is the most flexible option because any existing JAAS module (Kerberos, smart-card, custom database, etc.) can be plugged in without modifying Tomcat.
The appName attribute is passed to javax.security.auth.login.LoginContext to select the named entry in the JAAS login configuration file. Tomcat then examines the Subject returned by the LoginModule and maps its Principal objects to a user identity and security roles using the userClassNames and roleClassNames attributes.
conf/jaas.config):
CATALINA_OPTS:
CombinedRealm
CombinedRealm chains multiple Realms together. Authentication is attempted against each nested Realm in declaration order; the first successful authentication wins. This is useful when migrating from one user store to another or when different classes of users are stored in different systems.
As shown in the source, CombinedRealm maintains an ordered List<Realm> and adds each nested <Realm> child element via addRealm().
Usernames must be unique across all combined realms. If the same username exists in two nested realms the first realm’s credentials take precedence.
LockOutRealm
LockOutRealm extends CombinedRealm to add brute-force protection. It tracks failed login attempts per username and temporarily locks out accounts that exceed the failure threshold. Importantly, it records attempts for non-existent usernames too, preventing attackers from distinguishing valid usernames through timing differences.
Attributes (with defaults from source):
| Attribute | Default | Description |
|---|---|---|
failureCount | 5 | Number of consecutive failures before lockout |
lockOutTime | 300 | Seconds a user is locked out after exceeding failureCount |
cacheSize | 1000 | Maximum number of failed-user entries to keep in the cache |
cacheRemovalWarningTime | 3600 | Log a warning if a failed-user entry is evicted from cache before this many seconds have elapsed |
LockOutRealm is the default outer wrapper in conf/server.xml:
LockOutRealm, including CombinedRealm, DataSourceRealm, or JNDIRealm.
Credential Handlers
Credential handlers tell Tomcat how stored passwords are encoded so it can verify them against user-supplied passwords. They are configured as child elements of the<Realm>.
MessageDigestCredentialHandler
MessageDigestCredentialHandler supports hex-encoded digests as well as the {MD5}, {SHA}, and {SSHA} prefix formats commonly used by LDAP directories. Supported forms from the Javadoc:
encodedCredential— hex-encoded digest{MD5}encodedCredential— Base64-encoded MD5 digest{SHA}encodedCredential— Base64-encoded SHA-1 digest{SSHA}encodedCredential— 20-byte SHA-1 digest + salt (Base64)salt$iterationCount$encodedCredential— salted, iterated hex digest
SecretKeyCredentialHandler
SecretKeyCredentialHandler uses PBKDF2 key derivation (e.g. PBKDF2WithHmacSHA256), which is the most resistant option against offline dictionary attacks.
Generating Hashed Passwords with digest.sh
Tomcat ships a digest.sh utility (digest.bat on Windows) to pre-hash passwords so they are never stored in plain text:
password attribute of the <user> element in tomcat-users.xml or into the database.
