blob: 87d92ee9481ae879a4cb4c57db8397b759f98d9e [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>Catalina Functional Specifications (7.0.77) - JNDIRealm</title><meta name="author" content="Craig McClanahan"><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 Catalina Functional Specifications
刘洪青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="index.html">Functional Specs</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>Administrative Apps</strong></p><ul><li><a href="fs-admin-apps.html">Overall Requirements</a></li><li><a href="mbean-names.html">Tomcat MBean Names</a></li><li><a href="fs-admin-objects.html">Administered Objects</a></li><li><a href="fs-admin-opers.html">Supported Operations</a></li></ul><p><strong>Internal Servlets</strong></p><ul><li><a href="fs-default.html">Default Servlet</a></li></ul><p><strong>Realm Implementations</strong></p><ul><li><a href="fs-jdbc-realm.html">JDBC Realm</a></li><li><a href="fs-jndi-realm.html">JNDI Realm</a></li><li><a href="fs-memory-realm.html">Memory Realm</a></li></ul></td><!--RIGHT SIDE MAIN BODY--><td width="80%" valign="top" align="left" id="mainBody"><h1>JNDIRealm</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="#Overview">Overview</a><ol><li><a href="#Introduction">Introduction</a></li><li><a href="#External_Specifications">External Specifications</a></li><li><a href="#Implementation_Requirements">Implementation Requirements</a></li></ol></li><li><a href="#Dependencies">Dependencies</a><ol><li><a href="#Environmental_Dependencies">Environmental Dependencies</a></li><li><a href="#Container_Dependencies">Container Dependencies</a></li></ol></li><li><a href="#Functionality">Functionality</a><ol><li><a href="#Operational_Modes">Operational Modes</a></li><li><a href="#Administrator_Login_Mode_Functionality">Administrator Login Mode Functionality</a></li><li><a href="#Username_Login_Mode_Functionality">Username Login Mode Functionality</a></li></ol></li><li><a href="#Testable_Assertions">Testable Assertions</a></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="Overview"><strong>Overview</strong></a></font></td></tr><tr><td><blockquote>
84
85
86 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Introduction"><strong>Introduction</strong></a></font></td></tr><tr><td><blockquote>
87
88 <p>The purpose of the <strong>JNDIRealm</strong> implementation is to
刘洪青6266f992017-05-15 21:21:03 +080089 provide a mechanism by which Tomcat can acquire information needed
Hongqing Liufd5ee812014-05-10 16:32:51 +080090 to authenticate web application users, and define their security roles,
91 from a directory server or other service accessed via JNDI APIs. For
92 integration with Catalina, this class must implement the
93 <code>org.apache.catalina.Realm</code> interface.</p>
94
95 <p>This specification reflects a combination of functionality that is
96 already present in the <code>org.apache.catalina.realm.JNDIRealm</code>
97 class, as well as requirements for enhancements that have been
98 discussed. Where appropriate, requirements statements are marked
99 <em>[Current]</em> and <em>[Requested]</em> to distinguish them.</p>
100
101 <p>The current status of this functional specification is
102 <strong>PROPOSED</strong>. It has not yet been discussed and
103 agreed to on the TOMCAT-DEV mailing list.</p>
104
105 <p>The code in the current version of <code>JNDIRealm</code>, and the
106 ideas expressed in this functional specification, are the results of
107 contributions from many individuals, including (alphabetically):</p>
108 <ul>
109 <li>Holman, John &lt;j.g.holman@qmw.ac.uk&gt;</li>
110 <li>Lockhart, Ellen &lt;elockhart@home.com&gt;</li>
111 <li>McClanahan, Craig &lt;craigmcc@apache.org&gt;</li>
112 </ul>
113
114 </blockquote></td></tr></table>
115
116
117 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="External Specifications"><!--()--></a><a name="External_Specifications"><strong>External Specifications</strong></a></font></td></tr><tr><td><blockquote>
118
119 <p>The implementation of this functionality depends on the following
120 external specifications:</p>
121 <ul>
刘洪青6266f992017-05-15 21:21:03 +0800122 <li><a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/index.html">
123 Java Naming and Directory Interface</a> (version 1.2.1 or later)</li>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800124 </ul>
125
126 </blockquote></td></tr></table>
127
128
129 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Implementation Requirements"><!--()--></a><a name="Implementation_Requirements"><strong>Implementation Requirements</strong></a></font></td></tr><tr><td><blockquote>
130
131 <p>The implementation of this functionality shall conform to the
132 following requirements:</p>
133 <ul>
134 <li>Be realized in one or more implementation classes.</li>
135 <li>Implement the <code>org.apache.catalina.Realm</code> interface.
136 [Current]</li>
137 <li>Implement the <code>org.apache.catalina.Lifecycle</code>
138 interface. [Current]</li>
139 <li>Subclass the <code>org.apache.catalina.realm.RealmBase</code>
140 base class.</li>
141 <li>Live in the <code>org.apache.catalina.realm</code> package.
142 [Current]</li>
143 <li>Support a configurable debugging detail level. [Current]</li>
144 <li>Log debugging and operational messages (suitably internationalized)
145 via the <code>getContainer().log()</code> method. [Current]</li>
146 </ul>
147
148 </blockquote></td></tr></table>
149
150
151</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Dependencies"><strong>Dependencies</strong></a></font></td></tr><tr><td><blockquote>
152
153
154 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Environmental Dependencies"><!--()--></a><a name="Environmental_Dependencies"><strong>Environmental Dependencies</strong></a></font></td></tr><tr><td><blockquote>
155
156 <p>The following environmental dependencies must be met in order for
157 JNDIRealm to operate correctly:</p>
158 <ul>
159 <li>The desire to utilize JNDIRealm must be registered in
160 <code>$CATALINA_BASE/conf/server.xml</code>, in a
161 <code>&lt;Realm&gt;</code> element that is nested inside a
162 corresponding <code>&lt;Engine&gt;</code>, <code>&lt;Host&gt;</code>,
163 or <code>&lt;Context&gt;</code> element.</li>
164 <li>If the <em>Administrator Login</em> operational mode is selected,
165 the configured administrator username and password must be configured
166 in the corresponding directory server.</li>
167 <li>If the <em>Username Login</em> operational mode is selected,
168 the corresponding directory server must be configured to accept
169 logins with the username and password that will be passed to
170 <code>JNDIRealm</code> by the appropriate <code>Authenticator</code>.
171 </li>
172 </ul>
173
174 </blockquote></td></tr></table>
175
176
177 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Container Dependencies"><!--()--></a><a name="Container_Dependencies"><strong>Container Dependencies</strong></a></font></td></tr><tr><td><blockquote>
178
179 <p>Correct operation of JNDIRealm depends on the following
180 specific features of the surrounding container:</p>
181 <ul>
182 <li>Interactions with <code>JNDIRealm</code> will be initiated by
183 the appropriate <code>Authenticator</code> implementation, based
184 on the login method that is selected.</li>
185 </ul>
186
187 </blockquote></td></tr></table>
188
189
190</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Functionality"><strong>Functionality</strong></a></font></td></tr><tr><td><blockquote>
191
192
193 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Operational Modes"><!--()--></a><a name="Operational_Modes"><strong>Operational Modes</strong></a></font></td></tr><tr><td><blockquote>
194
195 <p>The completed <code>JNDIRealm</code> must support two major operational
196 modes in order to support all of the required use cases. For the purposes
197 of this document, the modes are called <em>administrator login</em> and
198 <em>Username Login</em>. They are described further in the following
199 paragraphs.</p>
200
201 <p>For <em>Administrator Login</em> mode, <code>JNDIRealm</code> will be
202 configured to establish one or more connections (using a connection pool)
203 to an appropriate directory server, using JNDI APIs, under a "system
204 administrator" username and password. This is similar to the approach
205 normally used to configure <code>JDBCRealm</code> to access authentication
206 and access control information in a database. It is assumed that the
207 system administrator username and password that are configured provide
208 sufficient privileges within the directory server to read (but not modify)
209 the username, password, and assigned roles for each valid user of the
210 web application associated with this <code>Realm</code>. The password
211 can be stored in cleartext, or in one of the digested modes supported by
212 the <code>org.apache.catalina.realm.RealmBase</code> base class.</p>
213
214 <p>For <em>Username Login</em> mode, <code>JNDIRealm</code> does not
215 normally remain connected to the directory server. Instead, whenever a
216 user is to be authenticated, a connection to the directory server
217 (using the username and password received from the authenticator) is
218 attempted. If this connection is successful, the user is assumed to be
219 successfully authenticated. This connection is then utilized to read
220 the corresponding security roles associated with this user, and the
221 connection is then broken.</p>
222
223 <p><strong>NOTE</strong> - <em>Username Login</em> mode cannot be used
224 if you have selected login method <code>DIGEST</code> in your web
225 application deployment descriptor (<code>web.xml</code>) file. This
226 restriction exists because the cleartext password is never available
227 to the container, so it is not possible to bind to the directory server
228 using the user's username and password.</p>
229
230 <p>Because these operational modes work so differently, the functionality
231 for each mode will be described separately. Whether or not both modes
232 are actually supported by a single class (versus a class per mode) is
233 an implementation detail left to the designer.</p>
234
235 <p><strong>NOTE</strong> - The current implementation only implements
236 part of the <em>Administrator Lookup</em> mode requirements. It does
237 not support the <em>Username Lookup</em> mode at all, at this point.</p>
238
239 </blockquote></td></tr></table>
240
241
242 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Administrator Login Mode Functionality"><!--()--></a><a name="Administrator_Login_Mode_Functionality"><strong>Administrator Login Mode Functionality</strong></a></font></td></tr><tr><td><blockquote>
243
244
245 <h3>Configurable Properties</h3>
246
247 <p>The implementation shall support the following properties
248 that can be configured with JavaBeans property setters:</p>
249 <ul>
250 <li><code>connectionURL</code> - URL of the directory server we will
251 be contacting.</li>
252 <li><code>contextFactory</code> - Fully qualified class name of the JNDI
253 context factory used to retrieve our InitialContext.
254 [com.sun.jndi.ldap.LdapCtxFactory]</li>
255 <li>Additional configuration properties required to establish the
256 appropriate connection. [Requested]</li>
257 <li>Connection pool configuration properties. [Requested]</li>
258 <li>Configuration properties defining how a particular user is
259 authenticated. The following capabilities should be supported:
260 <ul>
261 <li>Substitute the specified username into a string. [Requested]</li>
262 <li>Retrieve the distinguished name (DN) of an authorized user via an
263 LDAP search string with a replacement placeholder for the
264 username, and comparison of the password to a configurable
265 attribute retrieved from the search result. [Current]</li>
266 </ul></li>
267 <li>Configuration properties defining how the roles associated with a
268 particular authenticated user can be retrieved. The following
269 approaches should be supported:
270 <ul>
271 <li>Retrieve a specified attribute (possibly multi-valued)
272 from an LDAP search expression,
273 with a replacement placeholder for the DN of the user.
274 [Current]</li>
275 <li>Retrieve a set of role names that are defined implicitly (by
276 selecting principals that match a search pattern) rather than
277 explicitly (by finding a particular attribute value).
278 [Requested]</li>
279 </ul></li>
280 </ul>
281
282 <h3>Lifecycle Functionality</h3>
283
284 <p>The following processing must be performed when the <code>start()</code>
285 method is called:</p>
286 <ul>
287 <li>Establish a connection to the configured directory server, using the
288 configured system administrator username and password. [Current]</li>
289 <li>Configure and establish a connection pool of connections to the
290 directory server. [Requested]</li>
291 </ul>
292
293 <p>The following processing must be performed when the <code>stop()</code>
294 method is called:</p>
295 <ul>
296 <li>Close any opened connections to the directory server.</li>
297 </ul>
298
299
300 <h3>Method authenticate() Functionality</h3>
301
302 <p>When <code>authenticate()</code> is called, the following processing
303 is required:</p>
304 <ul>
305 <li>Acquire the one and only connection [Current] or acquire a connection
306 from the connection pool [Requested].</li>
307 <li>Authenticate the user by retrieving the user's Distinguished Name,
308 based on the specified username and password.</li>
309 <li>If the user was not authenticated, release the allocated connection
310 and return <code>null</code>.</li>
311 <li>Acquire a <code>List</code> of the security roles assigned to the
312 authenticated user.</li>
313 <li>Construct a new instance of class
314 <code>org.apache.catalina.realm.GenericPrincipal</code>, passing as
315 constructor arguments: this realm instance, the authenticated
316 username, and a <code>List</code> of the security roles associated
317 with this user.</li>
318 <li><strong>WARNING</strong> - Do not attempt to cache and reuse previous
319 <code>GenericPrincipal</code> objects for a particular user, because
320 the information in the directory server might have changed since the
321 last time this user was authenticated.</li>
322 <li>Return the newly constructed <code>GenericPrincipal</code>.</li>
323 </ul>
324
325
326 <h3>Method hasRole() Functionality</h3>
327
328 <p>When <code>hasRole()</code> is called, the following processing
329 is required:</p>
330 <ul>
331 <li>The <code>principal</code> that is passed as an argument SHOULD
332 be one that we returned (instanceof class
333 <code>org.apache.catalina.realm.GenericPrincipal</code>, with a
334 <code>realm</code> property that is equal to our instance.</li>
335 <li>If the passed <code>principal</code> meets these criteria, check
336 the specified role against the list returned by
337 <code>getRoles()</code>, and return <code>true</code> if the
338 specified role is included; otherwise, return <code>false</code>.</li>
339 <li>If the passed <code>principal</code> does not meet these criteria,
340 return <code>false</code>.</li>
341 </ul>
342
343 </blockquote></td></tr></table>
344
345
346 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Username Login Mode Functionality"><!--()--></a><a name="Username_Login_Mode_Functionality"><strong>Username Login Mode Functionality</strong></a></font></td></tr><tr><td><blockquote>
347
348 <h3>Configurable Properties</h3>
349
350 <p>The implementation shall support the following properties
351 that can be configured with JavaBeans property setters:</p>
352 <ul>
353 <li><code>connectionURL</code> - URL of the directory server we will
354 be contacting.</li>
355 <li><code>contextFactory</code> - Fully qualified class name of the JNDI
356 context factory used to retrieve our InitialContext.
357 [com.sun.jndi.ldap.LdapCtxFactory]</li>
358 <li>Additional configuration properties required to establish the
359 appropriate connection. [Requested]</li>
360 <li>Connection pool configuration properties. [Requested]</li>
361 <li>Configuration properties defining if and how a user might be looked
362 up before binding to the directory server. The following approaches
363 should be supported:
364 <ul>
365 <li>No previous lookup is required - username specified by the user
366 is the same as that used to authenticate to the directory
367 server.</li>
368 <li>Substitute the specified username into a string.</li>
369 <li>Search the directory server based on configured criteria to
370 retrieve the distinguished name of the user, then attempt to
371 bind with that distinguished name.</li>
372 </ul></li>
373 <li>Configuration properties defining how the roles associated with a
374 particular authenticated user can be retrieved. The following
375 approaches should be supported:
376 <ul>
377 <li>Retrieve a specified attribute (possibly multi-valued)
378 from an LDAP search expression,
379 with a replacement placeholder for the DN of the user.
380 [Current]</li>
381 </ul></li>
382 </ul>
383
384 <h3>Lifecycle Functionality</h3>
385
386 <p>The following processing must be performed when the <code>start()</code>
387 method is called:</p>
388 <ul>
389 <li>None required.</li>
390 </ul>
391
392 <p>The following processing must be performed when the <code>stop()</code>
393 method is called:</p>
394 <ul>
395 <li>None required.</li>
396 </ul>
397
398
399 <h3>Method authenticate() Functionality</h3>
400
401 <p>When <code>authenticate()</code> is called, the following processing
402 is required:</p>
403 <ul>
404 <li>Attempt to bind to the directory server, using the username and
405 password provided by the user.</li>
406 <li>If the user was not authenticated, release the allocated connection
407 and return <code>null</code>.</li>
408 <li>Acquire a <code>List</code> of the security roles assigned to the
409 authenticated user.</li>
410 <li>Construct a new instance of class
411 <code>org.apache.catalina.realm.GenericPrincipal</code>, passing as
412 constructor arguments: this realm instance, the authenticated
413 username, and a <code>List</code> of the security roles associated
414 with this user.</li>
415 <li><strong>WARNING</strong> - Do not attempt to cache and reuse previous
416 <code>GenericPrincipal</code> objects for a particular user, because
417 the information in the directory server might have changed since the
418 last time this user was authenticated.</li>
419 <li>Return the newly constructed <code>GenericPrincipal</code>.</li>
420 </ul>
421
422
423 <h3>Method hasRole() Functionality</h3>
424
425 <p>When <code>hasRole()</code> is called, the following processing
426 is required:</p>
427 <ul>
428 <li>The <code>principal</code> that is passed as an argument SHOULD
429 be one that we returned (instanceof class
430 <code>org.apache.catalina.realm.GenericPrincipal</code>, with a
431 <code>realm</code> property that is equal to our instance.</li>
432 <li>If the passed <code>principal</code> meets these criteria, check
433 the specified role against the list returned by
434 <code>getRoles()</code>, and return <code>true</code> if the
435 specified role is included; otherwise, return <code>false</code>.</li>
436 <li>If the passed <code>principal</code> does not meet these criteria,
437 return <code>false</code>.</li>
438 </ul>
439
440 </blockquote></td></tr></table>
441
442</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Testable Assertions"><!--()--></a><a name="Testable_Assertions"><strong>Testable Assertions</strong></a></font></td></tr><tr><td><blockquote>
443
刘洪青6266f992017-05-15 21:21:03 +0800444 <p>In addition to the assertions implied by the functionality requirements
Hongqing Liufd5ee812014-05-10 16:32:51 +0800445 listed above, the following additional assertions shall be tested to
446 validate the behavior of <code>JNDIRealm</code>:</p>
447 <ul>
448 </ul>
449
刘洪青6266f992017-05-15 21:21:03 +0800450</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
451 on improving documentation for Apache Tomcat.<br><br>
452 If you have trouble and need help, read
453 <a href="http://tomcat.apache.org/findhelp.html">Find Help</a> page
454 and ask your question on the tomcat-users
455 <a href="http://tomcat.apache.org/lists.html">mailing list</a>.
456 Do not ask such questions here. This is not a Q&amp;A section.<br><br>
457 The Apache Comments System is explained <a href="../comments.html">here</a>.
458 Comments may be removed by our moderators if they are either
459 implemented or considered invalid/off-topic.</p><script type="text/javascript"><!--//--><![CDATA[//><!--
460 var comments_shortname = 'tomcat';
461 var comments_identifier = 'http://tomcat.apache.org/tomcat-7.0-doc/funcspecs/fs-jndi-realm.html';
462 (function(w, d) {
463 if (w.location.hostname.toLowerCase() == "tomcat.apache.org") {
464 d.write('<div id="comments_thread"><\/div>');
465 var s = d.createElement('script');
466 s.type = 'text/javascript';
467 s.async = true;
468 s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
469 (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
470 }
471 else {
472 d.write('<div id="comments_thread"><strong>Comments are disabled for this page at the moment.<\/strong><\/div>');
473 }
474 })(window, document);
475 //--><!]]></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>
476 Copyright &copy; 1999-2017, Apache Software Foundation
Hongqing Liufd5ee812014-05-10 16:32:51 +0800477 </em></font></div></td></tr></table></body></html>