Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
771 blopes 1
<!DOCTYPE html SYSTEM "about:legacy-compat">
2
<html lang="en"><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"><link href="./images/docs-stylesheet.css" rel="stylesheet" type="text/css"><title>Apache Tomcat 9 (9.0.112) - Realm Configuration How-To</title></head><body><div id="wrapper"><header><div id="header"><div><div><div class="logo noPrint"><a href="https://tomcat.apache.org/"><img alt="Tomcat Home" src="./images/tomcat.png"></a></div><div style="height: 1px;"></div><div class="asfLogo noPrint"><a href="https://www.apache.org/" target="_blank"><img src="./images/asf-logo.svg" alt="The Apache Software Foundation" style="width: 266px; height: 83px;"></a></div><h1>Apache Tomcat 9</h1><div class="versionInfo">
3
            Version 9.0.112,
4
            <time datetime="2025-11-06">Nov 6 2025</time></div><div style="height: 1px;"></div><div style="clear: left;"></div></div></div></div></header><div id="middle"><div><div id="mainLeft" class="noprint"><div><nav><div><h2>Links</h2><ul><li><a href="index.html">Docs Home</a></li><li><a href="https://cwiki.apache.org/confluence/display/TOMCAT/FAQ">FAQ</a></li></ul></div><div><h2>User Guide</h2><ul><li><a href="introduction.html">1) Introduction</a></li><li><a href="setup.html">2) Setup</a></li><li><a href="appdev/index.html">3) First webapp</a></li><li><a href="deployer-howto.html">4) Deployer</a></li><li><a href="manager-howto.html">5) Manager</a></li><li><a href="host-manager-howto.html">6) Host Manager</a></li><li><a href="realm-howto.html">7) Realms and AAA</a></li><li><a href="security-manager-howto.html">8) Security Manager</a></li><li><a href="jndi-resources-howto.html">9) JNDI Resources</a></li><li><a href="jndi-datasource-examples-howto.html">10) JDBC DataSources</a></li><li><a href="class-loader-howto.html">11) Classloading</a></li><li><a href="jasper-howto.html">12) JSPs</a></li><li><a href="ssl-howto.html">13) SSL/TLS</a></li><li><a href="ssi-howto.html">14) SSI</a></li><li><a href="cgi-howto.html">15) CGI</a></li><li><a href="proxy-howto.html">16) Proxy Support</a></li><li><a href="mbeans-descriptors-howto.html">17) MBeans Descriptors</a></li><li><a href="default-servlet.html">18) Default Servlet</a></li><li><a href="cluster-howto.html">19) Clustering</a></li><li><a href="balancer-howto.html">20) Load Balancer</a></li><li><a href="connectors.html">21) Connectors</a></li><li><a href="monitoring.html">22) Monitoring and Management</a></li><li><a href="logging.html">23) Logging</a></li><li><a href="apr.html">24) APR/Native</a></li><li><a href="virtual-hosting-howto.html">25) Virtual Hosting</a></li><li><a href="aio.html">26) Advanced IO</a></li><li><a href="maven-jars.html">27) Mavenized</a></li><li><a href="security-howto.html">28) Security Considerations</a></li><li><a href="windows-service-howto.html">29) Windows Service</a></li><li><a href="windows-auth-howto.html">30) Windows Authentication</a></li><li><a href="jdbc-pool.html">31) Tomcat's JDBC Pool</a></li><li><a href="web-socket-howto.html">32) WebSocket</a></li><li><a href="rewrite.html">33) Rewrite</a></li><li><a href="cdi.html">34) CDI 2 and JAX-RS</a></li><li><a href="graal.html">35) AOT/GraalVM Support</a></li></ul></div><div><h2>Reference</h2><ul><li><a href="RELEASE-NOTES.txt">Release Notes</a></li><li><a href="config/index.html">Configuration</a></li><li><a href="api/index.html">Tomcat Javadocs</a></li><li><a href="servletapi/index.html">Servlet 4.0 Javadocs</a></li><li><a href="jspapi/index.html">JSP 2.3 Javadocs</a></li><li><a href="elapi/index.html">EL 3.0 Javadocs</a></li><li><a href="websocketapi/index.html">WebSocket 1.1 Javadocs</a></li><li><a href="jaspicapi/index.html">JASPIC 1.1 Javadocs</a></li><li><a href="annotationapi/index.html">Common Annotations 1.3 Javadocs</a></li><li><a href="https://tomcat.apache.org/connectors-doc/">JK 1.2 Documentation</a></li></ul></div><div><h2>Apache Tomcat Development</h2><ul><li><a href="building.html">Building</a></li><li><a href="changelog.html">Changelog</a></li><li><a href="https://cwiki.apache.org/confluence/display/TOMCAT/Tomcat+Versions">Status</a></li><li><a href="developers.html">Developers</a></li><li><a href="architecture/index.html">Architecture</a></li><li><a href="tribes/introduction.html">Tribes</a></li></ul></div></nav></div></div><div id="mainRight"><div id="content"><h2>Realm Configuration How-To</h2><h3 id="Table_of_Contents">Table of Contents</h3><div class="text">
5
<ul><li><a href="#Quick_Start">Quick Start</a></li><li><a href="#Overview">Overview</a><ol><li><a href="#What_is_a_Realm?">What is a Realm?</a></li><li><a href="#Configuring_a_Realm">Configuring a Realm</a></li></ol></li><li><a href="#Common_Features">Common Features</a><ol><li><a href="#Digested_Passwords">Digested Passwords</a></li><li><a href="#Example_Application">Example Application</a></li><li><a href="#Manager_Application">Manager Application</a></li><li><a href="#Realm_Logging">Realm Logging</a></li></ol></li><li><a href="#Standard_Realm_Implementations">Standard Realm Implementations</a><ol><li><a href="#DataSourceRealm">DataSourceRealm</a></li><li><a href="#JNDIRealm">JNDIRealm</a></li><li><a href="#UserDatabaseRealm">UserDatabaseRealm</a></li><li><a href="#MemoryRealm">MemoryRealm</a></li><li><a href="#JAASRealm">JAASRealm</a></li><li><a href="#CombinedRealm">CombinedRealm</a></li><li><a href="#LockOutRealm">LockOutRealm</a></li><li><a href="#JDBCRealm">JDBCRealm</a></li></ol></li></ul>
6
</div><h3 id="Quick_Start">Quick Start</h3><div class="text">
7
 
8
<p>This document describes how to configure Tomcat to support <em>container
9
managed security</em>, by connecting to an existing "database" of usernames,
10
passwords, and user roles.  You only need to care about this if you are using
11
a web application that includes one or more
12
<code>&lt;security-constraint&gt;</code> elements, and a
13
<code>&lt;login-config&gt;</code> element defining how users are required
14
to authenticate themselves.  If you are not utilizing these features, you can
15
safely skip this document.</p>
16
 
17
<p>For fundamental background information about container managed security,
18
see the <a href="https://cwiki.apache.org/confluence/display/TOMCAT/Specifications">Servlet
19
Specification (Version 2.4)</a>, Section 12.</p>
20
 
21
<p>For information about utilizing the <em>Single Sign On</em> feature of
22
Tomcat (allowing a user to authenticate themselves once across the entire
23
set of web applications associated with a virtual host), see
24
<a href="config/host.html#Single_Sign_On">here</a>.</p>
25
 
26
</div><h3 id="Overview">Overview</h3><div class="text">
27
 
28
 
29
<div class="subsection"><h4 id="What_is_a_Realm?">What is a Realm?</h4><div class="text">
30
 
31
<p>A <strong>Realm</strong> is a "database" of usernames and passwords that
32
identify valid users of a web application (or set of web applications), plus
33
an enumeration of the list of <em>roles</em> associated with each valid user.
34
You can think of roles as similar to <em>groups</em> in Unix-like operating
35
systems, because access to specific web application resources is granted to
36
all users possessing a particular role (rather than enumerating the list of
37
associated usernames).  A particular user can have any number of roles
38
associated with their username.</p>
39
 
40
<p>Although the Servlet Specification describes a portable mechanism for
41
applications to <em>declare</em> their security requirements (in the
42
<code>web.xml</code> deployment descriptor), there is no portable API
43
defining the interface between a servlet container and the associated user
44
and role information.  In many cases, however, it is desirable to "connect"
45
a servlet container to some existing authentication database or mechanism
46
that already exists in the production environment.  Therefore, Tomcat
47
defines a Java interface (<code>org.apache.catalina.Realm</code>) that
48
can be implemented by "plug in" components to establish this connection.
49
Six standard plug-ins are provided, supporting connections to various
50
sources of authentication information:</p>
51
<ul>
52
<li><a href="#JDBCRealm">JDBCRealm</a> - Accesses authentication information
53
    stored in a relational database, accessed via a JDBC driver.</li>
54
<li><a href="#DataSourceRealm">DataSourceRealm</a> - Accesses authentication
55
    information stored in a relational database, accessed via a named JNDI
56
    JDBC DataSource.</li>
57
<li><a href="#JNDIRealm">JNDIRealm</a> - Accesses authentication information
58
    stored in an LDAP based directory server, accessed via a JNDI provider.
59
    </li>
60
<li><a href="#UserDatabaseRealm">UserDatabaseRealm</a> - Accesses authentication
61
    information stored in an UserDatabase JNDI resource, which is typically
62
    backed by an XML document (<code>conf/tomcat-users.xml</code>).</li>
63
<li><a href="#MemoryRealm">MemoryRealm</a> - Accesses authentication
64
    information stored in an in-memory object collection, which is initialized
65
    from an XML document (<code>conf/tomcat-users.xml</code>).</li>
66
<li><a href="#JAASRealm">JAASRealm</a> - Accesses authentication information
67
    through the Java Authentication &amp; Authorization Service (JAAS)
68
    framework.</li>
69
</ul>
70
 
71
<p>It is also possible to write your own <code>Realm</code> implementation,
72
and integrate it with Tomcat.  To do so, you need to:</p>
73
<ul>
74
  <li>Implement <code>org.apache.catalina.Realm</code>,</li>
75
  <li>Place your compiled realm in $CATALINA_HOME/lib,</li>
76
  <li>Declare your realm as described in the "Configuring a Realm" section below,</li>
77
  <li>Declare your realm to the <a href="mbeans-descriptors-howto.html">MBeans Descriptors</a>.</li>
78
</ul>
79
 
80
</div></div>
81
 
82
 
83
<div class="subsection"><h4 id="Configuring_a_Realm">Configuring a Realm</h4><div class="text">
84
 
85
<p>Before getting into the details of the standard Realm implementations, it is
86
important to understand, in general terms, how a Realm is configured.  In
87
general, you will be adding an XML element to your <code>conf/server.xml</code>
88
configuration file, that looks something like this:</p>
89
 
90
<div class="codeBox"><pre><code>&lt;Realm className="... class name for this implementation"
91
       ... other attributes for this implementation .../&gt;</code></pre></div>
92
 
93
<p>The <code>&lt;Realm&gt;</code> element can be nested inside any one of
94
of the following <code>Container</code> elements.  The location of the
95
Realm element has a direct impact on the "scope" of that Realm
96
(i.e. which web applications will share the same authentication information):
97
</p>
98
<ul>
99
<li><em>Inside an &lt;Engine&gt; element</em> - This Realm will be shared
100
    across ALL web applications on ALL virtual hosts, UNLESS it is overridden
101
    by a Realm element nested inside a subordinate <code>&lt;Host&gt;</code>
102
    or <code>&lt;Context&gt;</code> element.</li>
103
<li><em>Inside a &lt;Host&gt; element</em> - This Realm will be shared across
104
    ALL web applications for THIS virtual host, UNLESS it is overridden
105
    by a Realm element nested inside a subordinate <code>&lt;Context&gt;</code>
106
    element.</li>
107
<li><em>Inside a &lt;Context&gt; element</em> - This Realm will be used ONLY
108
    for THIS web application.</li>
109
</ul>
110
 
111
 
112
</div></div>
113
 
114
 
115
</div><h3 id="Common_Features">Common Features</h3><div class="text">
116
 
117
 
118
<div class="subsection"><h4 id="Digested_Passwords">Digested Passwords</h4><div class="text">
119
 
120
<p>For each of the standard <code>Realm</code> implementations, the
121
user's password (by default) is stored in clear text.  In many
122
environments, this is undesirable because casual observers of the
123
authentication data can collect enough information to log on
124
successfully, and impersonate other users.  To avoid this problem, the
125
standard implementations support the concept of <em>digesting</em>
126
user passwords.  This allows the stored version of the passwords to be
127
encoded (in a form that is not easily reversible), but that the
128
<code>Realm</code> implementation can still utilize for
129
authentication.</p>
130
 
131
<p>When a standard realm authenticates by retrieving the stored
132
password and comparing it with the value presented by the user, you
133
can select digested passwords by placing a <a href="config/credentialhandler.html">
134
<code>CredentialHandler</code></a> element inside your <code>&lt;Realm&gt;</code>
135
element. An easy choice to support one of the algorithms SSHA, SHA or MD5
136
would be the usage of the <code>MessageDigestCredentialHandler</code>.
137
This element must be configured to one of the digest algorithms supported
138
by the <code>java.security.MessageDigest</code> class (SSHA, SHA or MD5).
139
When you select this option, the contents of the password that is stored
140
in the <code>Realm</code> must be the cleartext version of the password,
141
as digested by the specified algorithm.</p>
142
 
143
<p>When the <code>authenticate()</code> method of the Realm is called, the
144
(cleartext) password specified by the user is itself digested by the same
145
algorithm, and the result is compared with the value returned by the
146
<code>Realm</code>.  An equal match implies that the cleartext version of the
147
original password is the same as the one presented by the user, so that this
148
user should be authorized.</p>
149
 
150
<p>To calculate the digested value of a cleartext password, two convenience
151
techniques are supported:</p>
152
<ul>
153
<li>If you are writing an application that needs to calculate digested
154
    passwords dynamically, call the static <code>Digest()</code> method of the
155
    <code>org.apache.catalina.realm.RealmBase</code> class, passing the
156
    cleartext password, the digest algorithm name and the encoding as arguments.
157
    This method will return the digested password.</li>
158
<li>If you want to execute a command line utility to calculate the digested
159
    password, simply execute
160
<div class="codeBox"><pre><code>CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password}</code></pre></div>
161
    and the digested version of this cleartext password will be returned to
162
    standard output.</li>
163
</ul>
164
 
165
<p>If using digested passwords with DIGEST authentication, the cleartext used
166
   to generate the digest is different and the digest must use one iteration of
167
   the MD5 algorithm with no salt. In the examples above
168
   <code>{cleartext-password}</code> must be replaced with
169
   <code>{username}:{realm}:{cleartext-password}</code>. For example, in a
170
   development environment this might take the form
171
   <code>testUser:Authentication required:testPassword</code>. The value for
172
   <code>{realm}</code> is taken from the <code>&lt;realm-name&gt;</code>
173
   element of the web application's <code>&lt;login-config&gt;</code>. If
174
   not specified in web.xml, the default value of <code>Authentication
175
   required</code> is used.</p>
176
 
177
<p>Usernames and/or passwords using encodings other than the platform default
178
are supported using</p>
179
<div class="codeBox"><pre><code>CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} -e {encoding} {input}</code></pre></div>
180
<p>but care is required to ensure that the input is correctly passed to the
181
digester. The digester returns <code>{input}:{digest}</code>. If the input
182
appears corrupted in the return, the digest will be invalid.</p>
183
 
184
<p>The output format of the digest is <code>{salt}${iterations}${digest}</code>.
185
If the salt length is zero and the iteration count is one, the output is
186
simplified to <code>{digest}</code>.</p>
187
 
188
<p>The full syntax of <code>CATALINA_HOME/bin/digest.[bat|sh]</code> is:</p>
189
<div class="codeBox"><pre><code>CATALINA_HOME/bin/digest.[bat|sh] [-a &lt;algorithm&gt;] [-e &lt;encoding&gt;]
190
        [-i &lt;iterations&gt;] [-s &lt;salt-length&gt;] [-k &lt;key-length&gt;]
191
        [-h &lt;handler-class-name&gt;] [-f &lt;password-file&gt; | &lt;credentials&gt;]
192
</code></pre></div>
193
<ul>
194
<li><b>-a</b> - The algorithm to use to generate the stored
195
                credential. If not specified, the default for the handler will
196
                be used. If neither handler nor algorithm is specified then a
197
                default of <code>SHA-512</code> will be used</li>
198
<li><b>-e</b> - The encoding to use for any byte to/from character
199
                conversion that may be necessary. If not specified, the
200
                system encoding (<code>Charset#defaultCharset()</code>) will
201
                be used.</li>
202
<li><b>-i</b> - The number of iterations to use when generating the
203
                stored credential. If not specified, the default for the
204
                CredentialHandler will be used.</li>
205
<li><b>-s</b> - The length (in bytes) of salt to generate and store as
206
                part of the credential. If not specified, the default for
207
                the CredentialHandler will be used.</li>
208
<li><b>-k</b> - The length (in bits) of the key(s), if any, created while
209
                generating the credential. If not specified, the default
210
                for the CredentialHandler will be used.</li>
211
<li><b>-h</b> - The fully qualified class name of the CredentialHandler
212
                to use. If not specified, the built-in handlers will be
213
                tested in turn (MessageDigestCredentialHandler then
214
                SecretKeyCredentialHandler) and the first one to accept the
215
                specified algorithm will be used.</li>
216
<li><b>-f</b> - The name of the file that contains passwords to encode. Each
217
                line in the file should contain only one password. Using this
218
                option ignores other password input.</li>
219
</ul>
220
</div></div>
221
 
222
 
223
 
224
<div class="subsection"><h4 id="Example_Application">Example Application</h4><div class="text">
225
 
226
<p>The example application shipped with Tomcat includes an area that is
227
protected by a security constraint, utilizing form-based login.  To access it,
228
point your browser at
229
<a href="http://localhost:8080/examples/jsp/security/protected/">http://localhost:8080/examples/jsp/security/protected/</a>
230
and log on with one of the usernames and passwords described for the default
231
<a href="#UserDatabaseRealm">UserDatabaseRealm</a>.</p>
232
 
233
</div></div>
234
 
235
 
236
<div class="subsection"><h4 id="Manager_Application">Manager Application</h4><div class="text">
237
 
238
<p>If you wish to use the <a href="manager-howto.html">Manager Application</a>
239
to deploy and undeploy applications in a running Tomcat installation, you
240
MUST add the "manager-gui" role to at least one username in your selected
241
Realm implementation.  This is because the manager web application itself uses a
242
security constraint that requires role "manager-gui" to access ANY request URI
243
within the HTML interface of that application.</p>
244
 
245
<p>For security reasons, no username in the default Realm (i.e. using
246
<code>conf/tomcat-users.xml</code> is assigned the "manager-gui" role.
247
Therefore, no one will be able to utilize the features of this application
248
until the Tomcat administrator specifically assigns this role to one or more
249
users.</p>
250
 
251
</div></div>
252
 
253
<div class="subsection"><h4 id="Realm_Logging">Realm Logging</h4><div class="text">
254
 
255
<p>Debugging and exception messages logged by a <code>Realm</code> will
256
   be recorded by the logging configuration associated with the container
257
   for the realm: its surrounding <a href="config/context.html">Context</a>,
258
   <a href="config/host.html">Host</a>, or
259
   <a href="config/engine.html">Engine</a>.</p>
260
 
261
</div></div>
262
 
263
</div><h3 id="Standard_Realm_Implementations">Standard Realm Implementations</h3><div class="text">
264
 
265
<div class="subsection"><h4 id="DataSourceRealm">DataSourceRealm</h4><div class="text">
266
 
267
<h5>Introduction</h5>
268
 
269
<p><strong>DataSourceRealm</strong> is an implementation of the Tomcat
270
<code>Realm</code> interface that looks up users in a relational database
271
accessed via a JNDI named JDBC DataSource.  There is substantial configuration
272
flexibility that lets you adapt to existing table and column names, as long
273
as your database structure conforms to the following requirements:</p>
274
<ul>
275
<li>There must be a table, referenced below as the <em>users</em> table,
276
    that contains one row for every valid user that this <code>Realm</code>
277
    should recognize.</li>
278
<li>The <em>users</em> table must contain at least two columns (it may
279
    contain more if your existing applications required it):
280
    <ul>
281
    <li>Username to be recognized by Tomcat when the user logs in.</li>
282
    <li>Password to be recognized by Tomcat when the user logs in.
283
        This value may in cleartext or digested - see below for more
284
        information.</li>
285
    </ul></li>
286
<li>There must be a table, referenced below as the <em>user roles</em> table,
287
    that contains one row for every valid role that is assigned to a
288
    particular user.  It is legal for a user to have zero, one, or more than
289
    one valid role.</li>
290
<li>The <em>user roles</em> table must contain at least two columns (it may
291
    contain more if your existing applications required it):
292
    <ul>
293
    <li>Username to be recognized by Tomcat (same value as is specified
294
        in the <em>users</em> table).</li>
295
    <li>Role name of a valid role associated with this user.</li>
296
    </ul></li>
297
</ul>
298
 
299
<h5>Quick Start</h5>
300
 
301
<p>To set up Tomcat to use DataSourceRealm, you will need to follow these steps:</p>
302
<ol>
303
<li>If you have not yet done so, create tables and columns in your database
304
    that conform to the requirements described above.</li>
305
<li>Configure a database username and password for use by Tomcat, that has
306
    at least read only access to the tables described above.  (Tomcat will
307
    never attempt to write to these tables.)</li>
308
<li>Configure a JNDI named JDBC DataSource for your database.  Refer to the
309
    <a href="jndi-datasource-examples-howto.html">JNDI DataSource Example
310
    How-To</a> for information on how to configure a JNDI named JDBC DataSource.
311
    Be sure to set the <code>Realm</code>'s <code>localDataSource</code>
312
    attribute appropriately, depending on where the JNDI DataSource is
313
    defined.</li>
314
<li>Set up a <code>&lt;Realm&gt;</code> element, as described below, in your
315
    <code>$CATALINA_BASE/conf/server.xml</code> file.</li>
316
<li>Restart Tomcat if it is already running.</li>
317
</ol>
318
 
319
<h5>Realm Element Attributes</h5>
320
 
321
<p>To configure DataSourceRealm, you will create a <code>&lt;Realm&gt;</code>
322
element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
323
as described <a href="#Configuring_a_Realm">above</a>. The attributes for the
324
DataSourceRealm are defined in the <a href="config/realm.html">Realm</a>
325
configuration documentation.</p>
326
 
327
<h5>Example</h5>
328
 
329
<p>An example SQL script to create the needed tables might look something
330
like this (adapt the syntax as required for your particular database):</p>
331
<div class="codeBox"><pre><code>create table users (
332
  user_name         varchar(15) not null primary key,
333
  user_pass         varchar(15) not null
334
);
335
 
336
create table user_roles (
337
  user_name         varchar(15) not null,
338
  role_name         varchar(15) not null,
339
  primary key (user_name, role_name)
340
);</code></pre></div>
341
 
342
<p>Here is an example for using a MySQL database called "authority", configured
343
with the tables described above, and accessed with the JNDI JDBC DataSource with
344
name "java:/comp/env/jdbc/authority".</p>
345
<div class="codeBox"><pre><code>&lt;Realm className="org.apache.catalina.realm.DataSourceRealm"
346
   dataSourceName="jdbc/authority"
347
   userTable="users" userNameCol="user_name" userCredCol="user_pass"
348
   userRoleTable="user_roles" roleNameCol="role_name"/&gt;</code></pre></div>
349
 
350
<h5>Additional Notes</h5>
351
 
352
<p>DataSourceRealm operates according to the following rules:</p>
353
<ul>
354
<li>When a user attempts to access a protected resource for the first time,
355
    Tomcat will call the <code>authenticate()</code> method of this
356
    <code>Realm</code>.  Thus, any changes you have made to the database
357
    directly (new users, changed passwords or roles, etc.) will be immediately
358
    reflected.</li>
359
<li>Once a user has been authenticated, the user (and their associated
360
    roles) are cached within Tomcat for the duration of the user's login.
361
    (For FORM-based authentication, that means until the session times out or
362
    is invalidated; for BASIC authentication, that means until the user
363
    closes their browser).  The cached user is <strong>not</strong> saved and
364
    restored across sessions serialisations. Any changes to the database
365
    information for an already authenticated user will <strong>not</strong> be
366
    reflected until the next time that user logs on again.</li>
367
<li>Administering the information in the <em>users</em> and <em>user roles</em>
368
    table is the responsibility of your own applications.  Tomcat does not
369
    provide any built-in capabilities to maintain users and roles.</li>
370
</ul>
371
 
372
</div></div>
373
 
374
 
375
<div class="subsection"><h4 id="JNDIRealm">JNDIRealm</h4><div class="text">
376
 
377
<h5>Introduction</h5>
378
 
379
<p><strong>JNDIRealm</strong> is an implementation of the Tomcat
380
<code>Realm</code> interface that looks up users in an LDAP directory
381
server accessed by a JNDI provider (typically, the standard LDAP
382
provider that is available with the JNDI API classes). The realm
383
supports a variety of approaches to using a directory for
384
authentication.</p>
385
 
386
<h6>Connecting to the directory</h6>
387
 
388
<p>The realm's connection to the directory is defined by the
389
<strong>connectionURL</strong> configuration attribute. This is a URL
390
whose format is defined by the JNDI provider. It is usually an LDAP
391
URL that specifies the domain name of the directory server to connect
392
to, and optionally the port number and distinguished name (DN) of the
393
required root naming context.</p>
394
 
395
<p>If you have more than one provider you can configure an
396
<strong>alternateURL</strong>.  If a socket connection cannot be
397
made to the provider at the <strong>connectionURL</strong> an
398
attempt will be made to use the <strong>alternateURL</strong>.</p>
399
 
400
<p>When making a connection in order to search the directory and
401
retrieve user and role information, the realm authenticates itself to
402
the directory with the username and password specified by the
403
<strong>connectionName</strong> and
404
<strong>connectionPassword</strong> properties. If these properties
405
are not specified the connection is anonymous. This is sufficient in
406
many cases.
407
</p>
408
 
409
 
410
<h6>Selecting the user's directory entry</h6>
411
 
412
<p>Each user that can be authenticated must be represented in the
413
directory by an individual entry that corresponds to an element in the
414
initial <code>DirContext</code> defined by the
415
<strong>connectionURL</strong> attribute. This user entry must have an
416
attribute containing the username that is presented for
417
authentication.</p>
418
 
419
<p>Often the distinguished name of the user's entry contains the
420
username presented for authentication but is otherwise the same for
421
all users. In this case the <strong>userPattern</strong> attribute may
422
be used to specify the DN, with "{0}" marking where
423
the username should be substituted.</p>
424
 
425
<p>Otherwise the realm must search the directory to find a unique entry
426
containing the username. The following attributes configure this
427
search:</p>
428
 
429
     <ul>
430
     <li><strong>userBase</strong> - the entry that is the base of
431
         the subtree containing users.  If not specified, the search
432
         base is the top-level context.</li>
433
 
434
     <li><strong>userSubtree</strong> - the search scope. Set to
435
         <code>true</code> if you wish to search the entire subtree
436
         rooted at the <strong>userBase</strong> entry. The default value
437
         of <code>false</code> requests a single-level search
438
         including only the top level.</li>
439
 
440
     <li><strong>userSearch</strong> - pattern specifying the LDAP
441
         search filter to use after substitution of the username.</li>
442
 
443
    </ul>
444
 
445
 
446
<h6>Authenticating the user</h6>
447
 
448
<ul>
449
<li>
450
<p><b>Bind mode</b></p>
451
 
452
<p>By default the realm authenticates a user by binding to
453
the directory with the DN of the entry for that user and the password
454
presented by the user. If this simple bind succeeds the user is considered to
455
be authenticated.</p>
456
 
457
<p>For security reasons a directory may store a digest of the user's
458
password rather than the clear text version (see
459
<a href="#Digested_Passwords">Digested Passwords</a> for more information). In that case,
460
as part of the simple bind operation the directory automatically
461
computes the correct digest of the plaintext password presented by the
462
user before validating it against the stored value. In bind mode,
463
therefore, the realm is not involved in digest processing. The
464
<strong>digest</strong> attribute is not used, and will be ignored if
465
set.</p>
466
</li>
467
 
468
<li>
469
<p><b>Comparison mode</b></p>
470
<p>Alternatively, the realm may retrieve the stored
471
password from the directory and compare it explicitly with the value
472
presented by the user. This mode is configured by setting the
473
<strong>userPassword</strong> attribute to the name of a directory
474
attribute in the user's entry that contains the password.</p>
475
 
476
<p>Comparison mode has some disadvantages. First, the
477
<strong>connectionName</strong> and
478
<strong>connectionPassword</strong> attributes must be configured to
479
allow the realm to read users' passwords in the directory. For
480
security reasons this is generally undesirable; indeed many directory
481
implementations will not allow even the directory manager to read
482
these passwords. In addition, the realm must handle password digests
483
itself, including variations in the algorithms used and ways of
484
representing password hashes in the directory. However, the realm may
485
sometimes need access to the stored password, for example to support
486
HTTP Digest Access Authentication (RFC 2069). (Note that HTTP digest
487
authentication is different from the storage of password digests in
488
the repository for user information as discussed above).
489
</p>
490
</li>
491
</ul>
492
 
493
<h6>Assigning roles to the user</h6>
494
 
495
<p>The directory realm supports two approaches to the representation
496
of roles in the directory:</p>
497
 
498
<ul>
499
<li>
500
<p><b>Roles as explicit directory entries</b></p>
501
 
502
<p>Roles may be represented by explicit directory entries. A role
503
entry is usually an LDAP group entry with one attribute
504
containing the name of the role and another whose values are the
505
distinguished names or usernames of the users in that role.  The
506
following attributes configure a directory search to
507
find the names of roles associated with the authenticated user:</p>
508
 
509
<ul>
510
<li><strong>roleBase</strong> - the base entry for the role search.
511
    If not specified, the search base is the top-level directory
512
    context.</li>
513
 
514
<li><strong>roleSubtree</strong> - the search
515
    scope. Set to <code>true</code> if you wish to search the entire
516
    subtree rooted at the <code>roleBase</code> entry. The default
517
    value of <code>false</code> requests a single-level search
518
    including the top level only.</li>
519
 
520
<li><strong>roleSearch</strong> - the LDAP search filter for
521
    selecting role entries. It optionally includes pattern
522
    replacements "{0}" for the distinguished name and/or "{1}" for the
523
    username and/or "{2}" for an attribute from user's directory entry,
524
    of the authenticated user. Use <strong>userRoleAttribute</strong> to
525
    specify the name of the attribute that provides the value for "{2}".</li>
526
 
527
<li><strong>roleName</strong> - the attribute in a role entry
528
     containing the name of that role.</li>
529
 
530
<li><strong>roleNested</strong> - enable nested roles. Set to
531
     <code>true</code> if you want to nest roles in roles. If configured, then
532
     every newly found roleName and distinguished
533
     Name will be recursively tried for a new role search.
534
     The default value is <code>false</code>.</li>
535
 
536
</ul>
537
 
538
</li>
539
</ul>
540
 
541
<ul>
542
<li>
543
<p><b>Roles as an attribute of the user entry</b></p>
544
 
545
<p>Role names may also be held as the values of an attribute in the
546
user's directory entry. Use <strong>userRoleName</strong> to specify
547
the name of this attribute.</p>
548
 
549
</li>
550
</ul>
551
<p>A combination of both approaches to role representation may be used.</p>
552
 
553
<h5>Quick Start</h5>
554
 
555
<p>To set up Tomcat to use JNDIRealm, you will need to follow these steps:</p>
556
<ol>
557
<li>Make sure your directory server is configured with a schema that matches
558
    the requirements listed above.</li>
559
<li>If required, configure a username and password for use by Tomcat, that has
560
    read only access to the information described above.  (Tomcat will
561
    never attempt to modify this information.)</li>
562
<li>Set up a <code>&lt;Realm&gt;</code> element, as described below, in your
563
    <code>$CATALINA_BASE/conf/server.xml</code> file.</li>
564
<li>Restart Tomcat if it is already running.</li>
565
</ol>
566
 
567
<h5>Realm Element Attributes</h5>
568
 
569
<p>To configure JNDIRealm, you will create a <code>&lt;Realm&gt;</code>
570
element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
571
as described <a href="#Configuring_a_Realm">above</a>. The attributes for the
572
JNDIRealm are defined in the <a href="config/realm.html">Realm</a> configuration
573
documentation.</p>
574
 
575
<h5>Example</h5>
576
 
577
<p>Creation of the appropriate schema in your directory server is beyond the
578
scope of this document, because it is unique to each directory server
579
implementation.  In the examples below, we will assume that you are using a
580
distribution of the OpenLDAP directory server (version 2.0.11 or later), which
581
can be downloaded from
582
<a href="https://www.openldap.org">https://www.openldap.org</a>.  Assume that
583
your <code>slapd.conf</code> file contains the following settings
584
(among others):</p>
585
<div class="codeBox"><pre><code>database ldbm
586
suffix dc="mycompany",dc="com"
587
rootdn "cn=Manager,dc=mycompany,dc=com"
588
rootpw secret</code></pre></div>
589
 
590
<p>We will assume for <code>connectionURL</code> that the directory
591
server runs on the same machine as Tomcat.  See <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html">
592
http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html</a>
593
for more information about configuring and using the JNDI LDAP
594
provider.</p>
595
 
596
<p>Next, assume that this directory server has been populated with elements
597
as shown below (in LDIF format):</p>
598
 
599
<div class="codeBox"><pre><code># Define top-level entry
600
dn: dc=mycompany,dc=com
601
objectClass: dcObject
602
dc:mycompany
603
 
604
# Define an entry to contain people
605
# searches for users are based on this entry
606
dn: ou=people,dc=mycompany,dc=com
607
objectClass: organizationalUnit
608
ou: people
609
 
610
# Define a user entry for Janet Jones
611
dn: uid=jjones,ou=people,dc=mycompany,dc=com
612
objectClass: inetOrgPerson
613
uid: jjones
614
sn: jones
615
cn: janet jones
616
mail: j.jones@mycompany.com
617
userPassword: janet
618
 
619
# Define a user entry for Fred Bloggs
620
dn: uid=fbloggs,ou=people,dc=mycompany,dc=com
621
objectClass: inetOrgPerson
622
uid: fbloggs
623
sn: bloggs
624
cn: fred bloggs
625
mail: f.bloggs@mycompany.com
626
userPassword: fred
627
 
628
# Define an entry to contain LDAP groups
629
# searches for roles are based on this entry
630
dn: ou=groups,dc=mycompany,dc=com
631
objectClass: organizationalUnit
632
ou: groups
633
 
634
# Define an entry for the "tomcat" role
635
dn: cn=tomcat,ou=groups,dc=mycompany,dc=com
636
objectClass: groupOfUniqueNames
637
cn: tomcat
638
uniqueMember: uid=jjones,ou=people,dc=mycompany,dc=com
639
uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com
640
 
641
# Define an entry for the "role1" role
642
dn: cn=role1,ou=groups,dc=mycompany,dc=com
643
objectClass: groupOfUniqueNames
644
cn: role1
645
uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com</code></pre></div>
646
 
647
<p>An example <code>Realm</code> element for the OpenLDAP directory
648
server configured as described above might look like this, assuming
649
that users use their uid (e.g. jjones) to login to the
650
application and that an anonymous connection is sufficient to search
651
the directory and retrieve role information:</p>
652
 
653
<div class="codeBox"><pre><code>&lt;Realm   className="org.apache.catalina.realm.JNDIRealm"
654
     connectionURL="ldap://localhost:389"
655
       userPattern="uid={0},ou=people,dc=mycompany,dc=com"
656
          roleBase="ou=groups,dc=mycompany,dc=com"
657
          roleName="cn"
658
        roleSearch="(uniqueMember={0})"
659
/&gt;</code></pre></div>
660
 
661
<p>With this configuration, the realm will determine the user's
662
distinguished name by substituting the username into the
663
<code>userPattern</code>, authenticate by binding to the directory
664
with this DN and the password received from the user, and search the
665
directory to find the user's roles.</p>
666
 
667
<p>Now suppose that users are expected to enter their email address
668
rather than their userid when logging in. In this case the realm must
669
search the directory for the user's entry. (A search is also necessary
670
when user entries are held in multiple subtrees corresponding perhaps
671
to different organizational units or company locations).</p>
672
 
673
<p>Further, suppose that in addition to the group entries you want to
674
use an attribute of the user's entry to hold roles. Now the entry for
675
Janet Jones might read as follows:</p>
676
 
677
<div class="codeBox"><pre><code>dn: uid=jjones,ou=people,dc=mycompany,dc=com
678
objectClass: inetOrgPerson
679
uid: jjones
680
sn: jones
681
cn: janet jones
682
mail: j.jones@mycompany.com
683
memberOf: role2
684
memberOf: role3
685
userPassword: janet</code></pre></div>
686
 
687
<p> This realm configuration would satisfy the new requirements:</p>
688
 
689
<div class="codeBox"><pre><code>&lt;Realm   className="org.apache.catalina.realm.JNDIRealm"
690
     connectionURL="ldap://localhost:389"
691
          userBase="ou=people,dc=mycompany,dc=com"
692
        userSearch="(mail={0})"
693
      userRoleName="memberOf"
694
          roleBase="ou=groups,dc=mycompany,dc=com"
695
          roleName="cn"
696
        roleSearch="(uniqueMember={0})"
697
/&gt;</code></pre></div>
698
 
699
<p>Now when Janet Jones logs in as "j.jones@mycompany.com", the realm
700
searches the directory for a unique entry with that value as its mail
701
attribute and attempts to bind to the directory as
702
<code>uid=jjones,ou=people,dc=mycompany,dc=com</code> with the given
703
password. If authentication succeeds, they are assigned three roles:
704
"role2" and "role3", the values of the "memberOf" attribute in their
705
directory entry, and "tomcat", the value of the "cn" attribute in the
706
only group entry of which they are a member.</p>
707
 
708
<p>Finally, to authenticate the user by retrieving
709
the password from the directory and making a local comparison in the
710
realm, you might use a realm configuration like this:</p>
711
 
712
<div class="codeBox"><pre><code>&lt;Realm   className="org.apache.catalina.realm.JNDIRealm"
713
    connectionName="cn=Manager,dc=mycompany,dc=com"
714
connectionPassword="secret"
715
     connectionURL="ldap://localhost:389"
716
      userPassword="userPassword"
717
       userPattern="uid={0},ou=people,dc=mycompany,dc=com"
718
          roleBase="ou=groups,dc=mycompany,dc=com"
719
          roleName="cn"
720
        roleSearch="(uniqueMember={0})"
721
/&gt;</code></pre></div>
722
 
723
<p>However, as discussed above, the default bind mode for
724
authentication is usually to be preferred.</p>
725
 
726
<h5>Additional Notes</h5>
727
 
728
<p>JNDIRealm operates according to the following rules:</p>
729
<ul>
730
<li>When a user attempts to access a protected resource for the first time,
731
    Tomcat will call the <code>authenticate()</code> method of this
732
    <code>Realm</code>.  Thus, any changes you have made to the directory
733
    (new users, changed passwords or roles, etc.) will be immediately
734
    reflected.</li>
735
<li>Once a user has been authenticated, the user (and their associated
736
    roles) are cached within Tomcat for the duration of the user's login.
737
    (For FORM-based authentication, that means until the session times out or
738
    is invalidated; for BASIC authentication, that means until the user
739
    closes their browser).  The cached user is <strong>not</strong> saved and
740
    restored across sessions serialisations. Any changes to the directory
741
    information for an already authenticated user will <strong>not</strong> be
742
    reflected until the next time that user logs on again.</li>
743
<li>Administering the information in the directory server
744
    is the responsibility of your own applications.  Tomcat does not
745
    provide any built-in capabilities to maintain users and roles.</li>
746
</ul>
747
 
748
</div></div>
749
 
750
 
751
<div class="subsection"><h4 id="UserDatabaseRealm">UserDatabaseRealm</h4><div class="text">
752
 
753
<h5>Introduction</h5>
754
 
755
<p><strong>UserDatabaseRealm</strong> is an implementation of the Tomcat
756
<code>Realm</code> interface that uses a JNDI resource to store user
757
information. By default, the JNDI resource is backed by an XML file. It is not
758
designed for large-scale production use. At startup time, the UserDatabaseRealm
759
loads information about all users, and their corresponding roles, from an XML
760
document (by default, this document is loaded from
761
<code>$CATALINA_BASE/conf/tomcat-users.xml</code>). The users, their passwords
762
and their roles may all be editing dynamically, typically via JMX. Changes may
763
be saved and will be reflected in the XML file.</p>
764
 
765
<h5>Realm Element Attributes</h5>
766
 
767
<p>To configure UserDatabaseRealm, you will create a <code>&lt;Realm&gt;</code>
768
element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
769
as described <a href="#Configuring_a_Realm">above</a>. The attributes for the
770
UserDatabaseRealm are defined in the <a href="config/realm.html">Realm</a>
771
configuration documentation.</p>
772
 
773
<h5>User File Format</h5>
774
 
775
<p>For the XML file based <code>UserDatabase</code>, the users file uses the
776
same format as the <a href="#MemoryRealm">MemoryRealm</a>.</p>
777
 
778
<h5>Example</h5>
779
 
780
<p>The default installation of Tomcat is configured with a UserDatabaseRealm
781
nested inside the <code>&lt;Engine&gt;</code> element, so that it applies
782
to all virtual hosts and web applications.  The default contents of the
783
<code>conf/tomcat-users.xml</code> file is:</p>
784
<div class="codeBox"><pre><code>&lt;tomcat-users&gt;
785
  &lt;user username="tomcat" password="tomcat" roles="tomcat" /&gt;
786
  &lt;user username="role1"  password="tomcat" roles="role1"  /&gt;
787
  &lt;user username="both"   password="tomcat" roles="tomcat,role1" /&gt;
788
&lt;/tomcat-users&gt;</code></pre></div>
789
 
790
<h5>Additional Notes</h5>
791
 
792
<p>UserDatabaseRealm operates according to the following rules:</p>
793
<ul>
794
<li>When Tomcat first starts up, it loads all defined users and their
795
    associated information from the users file. Changes made to the data in
796
    this file will <strong>not</strong> be recognized until Tomcat is
797
    restarted. Changes may be made via the UserDatabase resource. Tomcat
798
    provides MBeans that may be accessed via JMX for this purpose.</li>
799
<li>When a user attempts to access a protected resource for the first time,
800
    Tomcat will call the <code>authenticate()</code> method of this
801
    <code>Realm</code>.</li>
802
<li>Once a user has been authenticated, the user becomes associated within
803
    Tomcat for the duration of the user's login.
804
    (For FORM-based authentication, that means until the session times out or
805
    is invalidated; for BASIC authentication, that means until the user
806
    closes their browser). However, the user roles will still reflect the
807
    <code>UserDatabase</code> contents, unlike for the other realms. If a user
808
    is removed from the database, it will be considered to have no roles.
809
    The <code>useStaticPrincipal</code> attribute of the
810
    <code>UserDatabaseRealm</code> can be used to instead cache the user along
811
    with all its roles. The cached user is <strong>not</strong> saved and
812
    restored across sessions serialisations. When the user's principal object
813
    is serialized for any reason, it will also be replaced by a static
814
    equivalent object with roles that will no longer reflect the database
815
    contents.</li>
816
</ul>
817
 
818
 
819
</div></div>
820
 
821
 
822
<div class="subsection"><h4 id="MemoryRealm">MemoryRealm</h4><div class="text">
823
 
824
<h5>Introduction</h5>
825
 
826
<p><strong>MemoryRealm</strong> is a simple demonstration implementation of the
827
Tomcat <code>Realm</code> interface.  It is not designed for production use.
828
At startup time, MemoryRealm loads information about all users, and their
829
corresponding roles, from an XML document (by default, this document is loaded
830
from <code>$CATALINA_BASE/conf/tomcat-users.xml</code>).  Changes to the data
831
in this file are not recognized until Tomcat is restarted.</p>
832
 
833
<h5>Realm Element Attributes</h5>
834
 
835
<p>To configure MemoryRealm, you will create a <code>&lt;Realm&gt;</code>
836
element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
837
as described <a href="#Configuring_a_Realm">above</a>. The attributes for the
838
MemoryRealm are defined in the <a href="config/realm.html">Realm</a>
839
configuration documentation.</p>
840
 
841
<h5>User File Format</h5>
842
 
843
<p>The users file (by default, <code>conf/tomcat-users.xml</code> must be an
844
XML document, with a root element <code>&lt;tomcat-users&gt;</code>.  Nested
845
inside the root element will be a <code>&lt;user&gt;</code> element for each
846
valid user, consisting of the following attributes:</p>
847
<ul>
848
<li><strong>name</strong> - Username this user must log on with.</li>
849
<li><strong>password</strong> - Password this user must log on with (in
850
    clear text if the <code>digest</code> attribute was not set on the
851
    <code>&lt;Realm&gt;</code> element, or digested appropriately as
852
    described <a href="#Digested_Passwords">here</a> otherwise).</li>
853
<li><strong>roles</strong> - Comma-delimited list of the role names
854
    associated with this user.</li>
855
</ul>
856
 
857
<h5>Additional Notes</h5>
858
 
859
<p>MemoryRealm operates according to the following rules:</p>
860
<ul>
861
<li>When Tomcat first starts up, it loads all defined users and their
862
    associated information from the users file.  Changes to the data in
863
    this file will <strong>not</strong> be recognized until Tomcat is
864
    restarted.</li>
865
<li>When a user attempts to access a protected resource for the first time,
866
    Tomcat will call the <code>authenticate()</code> method of this
867
    <code>Realm</code>.</li>
868
<li>Once a user has been authenticated, the user (and their associated
869
    roles) are cached within Tomcat for the duration of the user's login.
870
    (For FORM-based authentication, that means until the session times out or
871
    is invalidated; for BASIC authentication, that means until the user
872
    closes their browser).  The cached user is <strong>not</strong> saved and
873
    restored across sessions serialisations.</li>
874
<li>Administering the information in the users file is the responsibility
875
    of your application.  Tomcat does not
876
    provide any built-in capabilities to maintain users and roles.</li>
877
</ul>
878
 
879
 
880
</div></div>
881
 
882
 
883
<div class="subsection"><h4 id="JAASRealm">JAASRealm</h4><div class="text">
884
 
885
<h5>Introduction</h5>
886
 
887
        <p><strong>JAASRealm</strong> is an implementation of the Tomcat
888
<code>Realm</code> interface that authenticates users through the Java
889
Authentication &amp; Authorization Service (JAAS) framework which is now
890
provided as part of the standard Java SE API.</p>
891
        <p>Using JAASRealm gives the developer the ability to combine
892
practically any conceivable security realm with Tomcat's CMA. </p>
893
        <p>JAASRealm is prototype for Tomcat of the JAAS-based
894
J2EE authentication framework for J2EE v1.4, based on the <a href="https://www.jcp.org/en/jsr/detail?id=196">JCP Specification
895
Request 196</a> to enhance container-managed security and promote
896
'pluggable' authentication mechanisms whose implementations would be
897
container-independent.
898
        </p>
899
        <p>Based on the JAAS login module and principal (see <code>javax.security.auth.spi.LoginModule</code>
900
and <code>javax.security.Principal</code>), you can develop your own
901
security mechanism or wrap another third-party mechanism for
902
integration with the CMA as implemented by Tomcat.
903
        </p>
904
 
905
        <h5>Quick Start</h5>
906
        <p>To set up Tomcat to use JAASRealm with your own JAAS login module,
907
 you will need to follow these steps:</p>
908
        <ol>
909
          <li>Write your own LoginModule, User and Role classes based
910
on JAAS (see
911
<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/tutorials/GeneralAcnOnly.html">
912
the JAAS Authentication Tutorial</a> and
913
<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/JAASLMDevGuide.html">
914
the JAAS Login Module Developer's Guide</a>) to be managed by the JAAS Login
915
Context (<code>javax.security.auth.login.LoginContext</code>)
916
When developing your LoginModule, note that JAASRealm's built-in <code>CallbackHandler</code>
917
only recognizes the <code>NameCallback</code> and <code>PasswordCallback</code> at present.
918
          </li>
919
          <li>Although not specified in JAAS, you should create
920
separate classes to distinguish between users and roles, extending <code>javax.security.Principal</code>,
921
so that Tomcat can tell which Principals returned from your login
922
module are users and which are roles (see <code>org.apache.catalina.realm.JAASRealm</code>).
923
Regardless, the first Principal returned is <em>always</em> treated as the user Principal.
924
          </li>
925
          <li>Place the compiled classes on Tomcat's classpath
926
          </li>
927
          <li>Set up a login.config file for Java (see <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/tutorials/LoginConfigFile.html">
928
JAAS LoginConfig file</a>) and tell Tomcat where to find it by specifying
929
its location to the JVM, for instance by setting the environment
930
variable: <code>JAVA_OPTS=$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_BASE/conf/jaas.config</code></li>
931
 
932
          <li>Configure your security-constraints in your web.xml for
933
the resources you want to protect</li>
934
          <li>Configure the JAASRealm module in your server.xml </li>
935
          <li>Restart Tomcat if it is already running.</li>
936
        </ol>
937
        <h5>Realm Element Attributes</h5>
938
        <p>To configure JAASRealm as for step 6 above, you create
939
a <code>&lt;Realm&gt;</code> element and nest it in your
940
<code>$CATALINA_BASE/conf/server.xml</code>
941
file within your <code>&lt;Engine&gt;</code> node. The attributes for the
942
JAASRealm are defined in the <a href="config/realm.html">Realm</a>
943
configuration documentation.</p>
944
 
945
<h5>Example</h5>
946
 
947
<p>Here is an example of how your server.xml snippet should look.</p>
948
 
949
<div class="codeBox"><pre><code>&lt;Realm className="org.apache.catalina.realm.JAASRealm"
950
                appName="MyFooRealm"
951
    userClassNames="org.foobar.realm.FooUser"
952
     roleClassNames="org.foobar.realm.FooRole"/&gt;</code></pre></div>
953
 
954
<p>It is the responsibility of your login module to create and save User and
955
Role objects representing Principals for the user
956
(<code>javax.security.auth.Subject</code>). If your login module doesn't
957
create a user object but also doesn't throw a login exception, then the
958
Tomcat CMA will break and you will be left at the
959
http://localhost:8080/myapp/j_security_check URI or at some other
960
unspecified location.</p>
961
 
962
        <p>The flexibility of the JAAS approach is two-fold: </p>
963
        <ul>
964
          <li>you can carry out whatever processing you require behind
965
the scenes in your own login module.</li>
966
          <li>you can plug in a completely different LoginModule by changing the configuration
967
and restarting the server, without any code changes to your application.</li>
968
        </ul>
969
 
970
        <h5>Additional Notes</h5>
971
        <ul>
972
          <li>When a user attempts to access a protected resource for
973
              the first time, Tomcat will call the <code>authenticate()</code>
974
              method of this <code>Realm</code>.  Thus, any changes you have made in
975
              the security mechanism directly (new users, changed passwords or
976
              roles, etc.) will be immediately reflected.</li>
977
          <li>Once a user has been authenticated, the user (and their
978
              associated roles) are cached within Tomcat for the duration of
979
              the user's login.  For FORM-based authentication, that means until
980
              the session times out or is invalidated; for BASIC authentication,
981
              that means until the user closes their browser.  Any changes to the
982
              security information for an already authenticated user will <strong>not</strong>
983
              be reflected until the next time that user logs on again.</li>
984
          <li>As with other <code>Realm</code> implementations, digested passwords
985
              are supported if the <code>&lt;Realm&gt;</code> element in <code>server.xml</code>
986
              contains a <code>digest</code> attribute; JAASRealm's <code>CallbackHandler</code>
987
              will digest the password prior to passing it back to the <code>LoginModule</code></li>
988
        </ul>
989
 
990
</div></div>
991
 
992
 
993
<div class="subsection"><h4 id="CombinedRealm">CombinedRealm</h4><div class="text">
994
 
995
    <h5>Introduction</h5>
996
 
997
    <p><strong>CombinedRealm</strong> is an implementation of the Tomcat
998
    <code>Realm</code> interface that authenticates users through one or more
999
    sub-Realms.</p>
1000
 
1001
    <p>Using CombinedRealm gives the developer the ability to combine multiple
1002
    Realms of the same or different types. This can be used to authenticate
1003
    against different sources, provide fall back in case one Realm fails or for
1004
    any other purpose that requires multiple Realms.</p>
1005
 
1006
    <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
1007
    <code>Realm</code> element that defines the CombinedRealm. Authentication
1008
    will be attempted against each <code>Realm</code> in the order they are
1009
    listed. Authentication against any Realm will be sufficient to authenticate
1010
    the user.</p>
1011
 
1012
    <h5>Realm Element Attributes</h5>
1013
    <p>To configure a CombinedRealm, you create a <code>&lt;Realm&gt;</code>
1014
    element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code>
1015
    file within your <code>&lt;Engine&gt;</code> or <code>&lt;Host&gt;</code>.
1016
    You can also nest inside a <code>&lt;Context&gt;</code> node in a
1017
    <code>context.xml</code> file.</p>
1018
 
1019
<h5>Example</h5>
1020
 
1021
<p>Here is an example of how your server.xml snippet should look to use a
1022
UserDatabase Realm and a DataSource Realm.</p>
1023
 
1024
<div class="codeBox"><pre><code>&lt;Realm className="org.apache.catalina.realm.CombinedRealm" &gt;
1025
   &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm"
1026
             resourceName="UserDatabase"/&gt;
1027
   &lt;Realm className="org.apache.catalina.realm.DataSourceRealm"
1028
             dataSourceName="jdbc/authority"
1029
             userTable="users" userNameCol="user_name" userCredCol="user_pass"
1030
             userRoleTable="user_roles" roleNameCol="role_name"/&gt;
1031
&lt;/Realm&gt;</code></pre></div>
1032
 
1033
</div></div>
1034
 
1035
<div class="subsection"><h4 id="LockOutRealm">LockOutRealm</h4><div class="text">
1036
 
1037
    <h5>Introduction</h5>
1038
 
1039
    <p><strong>LockOutRealm</strong> is an implementation of the Tomcat
1040
    <code>Realm</code> interface that extends the CombinedRealm to provide lock
1041
    out functionality to provide a user lock out mechanism if there are too many
1042
    failed authentication attempts in a given period of time.</p>
1043
 
1044
    <p>To ensure correct operation, there is a reasonable degree of
1045
    synchronisation in this Realm.</p>
1046
 
1047
    <p>This Realm does not require modification to the underlying Realms or the
1048
    associated user storage mechanisms. It achieves this by recording all failed
1049
    logins, including those for users that do not exist. To prevent a DOS by
1050
    deliberating making requests with invalid users (and hence causing this
1051
    cache to grow) the size of the list of users that have failed authentication
1052
    is limited.</p>
1053
 
1054
    <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
1055
    <code>Realm</code> element that defines the LockOutRealm. Authentication
1056
    will be attempted against each <code>Realm</code> in the order they are
1057
    listed. Authentication against any Realm will be sufficient to authenticate
1058
    the user.</p>
1059
 
1060
    <h5>Realm Element Attributes</h5>
1061
    <p>To configure a LockOutRealm, you create a <code>&lt;Realm&gt;</code>
1062
    element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code>
1063
    file within your <code>&lt;Engine&gt;</code> or <code>&lt;Host&gt;</code>.
1064
    You can also nest inside a <code>&lt;Context&gt;</code> node in a
1065
    <code>context.xml</code> file. The attributes for the
1066
    LockOutRealm are defined in the <a href="config/realm.html">Realm</a>
1067
    configuration documentation.</p>
1068
 
1069
<h5>Example</h5>
1070
 
1071
<p>Here is an example of how your server.xml snippet should look to add lock out
1072
functionality to a UserDatabase Realm.</p>
1073
 
1074
<div class="codeBox"><pre><code>&lt;Realm className="org.apache.catalina.realm.LockOutRealm" &gt;
1075
   &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm"
1076
             resourceName="UserDatabase"/&gt;
1077
&lt;/Realm&gt;</code></pre></div>
1078
 
1079
</div></div>
1080
 
1081
<div class="subsection"><h4 id="JDBCRealm">JDBCRealm</h4><div class="text">
1082
 
1083
<h5>Introduction</h5>
1084
 
1085
<p><strong>The JDBC Database Realm has been deprecated and will be removed
1086
in Tomcat 10 onwards. Use the DataSourceRealm instead.</strong></p>
1087
 
1088
<p><strong>JDBCRealm</strong> is an implementation of the Tomcat
1089
<code>Realm</code> interface that looks up users in a relational database
1090
accessed via a JDBC driver.  There is substantial configuration flexibility
1091
that lets you adapt to existing table and column names, as long as your
1092
database structure conforms to the following requirements:</p>
1093
<ul>
1094
<li>There must be a table, referenced below as the <em>users</em> table,
1095
    that contains one row for every valid user that this <code>Realm</code>
1096
    should recognize.</li>
1097
<li>The <em>users</em> table must contain at least two columns (it may
1098
    contain more if your existing applications required it):
1099
    <ul>
1100
    <li>Username to be recognized by Tomcat when the user logs in.</li>
1101
    <li>Password to be recognized by Tomcat when the user logs in.
1102
        This value may in cleartext or digested - see below for more
1103
        information.</li>
1104
    </ul></li>
1105
<li>There must be a table, referenced below as the <em>user roles</em> table,
1106
    that contains one row for every valid role that is assigned to a
1107
    particular user.  It is legal for a user to have zero, one, or more than
1108
    one valid role.</li>
1109
<li>The <em>user roles</em> table must contain at least two columns (it may
1110
    contain more if your existing applications required it):
1111
    <ul>
1112
    <li>Username to be recognized by Tomcat (same value as is specified
1113
        in the <em>users</em> table).</li>
1114
    <li>Role name of a valid role associated with this user.</li>
1115
    </ul></li>
1116
</ul>
1117
 
1118
<h5>Quick Start</h5>
1119
 
1120
<p>To set up Tomcat to use JDBCRealm, you will need to follow these steps:</p>
1121
<ol>
1122
<li>If you have not yet done so, create tables and columns in your database
1123
    that conform to the requirements described above.</li>
1124
<li>Configure a database username and password for use by Tomcat, that has
1125
    at least read only access to the tables described above.  (Tomcat will
1126
    never attempt to write to these tables.)</li>
1127
<li>Place a copy of the JDBC driver you will be using inside the
1128
    <code>$CATALINA_HOME/lib</code> directory.
1129
    Note that <strong>only</strong> JAR files are recognized!</li>
1130
<li>Set up a <code>&lt;Realm&gt;</code> element, as described below, in your
1131
    <code>$CATALINA_BASE/conf/server.xml</code> file.</li>
1132
<li>Restart Tomcat if it is already running.</li>
1133
</ol>
1134
 
1135
<h5>Realm Element Attributes</h5>
1136
 
1137
<p>To configure JDBCRealm, you will create a <code>&lt;Realm&gt;</code>
1138
element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
1139
as described <a href="#Configuring_a_Realm">above</a>. The attributes for the
1140
JDBCRealm are defined in the <a href="config/realm.html">Realm</a> configuration
1141
documentation.</p>
1142
 
1143
<h5>Example</h5>
1144
 
1145
<p>An example SQL script to create the needed tables might look something
1146
like this (adapt the syntax as required for your particular database):</p>
1147
<div class="codeBox"><pre><code>create table users (
1148
  user_name         varchar(15) not null primary key,
1149
  user_pass         varchar(15) not null
1150
);
1151
 
1152
create table user_roles (
1153
  user_name         varchar(15) not null,
1154
  role_name         varchar(15) not null,
1155
  primary key (user_name, role_name)
1156
);</code></pre></div>
1157
 
1158
<p>Example <code>Realm</code> elements are included (commented out) in the
1159
default <code>$CATALINA_BASE/conf/server.xml</code> file.  Here's an example
1160
for using a MySQL database called "authority", configured with the tables
1161
described above, and accessed with username "dbuser" and password "dbpass":</p>
1162
<div class="codeBox"><pre><code>&lt;Realm className="org.apache.catalina.realm.JDBCRealm"
1163
      driverName="org.gjt.mm.mysql.Driver"
1164
   connectionURL="jdbc:mysql://localhost/authority?user=dbuser&amp;amp;password=dbpass"
1165
       userTable="users" userNameCol="user_name" userCredCol="user_pass"
1166
   userRoleTable="user_roles" roleNameCol="role_name"/&gt;</code></pre></div>
1167
 
1168
<h5>Additional Notes</h5>
1169
 
1170
<p>JDBCRealm operates according to the following rules:</p>
1171
<ul>
1172
<li>When a user attempts to access a protected resource for the first time,
1173
    Tomcat will call the <code>authenticate()</code> method of this
1174
    <code>Realm</code>.  Thus, any changes you have made to the database
1175
    directly (new users, changed passwords or roles, etc.) will be immediately
1176
    reflected.</li>
1177
<li>Once a user has been authenticated, the user (and his or her associated
1178
    roles) are cached within Tomcat for the duration of the user's login.
1179
    (For FORM-based authentication, that means until the session times out or
1180
    is invalidated; for BASIC authentication, that means until the user
1181
    closes their browser).  The cached user is <strong>not</strong> saved and
1182
    restored across sessions serialisations. Any changes to the database
1183
    information for an already authenticated user will <strong>not</strong> be
1184
    reflected until the next time that user logs on again.</li>
1185
<li>Administering the information in the <em>users</em> and <em>user roles</em>
1186
    table is the responsibility of your own applications.  Tomcat does not
1187
    provide any built-in capabilities to maintain users and roles.</li>
1188
</ul>
1189
 
1190
</div></div>
1191
 
1192
</div></div></div></div></div><footer><div id="footer">
1193
    Copyright &copy; 1999-2025, The Apache Software Foundation
1194
    <br>
1195
    Apache Tomcat, Tomcat, Apache, the Apache Tomcat logo and the Apache logo
1196
    are either registered trademarks or trademarks of the Apache Software
1197
    Foundation.
1198
    </div></footer></div></body></html>