Zend_Auth_Adapter_Ldap.xml 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.auth.adapter.ldap">
  4. <title>LDAP Authentication</title>
  5. <sect2 id="zend.auth.adapter.ldap.introduction">
  6. <title>Introduction</title>
  7. <para>
  8. <classname>Zend_Auth_Adapter_Ldap</classname> supports web application authentication
  9. with LDAP services. Its features include username and domain name canonicalization,
  10. multi-domain authentication, and failover capabilities. It has been tested to work with
  11. <ulink
  12. url="http://www.microsoft.com/windowsserver2003/technologies/directory/activedirectory/">Microsoft
  13. Active Directory</ulink> and <ulink url="http://www.openldap.org/">OpenLDAP</ulink>,
  14. but it should also work with other LDAP service providers.
  15. </para>
  16. <para>
  17. This documentation includes a guide on using
  18. <classname>Zend_Auth_Adapter_Ldap</classname>, an exploration of its API, an outline of
  19. the various available options, diagnostic information for troubleshooting authentication
  20. problems, and example options for both Active Directory and OpenLDAP servers.
  21. </para>
  22. </sect2>
  23. <sect2 id="zend.auth.adapter.ldap.usage">
  24. <title>Usage</title>
  25. <para>
  26. To incorporate <classname>Zend_Auth_Adapter_Ldap</classname> authentication into your
  27. application quickly, even if you're not using <classname>Zend_Controller</classname>,
  28. the meat of your code should look something like the following:
  29. <programlisting language="php"><![CDATA[
  30. $username = $this->_request->getParam('username');
  31. $password = $this->_request->getParam('password');
  32. $auth = Zend_Auth::getInstance();
  33. $config = new Zend_Config_Ini('../application/config/config.ini',
  34. 'production');
  35. $log_path = $config->ldap->log_path;
  36. $options = $config->ldap->toArray();
  37. unset($options['log_path']);
  38. $adapter = new Zend_Auth_Adapter_Ldap($options, $username,
  39. $password);
  40. $result = $auth->authenticate($adapter);
  41. if ($log_path) {
  42. $messages = $result->getMessages();
  43. $logger = new Zend_Log();
  44. $logger->addWriter(new Zend_Log_Writer_Stream($log_path));
  45. $filter = new Zend_Log_Filter_Priority(Zend_Log::DEBUG);
  46. $logger->addFilter($filter);
  47. foreach ($messages as $i => $message) {
  48. if ($i-- > 1) { // $messages[2] and up are log messages
  49. $message = str_replace("\n", "\n ", $message);
  50. $logger->log("Ldap: $i: $message", Zend_Log::DEBUG);
  51. }
  52. }
  53. }
  54. ]]></programlisting>
  55. Of course, the logging code is optional, but it is highly recommended that you use a
  56. logger. <classname>Zend_Auth_Adapter_Ldap</classname> will record just about every bit
  57. of information anyone could want in <varname>$messages</varname> (more below), which is
  58. a nice feature in itself for something that has a history of being notoriously difficult
  59. to debug.
  60. </para>
  61. <para>
  62. The <classname>Zend_Config_Ini</classname> code is used above to load the adapter
  63. options. It is also optional. A regular array would work equally well. The following is
  64. an example <filename>application/config/config.ini</filename> file that has options for
  65. two separate servers. With multiple sets of server options the adapter will try each, in
  66. order, until the credentials are successfully authenticated. The names of the servers
  67. (e.g., 'server1' and 'server2') are largely arbitrary. For details regarding the options
  68. array, see the <emphasis>Server Options</emphasis> section below. Note that
  69. <classname>Zend_Config_Ini</classname> requires that any values with "equals" characters
  70. (<emphasis>=</emphasis>) will need to be quoted (like the DNs shown below).
  71. <programlisting language="ini"><![CDATA[
  72. [production]
  73. ldap.log_path = /tmp/ldap.log
  74. ; Typical options for OpenLDAP
  75. ldap.server1.host = s0.foo.net
  76. ldap.server1.accountDomainName = foo.net
  77. ldap.server1.accountDomainNameShort = FOO
  78. ldap.server1.accountCanonicalForm = 3
  79. ldap.server1.username = "CN=user1,DC=foo,DC=net"
  80. ldap.server1.password = pass1
  81. ldap.server1.baseDn = "OU=Sales,DC=foo,DC=net"
  82. ldap.server1.bindRequiresDn = true
  83. ; Typical options for Active Directory
  84. ldap.server2.host = dc1.w.net
  85. ldap.server2.useStartTls = true
  86. ldap.server2.accountDomainName = w.net
  87. ldap.server2.accountDomainNameShort = W
  88. ldap.server2.accountCanonicalForm = 3
  89. ldap.server2.baseDn = "CN=Users,DC=w,DC=net"
  90. ]]></programlisting>
  91. The above configuration will instruct <classname>Zend_Auth_Adapter_Ldap</classname> to
  92. attempt to authenticate users with the OpenLDAP server <filename>s0.foo.net</filename>
  93. first. If the authentication fails for any reason, the AD server
  94. <filename>dc1.w.net</filename> will be tried.
  95. </para>
  96. <para>
  97. With servers in different domains, this configuration illustrates multi-domain
  98. authentication. You can also have multiple servers in the same domain to provide
  99. redundancy.
  100. </para>
  101. <para>
  102. Note that in this case, even though OpenLDAP has no need for the short NetBIOS style
  103. domain name used by Windows, we provide it here for name canonicalization purposes
  104. (described in the <emphasis>Username Canonicalization</emphasis> section below).
  105. </para>
  106. </sect2>
  107. <sect2 id="zend.auth.adapter.ldap.api">
  108. <title>The API</title>
  109. <para>
  110. The <classname>Zend_Auth_Adapter_Ldap</classname> constructor accepts three parameters.
  111. </para>
  112. <para>
  113. The <varname>$options</varname> parameter is required and must be an array containing
  114. one or more sets of options. Note that it is <emphasis>an array of arrays</emphasis> of
  115. <link linkend="zend.ldap"><classname>Zend_Ldap</classname></link> options. Even if you
  116. will be using only one LDAP server, the options must still be within another array.
  117. </para>
  118. <para>
  119. Below is <ulink url="http://php.net/print_r"><methodname>print_r()</methodname></ulink>
  120. output of an example options parameter containing two sets of server options for LDAP
  121. servers <filename>s0.foo.net</filename> and <filename>dc1.w.net</filename> (the same
  122. options as the above INI representation):
  123. <programlisting language="output"><![CDATA[
  124. Array
  125. (
  126. [server2] => Array
  127. (
  128. [host] => dc1.w.net
  129. [useStartTls] => 1
  130. [accountDomainName] => w.net
  131. [accountDomainNameShort] => W
  132. [accountCanonicalForm] => 3
  133. [baseDn] => CN=Users,DC=w,DC=net
  134. )
  135. [server1] => Array
  136. (
  137. [host] => s0.foo.net
  138. [accountDomainName] => foo.net
  139. [accountDomainNameShort] => FOO
  140. [accountCanonicalForm] => 3
  141. [username] => CN=user1,DC=foo,DC=net
  142. [password] => pass1
  143. [baseDn] => OU=Sales,DC=foo,DC=net
  144. [bindRequiresDn] => 1
  145. )
  146. )
  147. ]]></programlisting>
  148. The information provided in each set of options above is different mainly because AD
  149. does not require a username be in DN form when binding (see the
  150. <emphasis>bindRequiresDn</emphasis> option in the <emphasis>Server Options</emphasis>
  151. section below), which means we can omit a number of options associated with retrieving
  152. the DN for a username being authenticated.
  153. </para>
  154. <note>
  155. <title>What is a Distinguished Name?</title>
  156. <para>
  157. A DN or "distinguished name" is a string that represents the path to an object
  158. within the LDAP directory. Each comma-separated component is an attribute and value
  159. representing a node. The components are evaluated in reverse. For example, the user
  160. account <emphasis>CN=Bob Carter,CN=Users,DC=w,DC=net</emphasis> is located directly
  161. within the <emphasis>CN=Users,DC=w,DC=net container</emphasis>. This structure is
  162. best explored with an LDAP browser like the ADSI Edit MMC snap-in for Active
  163. Directory or phpLDAPadmin.
  164. </para>
  165. </note>
  166. <para>
  167. The names of servers (e.g. 'server1' and 'server2' shown above) are largely arbitrary,
  168. but for the sake of using <classname>Zend_Config</classname>, the identifiers should be
  169. present (as opposed to being numeric indexes) and should not contain any special
  170. characters used by the associated file formats (e.g. the '<emphasis>.</emphasis>' INI
  171. property separator, '<emphasis>&amp;</emphasis>' for XML entity references, etc).
  172. </para>
  173. <para>
  174. With multiple sets of server options, the adapter can authenticate users in multiple
  175. domains and provide failover so that if one server is not available, another will be
  176. queried.
  177. </para>
  178. <note>
  179. <title>The Gory Details: What Happens in the Authenticate Method?</title>
  180. <para>
  181. When the <methodname>authenticate()</methodname> method is called, the adapter
  182. iterates over each set of server options, sets them on the internal
  183. <classname>Zend_Ldap</classname> instance, and calls the
  184. <classname>Zend_Ldap::bind()</classname> method with the username and password being
  185. authenticated. The <classname>Zend_Ldap</classname> class checks to see if the
  186. username is qualified with a domain (e.g., has a domain component like
  187. <emphasis>alice@foo.net</emphasis> or <emphasis>FOO\alice</emphasis>). If a domain
  188. is present, but does not match either of the server's domain names
  189. (<emphasis>foo.net</emphasis> or <emphasis>FOO</emphasis>), a special exception is
  190. thrown and caught by <classname>Zend_Auth_Adapter_Ldap</classname> that causes that
  191. server to be ignored and the next set of server options is selected. If a domain
  192. <emphasis>does</emphasis> match, or if the user did not supply a qualified username,
  193. <classname>Zend_Ldap</classname> proceeds to try to bind with the supplied
  194. credentials. if the bind is not successful, <classname>Zend_Ldap</classname> throws
  195. a <classname>Zend_Ldap_Exception</classname> which is caught by
  196. <classname>Zend_Auth_Adapter_Ldap</classname> and the next set of server options is
  197. tried. If the bind is successful, the iteration stops, and the adapter's
  198. <methodname>authenticate()</methodname> method returns a successful result. If all
  199. server options have been tried without success, the authentication fails, and
  200. <methodname>authenticate()</methodname> returns a failure result with error messages
  201. from the last iteration.
  202. </para>
  203. </note>
  204. <para>
  205. The username and password parameters of the
  206. <classname>Zend_Auth_Adapter_Ldap</classname> constructor represent the credentials
  207. being authenticated (i.e., the credentials supplied by the user through your HTML login
  208. form). Alternatively, they may also be set with the
  209. <methodname>setUsername()</methodname> and <methodname>setPassword()</methodname>
  210. methods.
  211. </para>
  212. </sect2>
  213. <sect2 id="zend.auth.adapter.ldap.server-options">
  214. <title>Server Options</title>
  215. <para>
  216. Each set of server options <emphasis>in the context of
  217. <classname>Zend_Auth_Adapter_Ldap</classname></emphasis> consists of the following
  218. options, which are passed, largely unmodified, to
  219. <classname>Zend_Ldap::setOptions()</classname>:
  220. <table id="zend.auth.adapter.ldap.server-options.table">
  221. <title>Server Options</title>
  222. <tgroup cols="2">
  223. <thead>
  224. <row>
  225. <entry>Name</entry>
  226. <entry>Description</entry>
  227. </row>
  228. </thead>
  229. <tbody>
  230. <row>
  231. <entry><emphasis>host</emphasis></entry>
  232. <entry>
  233. The hostname of LDAP server that these options represent. This option is
  234. required.
  235. </entry>
  236. </row>
  237. <row>
  238. <entry><emphasis>port</emphasis></entry>
  239. <entry>
  240. The port on which the LDAP server is listening. If
  241. <emphasis>useSsl</emphasis> is <constant>TRUE</constant>, the default
  242. <emphasis>port</emphasis> value is 636. if <emphasis>useSsl</emphasis> is
  243. <constant>FALSE</constant>, the default <emphasis>port</emphasis> value is
  244. 389.
  245. </entry>
  246. </row>
  247. <row>
  248. <entry>useStartTls</entry>
  249. <entry>
  250. Whether or not the LDAP client should use TLS (aka SSLv2) encrypted
  251. transport. A value of <constant>TRUE</constant> is strongly favored in
  252. production environments to prevent passwords from be transmitted in clear
  253. text. The default value is <constant>FALSE</constant>, as servers frequently
  254. require that a certificate be installed separately after installation. The
  255. <emphasis>useSsl</emphasis> and <emphasis>useStartTls</emphasis> options are
  256. mutually exclusive. The <emphasis>useStartTls</emphasis> option should be
  257. favored over <emphasis>useSsl</emphasis> but not all servers support this
  258. newer mechanism.
  259. </entry>
  260. </row>
  261. <row>
  262. <entry>useSsl</entry>
  263. <entry>
  264. Whether or not the LDAP client should use SSL encrypted transport. The
  265. <emphasis>useSsl</emphasis> and <emphasis>useStartTls</emphasis> options are
  266. mutually exclusive, but <emphasis>useStartTls</emphasis> should be favored
  267. if the server and LDAP client library support it. This value also changes
  268. the default <emphasis>port</emphasis> value (see <emphasis>port</emphasis>
  269. description above).
  270. </entry>
  271. </row>
  272. <row>
  273. <entry><emphasis>username</emphasis></entry>
  274. <entry>
  275. The DN of the account used to perform account DN lookups. LDAP servers that
  276. require the username to be in DN form when performing the "bind" require
  277. this option. Meaning, if <emphasis>bindRequiresDn</emphasis> is
  278. <constant>TRUE</constant>, this option is required. This account does not
  279. need to be a privileged account; an account with read-only access to objects
  280. under the <emphasis>baseDn</emphasis> is all that is necessary (and
  281. preferred based on the <emphasis>Principle of Least Privilege</emphasis>).
  282. </entry>
  283. </row>
  284. <row>
  285. <entry><emphasis>password</emphasis></entry>
  286. <entry>
  287. The password of the account used to perform account DN lookups. If this
  288. option is not supplied, the LDAP client will attempt an "anonymous bind"
  289. when performing account DN lookups.
  290. </entry>
  291. </row>
  292. <row>
  293. <entry><emphasis>bindRequiresDn</emphasis></entry>
  294. <entry>
  295. Some LDAP servers require that the username used to bind be in DN form like
  296. <emphasis>CN=Alice Baker,OU=Sales,DC=foo,DC=net</emphasis> (basically all
  297. servers <emphasis>except</emphasis> AD). If this option is
  298. <constant>TRUE</constant>, this instructs <classname>Zend_Ldap</classname>
  299. to automatically retrieve the DN corresponding to the username being
  300. authenticated, if it is not already in DN form, and then re-bind with the
  301. proper DN. The default value is <constant>FALSE</constant>. Currently only
  302. Microsoft Active Directory Server (ADS) is known <emphasis>not</emphasis> to
  303. require usernames to be in DN form when binding, and therefore this option
  304. may be <constant>FALSE</constant> with AD (and it should be, as retrieving
  305. the DN requires an extra round trip to the server). Otherwise, this option
  306. must be set to <constant>TRUE</constant> (e.g. for OpenLDAP). This option
  307. also controls the default <emphasis>acountFilterFormat</emphasis> used when
  308. searching for accounts. See the <emphasis>accountFilterFormat</emphasis>
  309. option.
  310. </entry>
  311. </row>
  312. <row>
  313. <entry><emphasis>baseDn</emphasis></entry>
  314. <entry>
  315. The DN under which all accounts being authenticated are located. This option
  316. is required. if you are uncertain about the correct
  317. <emphasis>baseDn</emphasis> value, it should be sufficient to derive it from
  318. the user's DNS domain using <emphasis>DC=</emphasis> components. For
  319. example, if the user's principal name is <emphasis>alice@foo.net</emphasis>,
  320. a <emphasis>baseDn</emphasis> of <emphasis>DC=foo,DC=net</emphasis> should
  321. work. A more precise location (e.g.,
  322. <emphasis>OU=Sales,DC=foo,DC=net</emphasis>) will be more efficient,
  323. however.
  324. </entry>
  325. </row>
  326. <row>
  327. <entry><emphasis>accountCanonicalForm</emphasis></entry>
  328. <entry>
  329. A value of 2, 3 or 4 indicating the form to which account names should be
  330. canonicalized after successful authentication. Values are as follows: 2 for
  331. traditional username style names (e.g., <emphasis>alice</emphasis>), 3 for
  332. backslash-style names (e.g., <emphasis>FOO\alice</emphasis>) or 4 for
  333. principal style usernames (e.g., <emphasis>alice@foo.net</emphasis>). The
  334. default value is 4 (e.g., <emphasis>alice@foo.net</emphasis>). For example,
  335. with a value of 3, the identity returned by
  336. <classname>Zend_Auth_Result::getIdentity()</classname> (and
  337. <classname>Zend_Auth::getIdentity()</classname>, if
  338. <classname>Zend_Auth</classname> was used) will always be
  339. <emphasis>FOO\alice</emphasis>, regardless of what form Alice supplied,
  340. whether it be <emphasis>alice</emphasis>,
  341. <emphasis>alice@foo.net</emphasis>, <emphasis>FOO\alice</emphasis>,
  342. <emphasis>FoO\aLicE</emphasis>, <emphasis>foo.net\alice</emphasis>, etc. See
  343. the <emphasis>Account Name Canonicalization</emphasis> section in the
  344. <classname>Zend_Ldap</classname> documentation for details. Note that when
  345. using multiple sets of server options it is recommended, but not required,
  346. that the same <emphasis>accountCanonicalForm</emphasis> be used with all
  347. server options so that the resulting usernames are always canonicalized to
  348. the same form (e.g., if you canonicalize to
  349. <emphasis>EXAMPLE\username</emphasis> with an AD server but to
  350. <emphasis>username@example.com</emphasis> with an OpenLDAP server, that may
  351. be awkward for the application's high-level logic).
  352. </entry>
  353. </row>
  354. <row>
  355. <entry><emphasis>accountDomainName</emphasis></entry>
  356. <entry>
  357. The FQDN domain name for which the target LDAP server is an authority (e.g.,
  358. <filename>example.com</filename>). This option is used to canonicalize names
  359. so that the username supplied by the user can be converted as necessary for
  360. binding. It is also used to determine if the server is an authority for the
  361. supplied username (e.g., if <emphasis>accountDomainName</emphasis> is
  362. <emphasis>foo.net</emphasis> and the user supplies
  363. <emphasis>bob@bar.net</emphasis>, the server will not be queried, and a
  364. failure will result). This option is not required, but if it is not
  365. supplied, usernames in principal name form (e.g.,
  366. <emphasis>alice@foo.net</emphasis>) are not supported. It is strongly
  367. recommended that you supply this option, as there are many use-cases that
  368. require generating the principal name form.
  369. </entry>
  370. </row>
  371. <row>
  372. <entry><emphasis>accountDomainNameShort</emphasis></entry>
  373. <entry>
  374. The 'short' domain for which the target LDAP server is an authority (e.g.,
  375. <emphasis>FOO</emphasis>). Note that there is a 1:1 mapping between the
  376. <emphasis>accountDomainName</emphasis> and
  377. <emphasis>accountDomainNameShort</emphasis>. This option should be used to
  378. specify the NetBIOS domain name for Windows networks, but may also be used
  379. by non-AD servers (e.g., for consistency when multiple sets of server
  380. options with the backslash style <emphasis>accountCanonicalForm</emphasis>).
  381. This option is not required but if it is not supplied, usernames in
  382. backslash form (e.g., <emphasis>FOO\alice</emphasis>) are not supported.
  383. </entry>
  384. </row>
  385. <row>
  386. <entry><emphasis>accountFilterFormat</emphasis></entry>
  387. <entry>
  388. The LDAP search filter used to search for accounts. This string is a <ulink
  389. url="http://php.net/printf"><methodname>printf()</methodname></ulink>-style
  390. expression that must contain one '<emphasis>%s</emphasis>' to accomodate the
  391. username. The default value is
  392. '<emphasis>(&amp;(objectClass=user)(sAMAccountName=%s))</emphasis>', unless
  393. <emphasis>bindRequiresDn</emphasis> is set to <constant>TRUE</constant>, in
  394. which case the default is
  395. '<emphasis>(&amp;(objectClass=posixAccount)(uid=%s))</emphasis>'. For
  396. example, if for some reason you wanted to use
  397. <emphasis>bindRequiresDn = true</emphasis> with AD you would need to set
  398. <emphasis>accountFilterFormat =
  399. '(&amp;(objectClass=user)(sAMAccountName=%s))</emphasis>'.
  400. </entry>
  401. </row>
  402. <row>
  403. <entry><emphasis>optReferrals</emphasis></entry>
  404. <entry>
  405. If set to <constant>TRUE</constant>, this option indicates to the LDAP
  406. client that referrals should be followed. The default value is
  407. <constant>FALSE</constant>.
  408. </entry>
  409. </row>
  410. </tbody>
  411. </tgroup>
  412. </table>
  413. </para>
  414. <note>
  415. <para>
  416. If you enable <emphasis>useStartTls = true</emphasis> or
  417. <emphasis>useSsl = true</emphasis> you may find that the LDAP client generates an
  418. error claiming that it cannot validate the server's certificate. Assuming the PHP
  419. LDAP extension is ultimately linked to the OpenLDAP client libraries, to resolve
  420. this issue you can set "<emphasis>TLS_REQCERT never</emphasis>" in the OpenLDAP
  421. client <filename>ldap.conf</filename> (and restart the web server) to indicate to
  422. the OpenLDAP client library that you trust the server. Alternatively, if you are
  423. concerned that the server could be spoofed, you can export the LDAP server's root
  424. certificate and put it on the web server so that the OpenLDAP client can validate
  425. the server's identity.
  426. </para>
  427. </note>
  428. </sect2>
  429. <sect2 id="zend.auth.adapter.ldap.debugging">
  430. <title>Collecting Debugging Messages</title>
  431. <para>
  432. <classname>Zend_Auth_Adapter_Ldap</classname> collects debugging information within its
  433. <methodname>authenticate()</methodname> method. This information is stored in the
  434. <classname>Zend_Auth_Result</classname> object as messages. The array returned by
  435. <classname>Zend_Auth_Result::getMessages()</classname> is described as follows
  436. <table id="zend.auth.adapter.ldap.debugging.table">
  437. <title>Debugging Messages</title>
  438. <tgroup cols="2">
  439. <thead>
  440. <row>
  441. <entry>Messages Array Index</entry>
  442. <entry>Description</entry>
  443. </row>
  444. </thead>
  445. <tbody>
  446. <row>
  447. <entry>Index 0</entry>
  448. <entry>
  449. A generic, user-friendly message that is suitable for displaying to users
  450. (e.g., "Invalid credentials"). If the authentication is successful, this
  451. string is empty.
  452. </entry>
  453. </row>
  454. <row>
  455. <entry>Index 1</entry>
  456. <entry>
  457. A more detailed error message that is not suitable to be displayed to users
  458. but should be logged for the benefit of server operators. If the
  459. authentication is successful, this string is empty.
  460. </entry>
  461. </row>
  462. <row>
  463. <entry>Indexes 2 and higher</entry>
  464. <entry>
  465. All log messages in order starting at index 2.
  466. </entry>
  467. </row>
  468. </tbody>
  469. </tgroup>
  470. </table>
  471. In practice, index 0 should be displayed to the user (e.g., using the FlashMessenger
  472. helper), index 1 should be logged and, if debugging information is being collected,
  473. indexes 2 and higher could be logged as well (although the final message always includes
  474. the string from index 1).
  475. </para>
  476. </sect2>
  477. <sect2 id="zend.auth.adapter.ldap.options-common-server-specific">
  478. <title>Common Options for Specific Servers</title>
  479. <sect3 id="zend.auth.adapter.ldap.options-common-server-specific.active-directory">
  480. <title>Options for Active Directory</title>
  481. <para>
  482. For ADS, the following options are noteworthy:
  483. <table id="zend.auth.adapter.ldap.options-common-server-specific.active-directory.table">
  484. <title>Options for Active Directory</title>
  485. <tgroup cols="2">
  486. <thead>
  487. <row>
  488. <entry>Name</entry>
  489. <entry>Additional Notes</entry>
  490. </row>
  491. </thead>
  492. <tbody>
  493. <row>
  494. <entry><emphasis>host</emphasis></entry>
  495. <entry>
  496. As with all servers, this option is required.
  497. </entry>
  498. </row>
  499. <row>
  500. <entry><emphasis>useStartTls</emphasis></entry>
  501. <entry>
  502. For the sake of security, this should be <constant>TRUE</constant> if
  503. the server has the necessary certificate installed.
  504. </entry>
  505. </row>
  506. <row>
  507. <entry><emphasis>useSsl</emphasis></entry>
  508. <entry>
  509. Possibly used as an alternative to <emphasis>useStartTls</emphasis> (see
  510. above).
  511. </entry>
  512. </row>
  513. <row>
  514. <entry><emphasis>baseDn</emphasis></entry>
  515. <entry>
  516. As with all servers, this option is required. By default AD places all
  517. user accounts under the <emphasis>Users</emphasis> container (e.g.,
  518. <emphasis>CN=Users,DC=foo,DC=net</emphasis>), but the default is not
  519. common in larger organizations. Ask your AD administrator what the best
  520. DN for accounts for your application would be.
  521. </entry>
  522. </row>
  523. <row>
  524. <entry><emphasis>accountCanonicalForm</emphasis></entry>
  525. <entry>
  526. You almost certainly want this to be 3 for backslash style names (e.g.,
  527. <emphasis>FOO\alice</emphasis>), which are most familiar to Windows
  528. users. You should <emphasis>not</emphasis> use the unqualified form 2
  529. (e.g., <emphasis>alice</emphasis>), as this may grant access to your
  530. application to users with the same username in other trusted domains
  531. (e.g., <emphasis>BAR\alice</emphasis> and <emphasis>FOO\alice</emphasis>
  532. will be treated as the same user). (See also note below.)
  533. </entry>
  534. </row>
  535. <row>
  536. <entry><emphasis>accountDomainName</emphasis></entry>
  537. <entry>
  538. This is required with AD unless
  539. <emphasis>accountCanonicalForm</emphasis> 2 is used, which, again, is
  540. discouraged.
  541. </entry>
  542. </row>
  543. <row>
  544. <entry><emphasis>accountDomainNameShort</emphasis></entry>
  545. <entry>
  546. The NetBIOS name of the domain that users are in and for which the AD
  547. server is an authority. This is required if the backslash style
  548. <emphasis>accountCanonicalForm</emphasis> is used.
  549. </entry>
  550. </row>
  551. </tbody>
  552. </tgroup>
  553. </table>
  554. </para>
  555. <note>
  556. <para>
  557. Technically there should be no danger of accidental cross-domain authentication
  558. with the current <classname>Zend_Auth_Adapter_Ldap</classname> implementation,
  559. since server domains are explicitly checked, but this may not be true of a
  560. future implementation that discovers the domain at runtime, or if an alternative
  561. adapter is used (e.g., Kerberos). In general, account name ambiguity is known to
  562. be the source of security issues, so always try to use qualified account names.
  563. </para>
  564. </note>
  565. </sect3>
  566. <sect3 id="zend.auth.adapter.ldap.options-common-server-specific.openldap">
  567. <title>Options for OpenLDAP</title>
  568. <para>
  569. For OpenLDAP or a generic LDAP server using a typical posixAccount style schema, the
  570. following options are noteworthy:
  571. <table id="zend.auth.adapter.ldap.options-common-server-specific.openldap.table">
  572. <title>Options for OpenLDAP</title>
  573. <tgroup cols="2">
  574. <thead>
  575. <row>
  576. <entry>Name</entry>
  577. <entry>Additional Notes</entry>
  578. </row>
  579. </thead>
  580. <tbody>
  581. <row>
  582. <entry><emphasis>host</emphasis></entry>
  583. <entry>
  584. As with all servers, this option is required.
  585. </entry>
  586. </row>
  587. <row>
  588. <entry><emphasis>useStartTls</emphasis></entry>
  589. <entry>
  590. For the sake of security, this should be <constant>TRUE</constant> if
  591. the server has the necessary certificate installed.
  592. </entry>
  593. </row>
  594. <row>
  595. <entry><emphasis>useSsl</emphasis></entry>
  596. <entry>
  597. Possibly used as an alternative to <emphasis>useStartTls</emphasis> (see
  598. above).
  599. </entry>
  600. </row>
  601. <row>
  602. <entry><emphasis>username</emphasis></entry>
  603. <entry>
  604. Required and must be a DN, as OpenLDAP requires that usernames be in DN
  605. form when performing a bind. Try to use an unprivileged account.
  606. </entry>
  607. </row>
  608. <row>
  609. <entry><emphasis>password</emphasis></entry>
  610. <entry>
  611. The password corresponding to the username above, but this may be
  612. omitted if the LDAP server permits an anonymous binding to query user
  613. accounts.
  614. </entry>
  615. </row>
  616. <row>
  617. <entry><emphasis>bindRequiresDn</emphasis></entry>
  618. <entry>
  619. Required and must be <constant>TRUE</constant>, as OpenLDAP requires
  620. that usernames be in DN form when performing a bind.
  621. </entry>
  622. </row>
  623. <row>
  624. <entry><emphasis>baseDn</emphasis></entry>
  625. <entry>
  626. As with all servers, this option is required and indicates the DN under
  627. which all accounts being authenticated are located.
  628. </entry>
  629. </row>
  630. <row>
  631. <entry><emphasis>accountCanonicalForm</emphasis></entry>
  632. <entry>
  633. Optional, but the default value is 4 (principal style names like
  634. <emphasis>alice@foo.net</emphasis>), which may not be ideal if your
  635. users are used to backslash style names (e.g.,
  636. <emphasis>FOO\alice</emphasis>). For backslash style names use value 3.
  637. </entry>
  638. </row>
  639. <row>
  640. <entry><emphasis>accountDomainName</emphasis></entry>
  641. <entry>
  642. Required unless you're using <emphasis>accountCanonicalForm</emphasis>
  643. 2, which is not recommended.
  644. </entry>
  645. </row>
  646. <row>
  647. <entry><emphasis>accountDomainNameShort</emphasis></entry>
  648. <entry>
  649. If AD is not also being used, this value is not required. Otherwise, if
  650. <emphasis>accountCanonicalForm</emphasis> 3 is used, this option is
  651. required and should be a short name that corresponds adequately to the
  652. <emphasis>accountDomainName</emphasis> (e.g., if your
  653. <emphasis>accountDomainName</emphasis> is
  654. <emphasis>foo.net</emphasis>, a good
  655. <emphasis>accountDomainNameShort</emphasis> value might be
  656. <emphasis>FOO</emphasis>).
  657. </entry>
  658. </row>
  659. </tbody>
  660. </tgroup>
  661. </table>
  662. </para>
  663. </sect3>
  664. </sect2>
  665. </sect1>
  666. <!--
  667. vim:se ts=4 sw=4 et:
  668. -->