blob: d80508fa8e699abe8118864f29d916892331e1d6 [file] [log] [blame]
刘洪青6266f992017-05-15 21:21:03 +08001<html><head><META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>Apache Tomcat 7 (7.0.77) - Realm Configuration HOW-TO</title><meta name="author" content="Craig R. McClanahan"><meta name="author" content="Yoav Shapira"><meta name="author" content="Andrew R. Jaquith"><style type="text/css" media="print">
2 .noPrint {display: none;}
3 td#mainBody {width: 100%;}
4</style><style type="text/css">
5code {background-color:rgb(224,255,255);padding:0 0.1em;}
6code.attributeName, code.propertyName {background-color:transparent;}
7
8
9table {
10 border-collapse: collapse;
11 text-align: left;
12}
13table *:not(table) {
14 /* Prevent border-collapsing for table child elements like <div> */
15 border-collapse: separate;
16}
17
18th {
19 text-align: left;
20}
21
22
23div.codeBox pre code, code.attributeName, code.propertyName, code.noHighlight, .noHighlight code {
24 background-color: transparent;
25}
26div.codeBox {
27 overflow: auto;
28 margin: 1em 0;
29}
30div.codeBox pre {
31 margin: 0;
32 padding: 4px;
33 border: 1px solid #999;
34 border-radius: 5px;
35 background-color: #eff8ff;
36 display: table; /* To prevent <pre>s from taking the complete available width. */
37 /*
38 When it is officially supported, use the following CSS instead of display: table
39 to prevent big <pre>s from exceeding the browser window:
40 max-width: available;
41 width: min-content;
42 */
43}
44
45div.codeBox pre.wrap {
46 white-space: pre-wrap;
47}
48
49
50table.defaultTable tr, table.detail-table tr {
51 border: 1px solid #CCC;
52}
53
54table.defaultTable tr:nth-child(even), table.detail-table tr:nth-child(even) {
55 background-color: #FAFBFF;
56}
57
58table.defaultTable tr:nth-child(odd), table.detail-table tr:nth-child(odd) {
59 background-color: #EEEFFF;
60}
61
62table.defaultTable th, table.detail-table th {
63 background-color: #88b;
64 color: #fff;
65}
66
67table.defaultTable th, table.defaultTable td, table.detail-table th, table.detail-table td {
68 padding: 5px 8px;
69}
70
71
72p.notice {
73 border: 1px solid rgb(255, 0, 0);
74 background-color: rgb(238, 238, 238);
75 color: rgb(0, 51, 102);
76 padding: 0.5em;
77 margin: 1em 2em 1em 1em;
78}
79</style></head><body bgcolor="#ffffff" text="#000000" link="#525D76" alink="#525D76" vlink="#525D76"><table border="0" width="100%" cellspacing="0"><!--PAGE HEADER--><tr><td><!--PROJECT LOGO--><a href="http://tomcat.apache.org/"><img src="./images/tomcat.gif" align="right" alt="
Hongqing Liufd5ee812014-05-10 16:32:51 +080080 The Apache Tomcat Servlet/JSP Container
刘洪青6266f992017-05-15 21:21:03 +080081 " border="0"></a></td><td><h1><font face="arial,helvetica,sanserif">Apache Tomcat 7</font></h1><font face="arial,helvetica,sanserif">Version 7.0.77, Mar 28 2017</font></td><td><!--APACHE LOGO--><a href="http://www.apache.org/"><img src="./images/asf-logo.svg" align="right" alt="Apache Logo" border="0" style="width: 266px;height: 83px;"></a></td></tr></table><table border="0" width="100%" cellspacing="4"><!--HEADER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><tr><!--LEFT SIDE NAVIGATION--><td width="20%" valign="top" nowrap class="noPrint"><p><strong>Links</strong></p><ul><li><a href="index.html">Docs Home</a></li><li><a href="http://wiki.apache.org/tomcat/FAQ">FAQ</a></li><li><a href="#comments_section">User Comments</a></li></ul><p><strong>User Guide</strong></p><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="realm-howto.html">6) Realms and AAA</a></li><li><a href="security-manager-howto.html">7) Security Manager</a></li><li><a href="jndi-resources-howto.html">8) JNDI Resources</a></li><li><a href="jndi-datasource-examples-howto.html">9) JDBC DataSources</a></li><li><a href="class-loader-howto.html">10) Classloading</a></li><li><a href="jasper-howto.html">11) JSPs</a></li><li><a href="ssl-howto.html">12) SSL/TLS</a></li><li><a href="ssi-howto.html">13) SSI</a></li><li><a href="cgi-howto.html">14) CGI</a></li><li><a href="proxy-howto.html">15) Proxy Support</a></li><li><a href="mbeans-descriptors-howto.html">16) MBeans Descriptors</a></li><li><a href="default-servlet.html">17) Default Servlet</a></li><li><a href="cluster-howto.html">18) Clustering</a></li><li><a href="balancer-howto.html">19) Load Balancer</a></li><li><a href="connectors.html">20) Connectors</a></li><li><a href="monitoring.html">21) Monitoring and Management</a></li><li><a href="logging.html">22) Logging</a></li><li><a href="apr.html">23) APR/Native</a></li><li><a href="virtual-hosting-howto.html">24) Virtual Hosting</a></li><li><a href="aio.html">25) Advanced IO</a></li><li><a href="extras.html">26) Additional Components</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></ul><p><strong>Reference</strong></p><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 Javadocs</a></li><li><a href="jspapi/index.html">JSP 2.2 Javadocs</a></li><li><a href="elapi/index.html">EL 2.2 Javadocs</a></li><li><a href="websocketapi/index.html">WebSocket 1.1 Javadocs</a></li><li><a href="http://tomcat.apache.org/connectors-doc/">JK 1.2 Documentation</a></li></ul><p><strong>Apache Tomcat Development</strong></p><ul><li><a href="building.html">Building</a></li><li><a href="changelog.html">Changelog</a></li><li><a href="http://wiki.apache.org/tomcat/TomcatVersions">Status</a></li><li><a href="developers.html">Developers</a></li><li><a href="architecture/index.html">Architecture</a></li><li><a href="funcspecs/index.html">Functional Specs.</a></li><li><a href="tribes/introduction.html">Tribes</a></li></ul></td><!--RIGHT SIDE MAIN BODY--><td width="80%" valign="top" align="left" id="mainBody"><h1>Realm Configuration HOW-TO</h1><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Table of Contents"><!--()--></a><a name="Table_of_Contents"><strong>Table of Contents</strong></a></font></td></tr><tr><td><blockquote>
Hongqing Liufd5ee812014-05-10 16:32:51 +080082<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="#JDBCRealm">JDBCRealm</a></li><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></ol></li></ul>
83</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Quick Start"><!--()--></a><a name="Quick_Start"><strong>Quick Start</strong></a></font></td></tr><tr><td><blockquote>
84
85<p>This document describes how to configure Tomcat to support <em>container
86managed security</em>, by connecting to an existing "database" of usernames,
87passwords, and user roles. You only need to care about this if you are using
88a web application that includes one or more
89<code>&lt;security-constraint&gt;</code> elements, and a
90<code>&lt;login-config&gt;</code> element defining how users are required
91to authenticate themselves. If you are not utilizing these features, you can
92safely skip this document.</p>
93
94<p>For fundamental background information about container managed security,
95see the <a href="http://wiki.apache.org/tomcat/Specifications">Servlet
96Specification (Version 2.4)</a>, Section 12.</p>
97
98<p>For information about utilizing the <em>Single Sign On</em> feature of
刘洪青6266f992017-05-15 21:21:03 +080099Tomcat (allowing a user to authenticate themselves once across the entire
Hongqing Liufd5ee812014-05-10 16:32:51 +0800100set of web applications associated with a virtual host), see
101<a href="config/host.html#Single Sign On">here</a>.</p>
102
103</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Overview"><strong>Overview</strong></a></font></td></tr><tr><td><blockquote>
104
105
106<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="What is a Realm?"><!--()--></a><a name="What_is_a_Realm?"><strong>What is a Realm?</strong></a></font></td></tr><tr><td><blockquote>
107
108<p>A <strong>Realm</strong> is a "database" of usernames and passwords that
109identify valid users of a web application (or set of web applications), plus
110an enumeration of the list of <em>roles</em> associated with each valid user.
111You can think of roles as similar to <em>groups</em> in Unix-like operating
112systems, because access to specific web application resources is granted to
113all users possessing a particular role (rather than enumerating the list of
114associated usernames). A particular user can have any number of roles
115associated with their username.</p>
116
117<p>Although the Servlet Specification describes a portable mechanism for
118applications to <em>declare</em> their security requirements (in the
119<code>web.xml</code> deployment descriptor), there is no portable API
120defining the interface between a servlet container and the associated user
121and role information. In many cases, however, it is desirable to "connect"
122a servlet container to some existing authentication database or mechanism
刘洪青6266f992017-05-15 21:21:03 +0800123that already exists in the production environment. Therefore, Tomcat
Hongqing Liufd5ee812014-05-10 16:32:51 +0800124defines a Java interface (<code>org.apache.catalina.Realm</code>) that
125can be implemented by "plug in" components to establish this connection.
刘洪青6266f992017-05-15 21:21:03 +0800126Six standard plug-ins are provided, supporting connections to various
Hongqing Liufd5ee812014-05-10 16:32:51 +0800127sources of authentication information:</p>
128<ul>
129<li><a href="#JDBCRealm">JDBCRealm</a> - Accesses authentication information
130 stored in a relational database, accessed via a JDBC driver.</li>
131<li><a href="#DataSourceRealm">DataSourceRealm</a> - Accesses authentication
132 information stored in a relational database, accessed via a named JNDI
133 JDBC DataSource.</li>
134<li><a href="#JNDIRealm">JNDIRealm</a> - Accesses authentication information
135 stored in an LDAP based directory server, accessed via a JNDI provider.
136 </li>
137<li><a href="#UserDatabaseRealm">UserDatabaseRealm</a> - Accesses authentication
138 information stored in an UserDatabase JNDI resource, which is typically
139 backed by an XML document (<code>conf/tomcat-users.xml</code>).</li>
140<li><a href="#MemoryRealm">MemoryRealm</a> - Accesses authentication
141 information stored in an in-memory object collection, which is initialized
142 from an XML document (<code>conf/tomcat-users.xml</code>).</li>
143<li><a href="#JAASRealm">JAASRealm</a> - Accesses authentication information
144 through the Java Authentication &amp; Authorization Service (JAAS)
145 framework.</li>
146</ul>
147
148<p>It is also possible to write your own <code>Realm</code> implementation,
刘洪青6266f992017-05-15 21:21:03 +0800149and integrate it with Tomcat. To do so, you need to:
Hongqing Liufd5ee812014-05-10 16:32:51 +0800150<ul>
151 <li>Implement <code>org.apache.catalina.Realm</code>,</li>
152 <li>Place your compiled realm in $CATALINA_HOME/lib,</li>
153 <li>Declare your realm as described in the "Configuring a Realm" section below,</li>
刘洪青6266f992017-05-15 21:21:03 +0800154 <li>Declare your realm to the <a href="mbeans-descriptors-howto.html">MBeans Descriptors</a>.</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800155</ul>
156</p>
157
158</blockquote></td></tr></table>
159
160
161<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Configuring a Realm"><!--()--></a><a name="Configuring_a_Realm"><strong>Configuring a Realm</strong></a></font></td></tr><tr><td><blockquote>
162
163<p>Before getting into the details of the standard Realm implementations, it is
164important to understand, in general terms, how a Realm is configured. In
165general, you will be adding an XML element to your <code>conf/server.xml</code>
166configuration file, that looks something like this:</p>
167
刘洪青6266f992017-05-15 21:21:03 +0800168<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800169&lt;Realm className="... class name for this implementation"
170 ... other attributes for this implementation .../&gt;
刘洪青6266f992017-05-15 21:21:03 +0800171</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800172
刘洪青6266f992017-05-15 21:21:03 +0800173<p>The <code>&lt;Realm&gt;</code> element can be nested inside any one of
Hongqing Liufd5ee812014-05-10 16:32:51 +0800174of the following <code>Container</code> elements. The location of the
175Realm element has a direct impact on the "scope" of that Realm
176(i.e. which web applications will share the same authentication information):
177</p>
178<ul>
179<li><em>Inside an &lt;Engine&gt; element</em> - This Realm will be shared
180 across ALL web applications on ALL virtual hosts, UNLESS it is overridden
181 by a Realm element nested inside a subordinate <code>&lt;Host&gt;</code>
182 or <code>&lt;Context&gt;</code> element.</li>
183<li><em>Inside a &lt;Host&gt; element</em> - This Realm will be shared across
184 ALL web applications for THIS virtual host, UNLESS it is overridden
185 by a Realm element nested inside a subordinate <code>&lt;Context&gt;</code>
186 element.</li>
187<li><em>Inside a &lt;Context&gt; element</em> - This Realm will be used ONLY
188 for THIS web application.</li>
189</ul>
190
191
192</blockquote></td></tr></table>
193
194
195</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Common Features"><!--()--></a><a name="Common_Features"><strong>Common Features</strong></a></font></td></tr><tr><td><blockquote>
196
197
198<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Digested Passwords"><!--()--></a><a name="Digested_Passwords"><strong>Digested Passwords</strong></a></font></td></tr><tr><td><blockquote>
199
200<p>For each of the standard <code>Realm</code> implementations, the
201user's password (by default) is stored in clear text. In many
202environments, this is undesirable because casual observers of the
203authentication data can collect enough information to log on
204successfully, and impersonate other users. To avoid this problem, the
205standard implementations support the concept of <em>digesting</em>
206user passwords. This allows the stored version of the passwords to be
207encoded (in a form that is not easily reversible), but that the
208<code>Realm</code> implementation can still utilize for
209authentication.</p>
210
211<p>When a standard realm authenticates by retrieving the stored
212password and comparing it with the value presented by the user, you
213can select digested passwords by specifying the <code>digest</code>
214attribute on your <code>&lt;Realm&gt;</code> element. The value for
215this attribute must be one of the digest algorithms supported by the
216<code>java.security.MessageDigest</code> class (SHA, MD2, or MD5).
217When you select this option, the contents of the password that is
218stored in the <code>Realm</code> must be the cleartext version of the
219password, as digested by the specified algorithm.</p>
220
221<p>When the <code>authenticate()</code> method of the Realm is called, the
222(cleartext) password specified by the user is itself digested by the same
223algorithm, and the result is compared with the value returned by the
224<code>Realm</code>. An equal match implies that the cleartext version of the
225original password is the same as the one presented by the user, so that this
226user should be authorized.</p>
227
228<p>To calculate the digested value of a cleartext password, two convenience
229techniques are supported:</p>
230<ul>
231<li>If you are writing an application that needs to calculate digested
232 passwords dynamically, call the static <code>Digest()</code> method of the
233 <code>org.apache.catalina.realm.RealmBase</code> class, passing the
234 cleartext password and the digest algorithm name as arguments. This
235 method will return the digested password.</li>
236<li>If you want to execute a command line utility to calculate the digested
237 password, simply execute
刘洪青6266f992017-05-15 21:21:03 +0800238<div class="codeBox"><pre><code>CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password}
239</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800240 and the digested version of this cleartext password will be returned to
241 standard output.</li>
242</ul>
243
244<p>If using digested passwords with DIGEST authentication, the cleartext used
245 to generate the digest is different and the digest must use the MD5
246 algorithm. In the examples above <code>{cleartext-password}</code> must be
247 replaced with <code>{username}:{realm}:{cleartext-password}</code>. For
248 example, in a development environment this might take the form
249 <code>testUser:Authentication required:testPassword</code>. The value for
250 <code>{realm}</code> is taken from the <code>&lt;realm-name&gt;</code>
251 element of the web application's <code>&lt;login-config&gt;</code>. If
252 not specified in web.xml, the default value of <code>Authentication
253 required</code> is used.</p>
254
Hongqing Liufd5ee812014-05-10 16:32:51 +0800255<p>Non-ASCII usernames and/or passwords are supported using
刘洪青6266f992017-05-15 21:21:03 +0800256<div class="codeBox"><pre><code>CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} -e {encoding} {input}
257</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800258but care is required to ensure that the non-ASCII input is
259correctly passed to the digester.
260The digester returns <code>{input}:{digest}</code>. If the input appears
261corrupted in the return, the digest will be invalid.</p>
262
263</blockquote></td></tr></table>
264
265
266
267<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Example Application"><!--()--></a><a name="Example_Application"><strong>Example Application</strong></a></font></td></tr><tr><td><blockquote>
268
刘洪青6266f992017-05-15 21:21:03 +0800269<p>The example application shipped with Tomcat includes an area that is
Hongqing Liufd5ee812014-05-10 16:32:51 +0800270protected by a security constraint, utilizing form-based login. To access it,
271point your browser at
272<a href="http://localhost:8080/examples/jsp/security/protected/">http://localhost:8080/examples/jsp/security/protected/</a>
273and log on with one of the usernames and passwords described for the default
274<a href="#UserDatabaseRealm">UserDatabaseRealm</a>.</p>
275
276</blockquote></td></tr></table>
277
278
279<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Manager Application"><!--()--></a><a name="Manager_Application"><strong>Manager Application</strong></a></font></td></tr><tr><td><blockquote>
280
281<p>If you wish to use the <a href="manager-howto.html">Manager Application</a>
282to deploy and undeploy applications in a running Tomcat installation, you
283MUST add the "manager-gui" role to at least one username in your selected
284Realm implementation. This is because the manager web application itself uses a
285security constraint that requires role "manager-gui" to access ANY request URI
286within the HTML interface of that application.</p>
287
288<p>For security reasons, no username in the default Realm (i.e. using
289<code>conf/tomcat-users.xml</code> is assigned the "manager-gui" role.
290Therefore, no one will be able to utilize the features of this application
291until the Tomcat administrator specifically assigns this role to one or more
292users.</p>
293
294</blockquote></td></tr></table>
295
296<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Realm Logging"><!--()--></a><a name="Realm_Logging"><strong>Realm Logging</strong></a></font></td></tr><tr><td><blockquote>
297
298<p>Debugging and exception messages logged by a <code>Realm</code> will
299 be recorded by the logging configuration associated with the container
300 for the realm: its surrounding <a href="config/context.html">Context</a>,
301 <a href="config/host.html">Host</a>, or
302 <a href="config/engine.html">Engine</a>.</p>
303
304</blockquote></td></tr></table>
305
306</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Standard Realm Implementations"><!--()--></a><a name="Standard_Realm_Implementations"><strong>Standard Realm Implementations</strong></a></font></td></tr><tr><td><blockquote>
307
308<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="JDBCRealm"><strong>JDBCRealm</strong></a></font></td></tr><tr><td><blockquote>
309
310<h3>Introduction</h3>
311
刘洪青6266f992017-05-15 21:21:03 +0800312<p><strong>JDBCRealm</strong> is an implementation of the Tomcat
Hongqing Liufd5ee812014-05-10 16:32:51 +0800313<code>Realm</code> interface that looks up users in a relational database
314accessed via a JDBC driver. There is substantial configuration flexibility
315that lets you adapt to existing table and column names, as long as your
316database structure conforms to the following requirements:</p>
317<ul>
318<li>There must be a table, referenced below as the <em>users</em> table,
319 that contains one row for every valid user that this <code>Realm</code>
320 should recognize.</li>
321<li>The <em>users</em> table must contain at least two columns (it may
322 contain more if your existing applications required it):
323 <ul>
324 <li>Username to be recognized by Tomcat when the user logs in.</li>
325 <li>Password to be recognized by Tomcat when the user logs in.
326 This value may in cleartext or digested - see below for more
327 information.</li>
328 </ul></li>
329<li>There must be a table, referenced below as the <em>user roles</em> table,
330 that contains one row for every valid role that is assigned to a
331 particular user. It is legal for a user to have zero, one, or more than
332 one valid role.</li>
333<li>The <em>user roles</em> table must contain at least two columns (it may
334 contain more if your existing applications required it):
335 <ul>
336 <li>Username to be recognized by Tomcat (same value as is specified
337 in the <em>users</em> table).</li>
338 <li>Role name of a valid role associated with this user.</li>
339 </ul></li>
340</ul>
341
342<h3>Quick Start</h3>
343
344<p>To set up Tomcat to use JDBCRealm, you will need to follow these steps:</p>
345<ol>
346<li>If you have not yet done so, create tables and columns in your database
347 that conform to the requirements described above.</li>
348<li>Configure a database username and password for use by Tomcat, that has
349 at least read only access to the tables described above. (Tomcat will
350 never attempt to write to these tables.)</li>
351<li>Place a copy of the JDBC driver you will be using inside the
352 <code>$CATALINA_HOME/lib</code> directory.
353 Note that <strong>only</strong> JAR files are recognized!</li>
354<li>Set up a <code>&lt;Realm&gt;</code> element, as described below, in your
355 <code>$CATALINA_BASE/conf/server.xml</code> file.</li>
刘洪青6266f992017-05-15 21:21:03 +0800356<li>Restart Tomcat if it is already running.</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800357</ol>
358
359<h3>Realm Element Attributes</h3>
360
361<p>To configure JDBCRealm, you will create a <code>&lt;Realm&gt;</code>
362element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
363as described <a href="#Configuring a Realm">above</a>. The attributes for the
364JDBCRealm are defined in the <a href="config/realm.html">Realm</a> configuration
365documentation.</p>
366
367<h3>Example</h3>
368
369<p>An example SQL script to create the needed tables might look something
370like this (adapt the syntax as required for your particular database):</p>
刘洪青6266f992017-05-15 21:21:03 +0800371<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800372create table users (
373 user_name varchar(15) not null primary key,
374 user_pass varchar(15) not null
375);
376
377create table user_roles (
378 user_name varchar(15) not null,
379 role_name varchar(15) not null,
380 primary key (user_name, role_name)
381);
刘洪青6266f992017-05-15 21:21:03 +0800382</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800383
384<p>Example <code>Realm</code> elements are included (commented out) in the
385default <code>$CATALINA_BASE/conf/server.xml</code> file. Here's an example
386for using a MySQL database called "authority", configured with the tables
387described above, and accessed with username "dbuser" and password "dbpass":</p>
刘洪青6266f992017-05-15 21:21:03 +0800388<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800389&lt;Realm className="org.apache.catalina.realm.JDBCRealm"
390 driverName="org.gjt.mm.mysql.Driver"
391 connectionURL="jdbc:mysql://localhost/authority?user=dbuser&amp;amp;password=dbpass"
392 userTable="users" userNameCol="user_name" userCredCol="user_pass"
393 userRoleTable="user_roles" roleNameCol="role_name"/&gt;
刘洪青6266f992017-05-15 21:21:03 +0800394</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800395
396<h3>Additional Notes</h3>
397
398<p>JDBCRealm operates according to the following rules:</p>
399<ul>
400<li>When a user attempts to access a protected resource for the first time,
刘洪青6266f992017-05-15 21:21:03 +0800401 Tomcat will call the <code>authenticate()</code> method of this
Hongqing Liufd5ee812014-05-10 16:32:51 +0800402 <code>Realm</code>. Thus, any changes you have made to the database
403 directly (new users, changed passwords or roles, etc.) will be immediately
404 reflected.</li>
405<li>Once a user has been authenticated, the user (and his or her associated
406 roles) are cached within Tomcat for the duration of the user's login.
407 (For FORM-based authentication, that means until the session times out or
408 is invalidated; for BASIC authentication, that means until the user
409 closes their browser). The cached user is <strong>not</strong> saved and
410 restored across sessions serialisations. Any changes to the database
411 information for an already authenticated user will <strong>not</strong> be
412 reflected until the next time that user logs on again.</li>
413<li>Administering the information in the <em>users</em> and <em>user roles</em>
414 table is the responsibility of your own applications. Tomcat does not
415 provide any built-in capabilities to maintain users and roles.</li>
416</ul>
417
418</blockquote></td></tr></table>
419
420
421<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="DataSourceRealm"><strong>DataSourceRealm</strong></a></font></td></tr><tr><td><blockquote>
422
423<h3>Introduction</h3>
424
刘洪青6266f992017-05-15 21:21:03 +0800425<p><strong>DataSourceRealm</strong> is an implementation of the Tomcat
Hongqing Liufd5ee812014-05-10 16:32:51 +0800426<code>Realm</code> interface that looks up users in a relational database
427accessed via a JNDI named JDBC DataSource. There is substantial configuration
428flexibility that lets you adapt to existing table and column names, as long
429as your database structure conforms to the following requirements:</p>
430<ul>
431<li>There must be a table, referenced below as the <em>users</em> table,
432 that contains one row for every valid user that this <code>Realm</code>
433 should recognize.</li>
434<li>The <em>users</em> table must contain at least two columns (it may
435 contain more if your existing applications required it):
436 <ul>
437 <li>Username to be recognized by Tomcat when the user logs in.</li>
438 <li>Password to be recognized by Tomcat when the user logs in.
439 This value may in cleartext or digested - see below for more
440 information.</li>
刘洪青6266f992017-05-15 21:21:03 +0800441 </ul></li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800442<li>There must be a table, referenced below as the <em>user roles</em> table,
443 that contains one row for every valid role that is assigned to a
444 particular user. It is legal for a user to have zero, one, or more than
445 one valid role.</li>
446<li>The <em>user roles</em> table must contain at least two columns (it may
447 contain more if your existing applications required it):
448 <ul>
449 <li>Username to be recognized by Tomcat (same value as is specified
450 in the <em>users</em> table).</li>
451 <li>Role name of a valid role associated with this user.</li>
452 </ul></li>
453</ul>
454
455<h3>Quick Start</h3>
刘洪青6266f992017-05-15 21:21:03 +0800456
Hongqing Liufd5ee812014-05-10 16:32:51 +0800457<p>To set up Tomcat to use DataSourceRealm, you will need to follow these steps:</p>
刘洪青6266f992017-05-15 21:21:03 +0800458<ol>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800459<li>If you have not yet done so, create tables and columns in your database
460 that conform to the requirements described above.</li>
461<li>Configure a database username and password for use by Tomcat, that has
462 at least read only access to the tables described above. (Tomcat will
463 never attempt to write to these tables.)</li>
464<li>Configure a JNDI named JDBC DataSource for your database. Refer to the
刘洪青6266f992017-05-15 21:21:03 +0800465 <a href="jndi-datasource-examples-howto.html">JNDI DataSource Example
466 HOW-TO</a> for information on how to configure a JNDI named JDBC DataSource.
467 Be sure to set the <code>Realm</code>'s <code>localDataSource</code>
468 attribute appropriately, depending on where the JNDI DataSource is
469 defined.</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800470<li>Set up a <code>&lt;Realm&gt;</code> element, as described below, in your
471 <code>$CATALINA_BASE/conf/server.xml</code> file.</li>
刘洪青6266f992017-05-15 21:21:03 +0800472<li>Restart Tomcat if it is already running.</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800473</ol>
474
475<h3>Realm Element Attributes</h3>
476
477<p>To configure DataSourceRealm, you will create a <code>&lt;Realm&gt;</code>
478element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
479as described <a href="#Configuring a Realm">above</a>. The attributes for the
480DataSourceRealm are defined in the <a href="config/realm.html">Realm</a>
481configuration documentation.</p>
482
483<h3>Example</h3>
484
485<p>An example SQL script to create the needed tables might look something
486like this (adapt the syntax as required for your particular database):</p>
刘洪青6266f992017-05-15 21:21:03 +0800487<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800488create table users (
489 user_name varchar(15) not null primary key,
490 user_pass varchar(15) not null
491);
492
493create table user_roles (
494 user_name varchar(15) not null,
495 role_name varchar(15) not null,
496 primary key (user_name, role_name)
497);
刘洪青6266f992017-05-15 21:21:03 +0800498</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800499
500<p>Here is an example for using a MySQL database called "authority", configured
501with the tables described above, and accessed with the JNDI JDBC DataSource with
502name "java:/comp/env/jdbc/authority".</p>
刘洪青6266f992017-05-15 21:21:03 +0800503<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800504&lt;Realm className="org.apache.catalina.realm.DataSourceRealm"
505 dataSourceName="jdbc/authority"
506 userTable="users" userNameCol="user_name" userCredCol="user_pass"
507 userRoleTable="user_roles" roleNameCol="role_name"/&gt;
刘洪青6266f992017-05-15 21:21:03 +0800508</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800509
510<h3>Additional Notes</h3>
511
512<p>DataSourceRealm operates according to the following rules:</p>
513<ul>
514<li>When a user attempts to access a protected resource for the first time,
刘洪青6266f992017-05-15 21:21:03 +0800515 Tomcat will call the <code>authenticate()</code> method of this
Hongqing Liufd5ee812014-05-10 16:32:51 +0800516 <code>Realm</code>. Thus, any changes you have made to the database
517 directly (new users, changed passwords or roles, etc.) will be immediately
518 reflected.</li>
519<li>Once a user has been authenticated, the user (and his or her associated
520 roles) are cached within Tomcat for the duration of the user's login.
521 (For FORM-based authentication, that means until the session times out or
522 is invalidated; for BASIC authentication, that means until the user
523 closes their browser). The cached user is <strong>not</strong> saved and
524 restored across sessions serialisations. Any changes to the database
525 information for an already authenticated user will <strong>not</strong> be
526 reflected until the next time that user logs on again.</li>
527<li>Administering the information in the <em>users</em> and <em>user roles</em>
528 table is the responsibility of your own applications. Tomcat does not
529 provide any built-in capabilities to maintain users and roles.</li>
530</ul>
531
532</blockquote></td></tr></table>
533
534
535<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="JNDIRealm"><strong>JNDIRealm</strong></a></font></td></tr><tr><td><blockquote>
536
537<h3>Introduction</h3>
538
刘洪青6266f992017-05-15 21:21:03 +0800539<p><strong>JNDIRealm</strong> is an implementation of the Tomcat
Hongqing Liufd5ee812014-05-10 16:32:51 +0800540<code>Realm</code> interface that looks up users in an LDAP directory
541server accessed by a JNDI provider (typically, the standard LDAP
542provider that is available with the JNDI API classes). The realm
543supports a variety of approaches to using a directory for
544authentication.</p>
545
546<h4>Connecting to the directory</h4>
547
548<p>The realm's connection to the directory is defined by the
549<strong>connectionURL</strong> configuration attribute. This is a URL
550whose format is defined by the JNDI provider. It is usually an LDAP
551URL that specifies the domain name of the directory server to connect
552to, and optionally the port number and distinguished name (DN) of the
553required root naming context.</p>
554
555<p>If you have more than one provider you can configure an
556<strong>alternateURL</strong>. If a socket connection can not be
557made to the provider at the <strong>connectionURL</strong> an
558attempt will be made to use the <strong>alternateURL</strong>.</p>
559
560<p>When making a connection in order to search the directory and
561retrieve user and role information, the realm authenticates itself to
562the directory with the username and password specified by the
563<strong>connectionName</strong> and
564<strong>connectionPassword</strong> properties. If these properties
565are not specified the connection is anonymous. This is sufficient in
566many cases.
567</p>
568
569
570<h4>Selecting the user's directory entry</h4>
571
572<p>Each user that can be authenticated must be represented in the
573directory by an individual entry that corresponds to an element in the
574initial <code>DirContext</code> defined by the
575<strong>connectionURL</strong> attribute. This user entry must have an
576attribute containing the username that is presented for
577authentication.</p>
578
579<p>Often the distinguished name of the user's entry contains the
580username presented for authentication but is otherwise the same for
581all users. In this case the <strong>userPattern</strong> attribute may
582be used to specify the DN, with "{0}" marking where
583the username should be substituted.</p>
584
585<p>Otherwise the realm must search the directory to find a unique entry
586containing the username. The following attributes configure this
587search:
588
589 <ul>
590 <li><strong>userBase</strong> - the entry that is the base of
591 the subtree containing users. If not specified, the search
592 base is the top-level context.</li>
593
594 <li><strong>userSubtree</strong> - the search scope. Set to
595 <code>true</code> if you wish to search the entire subtree
596 rooted at the <strong>userBase</strong> entry. The default value
597 of <code>false</code> requests a single-level search
598 including only the top level.</li>
599
600 <li><strong>userSearch</strong> - pattern specifying the LDAP
601 search filter to use after substitution of the username.</li>
602
603 </ul>
604</p>
605
606
607<h4>Authenticating the user</h4>
608
609<ul>
610<li>
611<p><b>Bind mode</b></p>
612
613<p>By default the realm authenticates a user by binding to
614the directory with the DN of the entry for that user and the password
615presented by the user. If this simple bind succeeds the user is considered to
616be authenticated.</p>
617
618<p>For security reasons a directory may store a digest of the user's
619password rather than the clear text version (see <a href="#Digested Passwords">Digested Passwords</a> for more information). In that case,
620as part of the simple bind operation the directory automatically
621computes the correct digest of the plaintext password presented by the
622user before validating it against the stored value. In bind mode,
623therefore, the realm is not involved in digest processing. The
624<strong>digest</strong> attribute is not used, and will be ignored if
625set.</p>
626</li>
627
628<li>
629<p><b>Comparison mode</b></p>
630<p>Alternatively, the realm may retrieve the stored
631password from the directory and compare it explicitly with the value
632presented by the user. This mode is configured by setting the
633<strong>userPassword</strong> attribute to the name of a directory
634attribute in the user's entry that contains the password.</p>
635
636<p>Comparison mode has some disadvantages. First, the
637<strong>connectionName</strong> and
638<strong>connectionPassword</strong> attributes must be configured to
639allow the realm to read users' passwords in the directory. For
640security reasons this is generally undesirable; indeed many directory
641implementations will not allow even the directory manager to read
642these passwords. In addition, the realm must handle password digests
643itself, including variations in the algorithms used and ways of
644representing password hashes in the directory. However, the realm may
645sometimes need access to the stored password, for example to support
646HTTP Digest Access Authentication (RFC 2069). (Note that HTTP digest
647authentication is different from the storage of password digests in
648the repository for user information as discussed above).
649</p>
650</li>
651</ul>
652
653<h4>Assigning roles to the user</h4>
654
655<p>The directory realm supports two approaches to the representation
656of roles in the directory:</p>
657
658<ul>
659<li>
660<p><b>Roles as explicit directory entries</b></p>
661
662<p>Roles may be represented by explicit directory entries. A role
663entry is usually an LDAP group entry with one attribute
664containing the name of the role and another whose values are the
665distinguished names or usernames of the users in that role. The
666following attributes configure a directory search to
667find the names of roles associated with the authenticated user:</p>
668
669<ul>
670<li><strong>roleBase</strong> - the base entry for the role search.
671 If not specified, the search base is the top-level directory
672 context.</li>
673
674<li><strong>roleSubtree</strong> - the search
675 scope. Set to <code>true</code> if you wish to search the entire
676 subtree rooted at the <code>roleBase</code> entry. The default
677 value of <code>false</code> requests a single-level search
678 including the top level only.</li>
679
680<li><strong>roleSearch</strong> - the LDAP search filter for
681 selecting role entries. It optionally includes pattern
682 replacements "{0}" for the distinguished name and/or "{1}" for the
刘洪青6266f992017-05-15 21:21:03 +0800683 username and/or "{2}" for an attribute from user's directory entry,
684 of the authenticated user. Use <strong>userRoleAttribute</strong> to
685 specify the name of the attribute that provides the value for "{2}".</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800686
687<li><strong>roleName</strong> - the attribute in a role entry
688 containing the name of that role.</li>
689
690<li><strong>roleNested</strong> - enable nested roles. Set to
刘洪青6266f992017-05-15 21:21:03 +0800691 <code>true</code> if you want to nest roles in roles. If configured, then
Hongqing Liufd5ee812014-05-10 16:32:51 +0800692 every newly found roleName and distinguished
693 Name will be recursively tried for a new role search.
694 The default value is <code>false</code>.</li>
695
696</ul>
697
698</li>
699</ul>
700
701<ul>
702<li>
703<p><b>Roles as an attribute of the user entry</b></p>
704
705<p>Role names may also be held as the values of an attribute in the
706user's directory entry. Use <strong>userRoleName</strong> to specify
707the name of this attribute.</p>
708
709</li>
710</ul>
711<p>A combination of both approaches to role representation may be used.</p>
712
713<h3>Quick Start</h3>
714
715<p>To set up Tomcat to use JNDIRealm, you will need to follow these steps:</p>
716<ol>
717<li>Make sure your directory server is configured with a schema that matches
718 the requirements listed above.</li>
719<li>If required, configure a username and password for use by Tomcat, that has
720 read only access to the information described above. (Tomcat will
721 never attempt to modify this information.)</li>
722<li>Set up a <code>&lt;Realm&gt;</code> element, as described below, in your
723 <code>$CATALINA_BASE/conf/server.xml</code> file.</li>
刘洪青6266f992017-05-15 21:21:03 +0800724<li>Restart Tomcat if it is already running.</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800725</ol>
726
727<h3>Realm Element Attributes</h3>
728
729<p>To configure JNDIRealm, you will create a <code>&lt;Realm&gt;</code>
730element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
731as described <a href="#Configuring a Realm">above</a>. The attributes for the
732JNDIRealm are defined in the <a href="config/realm.html">Realm</a> configuration
733documentation.</p>
734
735<h3>Example</h3>
736
737<p>Creation of the appropriate schema in your directory server is beyond the
738scope of this document, because it is unique to each directory server
739implementation. In the examples below, we will assume that you are using a
740distribution of the OpenLDAP directory server (version 2.0.11 or later), which
741can be downloaded from
742<a href="http://www.openldap.org">http://www.openldap.org</a>. Assume that
743your <code>slapd.conf</code> file contains the following settings
744(among others):</p>
刘洪青6266f992017-05-15 21:21:03 +0800745<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800746database ldbm
747suffix dc="mycompany",dc="com"
748rootdn "cn=Manager,dc=mycompany,dc=com"
749rootpw secret
刘洪青6266f992017-05-15 21:21:03 +0800750</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800751
752<p>We will assume for <code>connectionURL</code> that the directory
刘洪青6266f992017-05-15 21:21:03 +0800753server runs on the same machine as Tomcat. See <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html">
754http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html</a>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800755for more information about configuring and using the JNDI LDAP
756provider.</p>
757
758<p>Next, assume that this directory server has been populated with elements
759as shown below (in LDIF format):</p>
760
刘洪青6266f992017-05-15 21:21:03 +0800761<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800762
763# Define top-level entry
764dn: dc=mycompany,dc=com
765objectClass: dcObject
766dc:mycompany
767
768# Define an entry to contain people
769# searches for users are based on this entry
770dn: ou=people,dc=mycompany,dc=com
771objectClass: organizationalUnit
772ou: people
773
774# Define a user entry for Janet Jones
775dn: uid=jjones,ou=people,dc=mycompany,dc=com
776objectClass: inetOrgPerson
777uid: jjones
778sn: jones
779cn: janet jones
780mail: j.jones@mycompany.com
781userPassword: janet
782
783# Define a user entry for Fred Bloggs
784dn: uid=fbloggs,ou=people,dc=mycompany,dc=com
785objectClass: inetOrgPerson
786uid: fbloggs
787sn: bloggs
788cn: fred bloggs
789mail: f.bloggs@mycompany.com
790userPassword: fred
791
792# Define an entry to contain LDAP groups
793# searches for roles are based on this entry
794dn: ou=groups,dc=mycompany,dc=com
795objectClass: organizationalUnit
796ou: groups
797
798# Define an entry for the "tomcat" role
799dn: cn=tomcat,ou=groups,dc=mycompany,dc=com
800objectClass: groupOfUniqueNames
801cn: tomcat
802uniqueMember: uid=jjones,ou=people,dc=mycompany,dc=com
803uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com
804
805# Define an entry for the "role1" role
806dn: cn=role1,ou=groups,dc=mycompany,dc=com
807objectClass: groupOfUniqueNames
808cn: role1
809uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com
刘洪青6266f992017-05-15 21:21:03 +0800810</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800811
812<p>An example <code>Realm</code> element for the OpenLDAP directory
813server configured as described above might look like this, assuming
814that users use their uid (e.g. jjones) to login to the
815application and that an anonymous connection is sufficient to search
816the directory and retrieve role information:</p>
817
刘洪青6266f992017-05-15 21:21:03 +0800818<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800819&lt;Realm className="org.apache.catalina.realm.JNDIRealm"
820 connectionURL="ldap://localhost:389"
821 userPattern="uid={0},ou=people,dc=mycompany,dc=com"
822 roleBase="ou=groups,dc=mycompany,dc=com"
823 roleName="cn"
824 roleSearch="(uniqueMember={0})"
825/&gt;
刘洪青6266f992017-05-15 21:21:03 +0800826</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800827
828<p>With this configuration, the realm will determine the user's
829distinguished name by substituting the username into the
830<code>userPattern</code>, authenticate by binding to the directory
831with this DN and the password received from the user, and search the
832directory to find the user's roles.</p>
833
834<p>Now suppose that users are expected to enter their email address
835rather than their userid when logging in. In this case the realm must
836search the directory for the user's entry. (A search is also necessary
837when user entries are held in multiple subtrees corresponding perhaps
838to different organizational units or company locations).</p>
839
840<p>Further, suppose that in addition to the group entries you want to
841use an attribute of the user's entry to hold roles. Now the entry for
842Janet Jones might read as follows:</p>
843
刘洪青6266f992017-05-15 21:21:03 +0800844<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800845dn: uid=jjones,ou=people,dc=mycompany,dc=com
846objectClass: inetOrgPerson
847uid: jjones
848sn: jones
849cn: janet jones
850mail: j.jones@mycompany.com
851memberOf: role2
852memberOf: role3
853userPassword: janet
刘洪青6266f992017-05-15 21:21:03 +0800854</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800855
856<p> This realm configuration would satisfy the new requirements:</p>
857
刘洪青6266f992017-05-15 21:21:03 +0800858<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800859&lt;Realm className="org.apache.catalina.realm.JNDIRealm"
860 connectionURL="ldap://localhost:389"
861 userBase="ou=people,dc=mycompany,dc=com"
862 userSearch="(mail={0})"
863 userRoleName="memberOf"
864 roleBase="ou=groups,dc=mycompany,dc=com"
865 roleName="cn"
866 roleSearch="(uniqueMember={0})"
867/&gt;
刘洪青6266f992017-05-15 21:21:03 +0800868</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800869
870<p>Now when Janet Jones logs in as "j.jones@mycompany.com", the realm
871searches the directory for a unique entry with that value as its mail
872attribute and attempts to bind to the directory as
873<code>uid=jjones,ou=people,dc=mycompany,dc=com</code> with the given
874password. If authentication succeeds, she is assigned three roles:
875"role2" and "role3", the values of the "memberOf" attribute in her
876directory entry, and "tomcat", the value of the "cn" attribute in the
877only group entry of which she is a member.</p>
878
879<p>Finally, to authenticate the user by retrieving
880the password from the directory and making a local comparison in the
881realm, you might use a realm configuration like this:</p>
882
刘洪青6266f992017-05-15 21:21:03 +0800883<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800884&lt;Realm className="org.apache.catalina.realm.JNDIRealm"
885 connectionName="cn=Manager,dc=mycompany,dc=com"
886connectionPassword="secret"
887 connectionURL="ldap://localhost:389"
888 userPassword="userPassword"
889 userPattern="uid={0},ou=people,dc=mycompany,dc=com"
890 roleBase="ou=groups,dc=mycompany,dc=com"
891 roleName="cn"
892 roleSearch="(uniqueMember={0})"
893/&gt;
刘洪青6266f992017-05-15 21:21:03 +0800894</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800895
896<p>However, as discussed above, the default bind mode for
897authentication is usually to be preferred.</p>
898
899<h3>Additional Notes</h3>
900
901<p>JNDIRealm operates according to the following rules:</p>
902<ul>
903<li>When a user attempts to access a protected resource for the first time,
刘洪青6266f992017-05-15 21:21:03 +0800904 Tomcat will call the <code>authenticate()</code> method of this
Hongqing Liufd5ee812014-05-10 16:32:51 +0800905 <code>Realm</code>. Thus, any changes you have made to the directory
906 (new users, changed passwords or roles, etc.) will be immediately
907 reflected.</li>
908<li>Once a user has been authenticated, the user (and his or her associated
909 roles) are cached within Tomcat for the duration of the user's login.
910 (For FORM-based authentication, that means until the session times out or
911 is invalidated; for BASIC authentication, that means until the user
912 closes their browser). The cached user is <strong>not</strong> saved and
913 restored across sessions serialisations. Any changes to the directory
914 information for an already authenticated user will <strong>not</strong> be
915 reflected until the next time that user logs on again.</li>
916<li>Administering the information in the directory server
917 is the responsibility of your own applications. Tomcat does not
918 provide any built-in capabilities to maintain users and roles.</li>
919</ul>
920
921</blockquote></td></tr></table>
922
923
924<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="UserDatabaseRealm"><strong>UserDatabaseRealm</strong></a></font></td></tr><tr><td><blockquote>
925
926<h3>Introduction</h3>
927
刘洪青6266f992017-05-15 21:21:03 +0800928<p><strong>UserDatabaseRealm</strong> is an implementation of the Tomcat
Hongqing Liufd5ee812014-05-10 16:32:51 +0800929<code>Realm</code> interface that uses a JNDI resource to store user
930information. By default, the JNDI resource is backed by an XML file. It is not
931designed for large-scale production use. At startup time, the UserDatabaseRealm
932loads information about all users, and their corresponding roles, from an XML
933document (by default, this document is loaded from
934<code>$CATALINA_BASE/conf/tomcat-users.xml</code>). The users, their passwords
935and their roles may all be editing dynamically, typically via JMX. Changes may
936be saved and will be reflected in the XML file.</p>
937
938<h3>Realm Element Attributes</h3>
939
940<p>To configure UserDatabaseRealm, you will create a <code>&lt;Realm&gt;</code>
941element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
942as described <a href="#Configuring a Realm">above</a>. The attributes for the
943UserDatabaseRealm are defined in the <a href="config/realm.html">Realm</a>
944configuration documentation.</p>
945
946<h3>User File Format</h3>
947
948<p>The users file uses the same format as the
949<a href="#MemoryRealm">MemoryRealm</a>.</p>
950
951<h3>Example</h3>
952
刘洪青6266f992017-05-15 21:21:03 +0800953<p>The default installation of Tomcat is configured with a UserDatabaseRealm
Hongqing Liufd5ee812014-05-10 16:32:51 +0800954nested inside the <code>&lt;Engine&gt;</code> element, so that it applies
955to all virtual hosts and web applications. The default contents of the
956<code>conf/tomcat-users.xml</code> file is:</p>
刘洪青6266f992017-05-15 21:21:03 +0800957<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800958&lt;tomcat-users&gt;
959 &lt;user name="tomcat" password="tomcat" roles="tomcat" /&gt;
960 &lt;user name="role1" password="tomcat" roles="role1" /&gt;
961 &lt;user name="both" password="tomcat" roles="tomcat,role1" /&gt;
962&lt;/tomcat-users&gt;
刘洪青6266f992017-05-15 21:21:03 +0800963</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800964
965<h3>Additional Notes</h3>
966
967<p>UserDatabaseRealm operates according to the following rules:</p>
968<ul>
969<li>When Tomcat first starts up, it loads all defined users and their
970 associated information from the users file. Changes made to the data in
971 this file will <strong>not</strong> be recognized until Tomcat is
972 restarted. Changes may be made via the UserDatabase resource. Tomcat
973 provides MBeans that may be accessed via JMX for this purpose.</li>
974<li>When a user attempts to access a protected resource for the first time,
刘洪青6266f992017-05-15 21:21:03 +0800975 Tomcat will call the <code>authenticate()</code> method of this
Hongqing Liufd5ee812014-05-10 16:32:51 +0800976 <code>Realm</code>.</li>
977<li>Once a user has been authenticated, the user (and his or her associated
978 roles) are cached within Tomcat for the duration of the user's login.
979 (For FORM-based authentication, that means until the session times out or
980 is invalidated; for BASIC authentication, that means until the user
981 closes their browser). The cached user is <strong>not</strong> saved and
982 restored across sessions serialisations.</li>
983</ul>
984
985
986</blockquote></td></tr></table>
987
988
989<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="MemoryRealm"><strong>MemoryRealm</strong></a></font></td></tr><tr><td><blockquote>
990
991<h3>Introduction</h3>
992
993<p><strong>MemoryRealm</strong> is a simple demonstration implementation of the
刘洪青6266f992017-05-15 21:21:03 +0800994Tomcat <code>Realm</code> interface. It is not designed for production use.
Hongqing Liufd5ee812014-05-10 16:32:51 +0800995At startup time, MemoryRealm loads information about all users, and their
996corresponding roles, from an XML document (by default, this document is loaded
997from <code>$CATALINA_BASE/conf/tomcat-users.xml</code>). Changes to the data
998in this file are not recognized until Tomcat is restarted.</p>
999
1000<h3>Realm Element Attributes</h3>
1001
1002<p>To configure MemoryRealm, you will create a <code>&lt;Realm&gt;</code>
1003element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code> file,
1004as described <a href="#Configuring a Realm">above</a>. The attributes for the
1005MemoryRealm are defined in the <a href="config/realm.html">Realm</a>
1006configuration documentation.</p>
1007
1008<h3>User File Format</h3>
1009
1010<p>The users file (by default, <code>conf/tomcat-users.xml</code> must be an
1011XML document, with a root element <code>&lt;tomcat-users&gt;</code>. Nested
1012inside the root element will be a <code>&lt;user&gt;</code> element for each
1013valid user, consisting of the following attributes:</p>
1014<ul>
1015<li><strong>name</strong> - Username this user must log on with.</li>
1016<li><strong>password</strong> - Password this user must log on with (in
1017 clear text if the <code>digest</code> attribute was not set on the
1018 <code>&lt;Realm&gt;</code> element, or digested appropriately as
1019 described <a href="#Digested Passwords">here</a> otherwise).</li>
1020<li><strong>roles</strong> - Comma-delimited list of the role names
1021 associated with this user.</li>
1022</ul>
1023
1024<h3>Additional Notes</h3>
1025
1026<p>MemoryRealm operates according to the following rules:</p>
1027<ul>
1028<li>When Tomcat first starts up, it loads all defined users and their
1029 associated information from the users file. Changes to the data in
1030 this file will <strong>not</strong> be recognized until Tomcat is
1031 restarted.</li>
1032<li>When a user attempts to access a protected resource for the first time,
刘洪青6266f992017-05-15 21:21:03 +08001033 Tomcat will call the <code>authenticate()</code> method of this
Hongqing Liufd5ee812014-05-10 16:32:51 +08001034 <code>Realm</code>.</li>
1035<li>Once a user has been authenticated, the user (and his or her associated
1036 roles) are cached within Tomcat for the duration of the user's login.
1037 (For FORM-based authentication, that means until the session times out or
1038 is invalidated; for BASIC authentication, that means until the user
1039 closes their browser). The cached user is <strong>not</strong> saved and
1040 restored across sessions serialisations.</li>
1041<li>Administering the information in the users file is the responsibility
1042 of your application. Tomcat does not
1043 provide any built-in capabilities to maintain users and roles.</li>
1044</ul>
1045
1046
1047</blockquote></td></tr></table>
1048
1049
1050<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="JAASRealm"><strong>JAASRealm</strong></a></font></td></tr><tr><td><blockquote>
1051
1052<h3>Introduction</h3>
1053
1054 <p><strong>JAASRealm</strong> is an implementation of the Tomcat
刘洪青6266f992017-05-15 21:21:03 +08001055<code>Realm</code> interface that authenticates users through the Java
Hongqing Liufd5ee812014-05-10 16:32:51 +08001056Authentication &amp; Authorization Service (JAAS) framework which is now
刘洪青6266f992017-05-15 21:21:03 +08001057provided as part of the standard Java SE API.</p>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001058 <p>Using JAASRealm gives the developer the ability to combine
1059practically any conceivable security realm with Tomcat's CMA. </p>
1060 <p>JAASRealm is prototype for Tomcat of the JAAS-based
1061J2EE authentication framework for J2EE v1.4, based on the <a href="http://www.jcp.org/en/jsr/detail?id=196">JCP Specification
1062Request 196</a> to enhance container-managed security and promote
1063'pluggable' authentication mechanisms whose implementations would be
1064container-independent.
1065 </p>
1066 <p>Based on the JAAS login module and principal (see <code>javax.security.auth.spi.LoginModule</code>
1067and <code>javax.security.Principal</code>), you can develop your own
1068security mechanism or wrap another third-party mechanism for
1069integration with the CMA as implemented by Tomcat.
1070 </p>
1071
1072 <h3>Quick Start</h3>
1073 <p>To set up Tomcat to use JAASRealm with your own JAAS login module,
1074 you will need to follow these steps:</p>
1075 <ol>
1076 <li>Write your own LoginModule, User and Role classes based
刘洪青6266f992017-05-15 21:21:03 +08001077on JAAS (see
1078<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/tutorials/GeneralAcnOnly.html">
1079the JAAS Authentication Tutorial</a> and
1080<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/jaas/JAASLMDevGuide.html">
1081the JAAS Login Module Developer's Guide</a>) to be managed by the JAAS Login
Hongqing Liufd5ee812014-05-10 16:32:51 +08001082Context (<code>javax.security.auth.login.LoginContext</code>)
1083When developing your LoginModule, note that JAASRealm's built-in <code>CallbackHandler</code>
1084only recognizes the <code>NameCallback</code> and <code>PasswordCallback</code> at present.
1085 </li>
1086 <li>Although not specified in JAAS, you should create
刘洪青6266f992017-05-15 21:21:03 +08001087separate classes to distinguish between users and roles, extending <code>javax.security.Principal</code>,
Hongqing Liufd5ee812014-05-10 16:32:51 +08001088so that Tomcat can tell which Principals returned from your login
1089module are users and which are roles (see <code>org.apache.catalina.realm.JAASRealm</code>).
1090Regardless, the first Principal returned is <em>always</em> treated as the user Principal.
1091 </li>
1092 <li>Place the compiled classes on Tomcat's classpath
1093 </li>
刘洪青6266f992017-05-15 21:21:03 +08001094 <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">
1095JAAS LoginConfig file</a>) and tell Tomcat where to find it by specifying
Hongqing Liufd5ee812014-05-10 16:32:51 +08001096its location to the JVM, for instance by setting the environment
1097variable: <code>JAVA_OPTS=$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_BASE/conf/jaas.config</code></li>
1098
1099 <li>Configure your security-constraints in your web.xml for
1100the resources you want to protect</li>
1101 <li>Configure the JAASRealm module in your server.xml </li>
刘洪青6266f992017-05-15 21:21:03 +08001102 <li>Restart Tomcat if it is already running.</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001103 </ol>
1104 <h3>Realm Element Attributes</h3>
1105 <p>To configure JAASRealm as for step 6 above, you create
刘洪青6266f992017-05-15 21:21:03 +08001106a <code>&lt;Realm&gt;</code> element and nest it in your
Hongqing Liufd5ee812014-05-10 16:32:51 +08001107<code>$CATALINA_BASE/conf/server.xml</code>
1108file within your <code>&lt;Engine&gt;</code> node. The attributes for the
1109JAASRealm are defined in the <a href="config/realm.html">Realm</a>
1110configuration documentation.</p>
1111
1112<h3>Example</h3>
1113
1114<p>Here is an example of how your server.xml snippet should look.</p>
1115
刘洪青6266f992017-05-15 21:21:03 +08001116<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001117&lt;Realm className="org.apache.catalina.realm.JAASRealm"
1118 appName="MyFooRealm"
1119 userClassNames="org.foobar.realm.FooUser"
刘洪青6266f992017-05-15 21:21:03 +08001120 roleClassNames="org.foobar.realm.FooRole"/&gt;
1121</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001122
刘洪青6266f992017-05-15 21:21:03 +08001123<p>It is the responsibility of your login module to create and save User and
1124Role objects representing Principals for the user
1125(<code>javax.security.auth.Subject</code>). If your login module doesn't
1126create a user object but also doesn't throw a login exception, then the
1127Tomcat CMA will break and you will be left at the
1128http://localhost:8080/myapp/j_security_check URI or at some other
Hongqing Liufd5ee812014-05-10 16:32:51 +08001129unspecified location.</p>
1130
1131 <p>The flexibility of the JAAS approach is two-fold: </p>
1132 <ul>
1133 <li>you can carry out whatever processing you require behind
1134the scenes in your own login module.</li>
刘洪青6266f992017-05-15 21:21:03 +08001135 <li>you can plug in a completely different LoginModule by changing the configuration
Hongqing Liufd5ee812014-05-10 16:32:51 +08001136and restarting the server, without any code changes to your application.</li>
1137 </ul>
1138
1139 <h3>Additional Notes</h3>
1140 <ul>
1141 <li>When a user attempts to access a protected resource for
刘洪青6266f992017-05-15 21:21:03 +08001142 the first time, Tomcat will call the <code>authenticate()</code>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001143 method of this <code>Realm</code>. Thus, any changes you have made in
1144 the security mechanism directly (new users, changed passwords or
1145 roles, etc.) will be immediately reflected.</li>
1146 <li>Once a user has been authenticated, the user (and his or
1147 her associated roles) are cached within Tomcat for the duration of
1148 the user's login. For FORM-based authentication, that means until
1149 the session times out or is invalidated; for BASIC authentication,
1150 that means until the user closes their browser. Any changes to the
1151 security information for an already authenticated user will <strong>not</strong>
1152 be reflected until the next time that user logs on again.</li>
1153 <li>As with other <code>Realm</code> implementations, digested passwords
1154 are supported if the <code>&lt;Realm&gt;</code> element in <code>server.xml</code>
1155 contains a <code>digest</code> attribute; JAASRealm's <code>CallbackHandler</code>
刘洪青6266f992017-05-15 21:21:03 +08001156 will digest the password prior to passing it back to the <code>LoginModule</code></li>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001157 </ul>
1158
1159</blockquote></td></tr></table>
1160
1161
1162<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="CombinedRealm"><strong>CombinedRealm</strong></a></font></td></tr><tr><td><blockquote>
1163
1164 <h3>Introduction</h3>
1165
刘洪青6266f992017-05-15 21:21:03 +08001166 <p><strong>CombinedRealm</strong> is an implementation of the Tomcat
Hongqing Liufd5ee812014-05-10 16:32:51 +08001167 <code>Realm</code> interface that authenticates users through one or more
1168 sub-Realms.</p>
1169
1170 <p>Using CombinedRealm gives the developer the ability to combine multiple
1171 Realms of the same or different types. This can be used to authenticate
1172 against different sources, provide fall back in case one Realm fails or for
1173 any other purpose that requires multiple Realms.</p>
1174
1175 <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
1176 <code>Realm</code> element that defines the CombinedRealm. Authentication
1177 will be attempted against each <code>Realm</code> in the order they are
1178 listed. Authentication against any Realm will be sufficient to authenticate
1179 the user.</p>
1180
1181 <h3>Realm Element Attributes</h3>
1182 <p>To configure a CombinedRealm, you create a <code>&lt;Realm&gt;</code>
1183 element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code>
1184 file within your <code>&lt;Engine&gt;</code> or <code>&lt;Host&gt;</code>.
1185 You can also nest inside a <code>&lt;Context&gt;</code> node in a
1186 <code>context.xml</code> file.</p>
刘洪青6266f992017-05-15 21:21:03 +08001187
Hongqing Liufd5ee812014-05-10 16:32:51 +08001188<h3>Example</h3>
1189
1190<p>Here is an example of how your server.xml snippet should look to use a
1191UserDatabase Realm and a DataSource Realm.</p>
1192
刘洪青6266f992017-05-15 21:21:03 +08001193<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001194&lt;Realm className="org.apache.catalina.realm.CombinedRealm" &gt;
1195 &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm"
1196 resourceName="UserDatabase"/&gt;
1197 &lt;Realm className="org.apache.catalina.realm.DataSourceRealm"
1198 dataSourceName="jdbc/authority"
1199 userTable="users" userNameCol="user_name" userCredCol="user_pass"
1200 userRoleTable="user_roles" roleNameCol="role_name"/&gt;
1201&lt;/Realm&gt;
刘洪青6266f992017-05-15 21:21:03 +08001202</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001203
1204</blockquote></td></tr></table>
1205
1206<table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="LockOutRealm"><strong>LockOutRealm</strong></a></font></td></tr><tr><td><blockquote>
1207
1208 <h3>Introduction</h3>
1209
刘洪青6266f992017-05-15 21:21:03 +08001210 <p><strong>LockOutRealm</strong> is an implementation of the Tomcat
Hongqing Liufd5ee812014-05-10 16:32:51 +08001211 <code>Realm</code> interface that extends the CombinedRealm to provide lock
1212 out functionality to provide a user lock out mechanism if there are too many
1213 failed authentication attempts in a given period of time.</p>
刘洪青6266f992017-05-15 21:21:03 +08001214
Hongqing Liufd5ee812014-05-10 16:32:51 +08001215 <p>To ensure correct operation, there is a reasonable degree of
1216 synchronisation in this Realm.</p>
刘洪青6266f992017-05-15 21:21:03 +08001217
Hongqing Liufd5ee812014-05-10 16:32:51 +08001218 <p>This Realm does not require modification to the underlying Realms or the
1219 associated user storage mechanisms. It achieves this by recording all failed
1220 logins, including those for users that do not exist. To prevent a DOS by
1221 deliberating making requests with invalid users (and hence causing this
1222 cache to grow) the size of the list of users that have failed authentication
1223 is limited.</p>
1224
1225 <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
1226 <code>Realm</code> element that defines the LockOutRealm. Authentication
1227 will be attempted against each <code>Realm</code> in the order they are
1228 listed. Authentication against any Realm will be sufficient to authenticate
1229 the user.</p>
1230
1231 <h3>Realm Element Attributes</h3>
1232 <p>To configure a LockOutRealm, you create a <code>&lt;Realm&gt;</code>
1233 element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code>
1234 file within your <code>&lt;Engine&gt;</code> or <code>&lt;Host&gt;</code>.
1235 You can also nest inside a <code>&lt;Context&gt;</code> node in a
1236 <code>context.xml</code> file. The attributes for the
1237 LockOutRealm are defined in the <a href="config/realm.html">Realm</a>
1238 configuration documentation.</p>
刘洪青6266f992017-05-15 21:21:03 +08001239
Hongqing Liufd5ee812014-05-10 16:32:51 +08001240<h3>Example</h3>
1241
1242<p>Here is an example of how your server.xml snippet should look to add lock out
1243functionality to a UserDatabase Realm.</p>
1244
刘洪青6266f992017-05-15 21:21:03 +08001245<div class="codeBox"><pre><code>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001246&lt;Realm className="org.apache.catalina.realm.LockOutRealm" &gt;
1247 &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm"
1248 resourceName="UserDatabase"/&gt;
1249&lt;/Realm&gt;
刘洪青6266f992017-05-15 21:21:03 +08001250</code></pre></div>
Hongqing Liufd5ee812014-05-10 16:32:51 +08001251
1252</blockquote></td></tr></table>
1253
刘洪青6266f992017-05-15 21:21:03 +08001254</blockquote></td></tr></table></td></tr><tr class="noPrint"><td width="20%" valign="top" nowrap class="noPrint"></td><td width="80%" valign="top" align="left"><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="comments_section" id="comments_section"><strong>Comments</strong></a></font></td></tr><tr><td><blockquote><p class="notice"><strong>Notice: </strong>This comments section collects your suggestions
1255 on improving documentation for Apache Tomcat.<br><br>
1256 If you have trouble and need help, read
1257 <a href="http://tomcat.apache.org/findhelp.html">Find Help</a> page
1258 and ask your question on the tomcat-users
1259 <a href="http://tomcat.apache.org/lists.html">mailing list</a>.
1260 Do not ask such questions here. This is not a Q&amp;A section.<br><br>
1261 The Apache Comments System is explained <a href="./comments.html">here</a>.
1262 Comments may be removed by our moderators if they are either
1263 implemented or considered invalid/off-topic.</p><script type="text/javascript"><!--//--><![CDATA[//><!--
1264 var comments_shortname = 'tomcat';
1265 var comments_identifier = 'http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html';
1266 (function(w, d) {
1267 if (w.location.hostname.toLowerCase() == "tomcat.apache.org") {
1268 d.write('<div id="comments_thread"><\/div>');
1269 var s = d.createElement('script');
1270 s.type = 'text/javascript';
1271 s.async = true;
1272 s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
1273 (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
1274 }
1275 else {
1276 d.write('<div id="comments_thread"><strong>Comments are disabled for this page at the moment.<\/strong><\/div>');
1277 }
1278 })(window, document);
1279 //--><!]]></script></blockquote></td></tr></table></td></tr><!--FOOTER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><!--PAGE FOOTER--><tr><td colspan="2"><div align="center"><font color="#525D76" size="-1"><em>
1280 Copyright &copy; 1999-2017, Apache Software Foundation
Hongqing Liufd5ee812014-05-10 16:32:51 +08001281 </em></font></div></td></tr></table></body></html>