Zend_Auth.xml 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.auth.introduction">
  4. <title>Introduction</title>
  5. <para>
  6. <classname>Zend_Auth</classname> provides an <acronym>API</acronym> for authentication and
  7. includes concrete authentication adapters for common use case scenarios.
  8. </para>
  9. <para>
  10. <classname>Zend_Auth</classname> is concerned only with <emphasis>authentication</emphasis>
  11. and not with <emphasis>authorization</emphasis>. Authentication is loosely defined as
  12. determining whether an entity actually is what it purports to be (i.e., identification),
  13. based on some set of credentials. Authorization, the process of deciding whether to allow
  14. an entity access to, or to perform operations upon, other entities is outside the scope of
  15. <classname>Zend_Auth</classname>. For more information about authorization and access
  16. control with Zend Framework, please see <link
  17. linkend="zend.acl"><classname>Zend_Acl</classname></link>.
  18. </para>
  19. <note>
  20. <para>
  21. The <classname>Zend_Auth</classname> class implements the Singleton pattern - only one
  22. instance of the class is available - through its static
  23. <methodname>getInstance()</methodname> method. This means that using the
  24. <emphasis>new</emphasis> operator and the <emphasis>clone</emphasis> keyword will not
  25. work with the <classname>Zend_Auth</classname> class; use
  26. <methodname>Zend_Auth::getInstance()</methodname> instead.
  27. </para>
  28. </note>
  29. <sect2 id="zend.auth.introduction.adapters">
  30. <title>Adapters</title>
  31. <para>
  32. A <classname>Zend_Auth</classname> adapter is used to authenticate against a particular
  33. type of authentication service, such as <acronym>LDAP</acronym>,
  34. <acronym>RDBMS</acronym>, or file-based storage. Different adapters are likely to have
  35. vastly different options and behaviors, but some basic things are common among
  36. authentication adapters. For example, accepting authentication credentials (including a
  37. purported identity), performing queries against the authentication service, and
  38. returning results are common to <classname>Zend_Auth</classname> adapters.
  39. </para>
  40. <para>
  41. Each <classname>Zend_Auth</classname> adapter class implements
  42. <classname>Zend_Auth_Adapter_Interface</classname>. This interface defines one method,
  43. <methodname>authenticate()</methodname>, that an adapter class must implement for
  44. performing an authentication query. Each adapter class must be prepared prior to
  45. calling <methodname>authenticate()</methodname>. Such adapter preparation includes
  46. setting up credentials (e.g., username and password) and defining values for
  47. adapter-specific configuration options, such as database connection settings for a
  48. database table adapter.
  49. </para>
  50. <para>
  51. The following is an example authentication adapter that requires a username and
  52. password to be set for authentication. Other details, such as how the authentication
  53. service is queried, have been omitted for brevity:
  54. </para>
  55. <programlisting language="php"><![CDATA[
  56. class MyAuthAdapter implements Zend_Auth_Adapter_Interface
  57. {
  58. /**
  59. * Sets username and password for authentication
  60. *
  61. * @return void
  62. */
  63. public function __construct($username, $password)
  64. {
  65. // ...
  66. }
  67. /**
  68. * Performs an authentication attempt
  69. *
  70. * @throws Zend_Auth_Adapter_Exception If authentication cannot
  71. * be performed
  72. * @return Zend_Auth_Result
  73. */
  74. public function authenticate()
  75. {
  76. // ...
  77. }
  78. }
  79. ]]></programlisting>
  80. <para>
  81. As indicated in its docblock, <methodname>authenticate()</methodname> must return an
  82. instance of <classname>Zend_Auth_Result</classname> (or of a class derived from
  83. <classname>Zend_Auth_Result</classname>). If for some reason performing an
  84. authentication query is impossible, <methodname>authenticate()</methodname> should
  85. throw an exception that derives from
  86. <classname>Zend_Auth_Adapter_Exception</classname>.
  87. </para>
  88. </sect2>
  89. <sect2 id="zend.auth.introduction.results">
  90. <title>Results</title>
  91. <para>
  92. <classname>Zend_Auth</classname> adapters return an instance of
  93. <classname>Zend_Auth_Result</classname> with <methodname>authenticate()</methodname> in
  94. order to represent the results of an authentication attempt. Adapters populate the
  95. <classname>Zend_Auth_Result</classname> object upon construction, so that the following
  96. four methods provide a basic set of user-facing operations that are common to the
  97. results of <classname>Zend_Auth</classname> adapters:
  98. </para>
  99. <itemizedlist>
  100. <listitem>
  101. <para>
  102. <methodname>isValid()</methodname> - returns <constant>TRUE</constant> if and
  103. only if the result represents a successful authentication attempt
  104. </para>
  105. </listitem>
  106. <listitem>
  107. <para>
  108. <methodname>getCode()</methodname> - returns a
  109. <classname>Zend_Auth_Result</classname> constant identifier for determining
  110. the type of authentication failure or whether success has occurred. This
  111. may be used in situations where the developer wishes to distinguish among
  112. several authentication result types. This allows developers to maintain
  113. detailed authentication result statistics, for example. Another use of this
  114. feature is to provide specific, customized messages to users for usability
  115. reasons, though developers are encouraged to consider the risks of
  116. providing such detailed reasons to users, instead of a general
  117. authentication failure message. For more information, see the notes below.
  118. </para>
  119. </listitem>
  120. <listitem>
  121. <para>
  122. <methodname>getIdentity()</methodname> - returns the identity of the
  123. authentication attempt
  124. </para>
  125. </listitem>
  126. <listitem>
  127. <para>
  128. <methodname>getMessages()</methodname> - returns an array of messages
  129. regarding a failed authentication attempt
  130. </para>
  131. </listitem>
  132. </itemizedlist>
  133. <para>
  134. A developer may wish to branch based on the type of authentication result in order to
  135. perform more specific operations. Some operations developers might find useful are
  136. locking accounts after too many unsuccessful password attempts, flagging an IP address
  137. after too many nonexistent identities are attempted, and providing specific, customized
  138. authentication result messages to the user. The following result codes are available:
  139. </para>
  140. <programlisting language="php"><![CDATA[
  141. Zend_Auth_Result::SUCCESS
  142. Zend_Auth_Result::FAILURE
  143. Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
  144. Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
  145. Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
  146. Zend_Auth_Result::FAILURE_UNCATEGORIZED
  147. ]]></programlisting>
  148. <para>
  149. The following example illustrates how a developer may branch on the result code:
  150. </para>
  151. <programlisting language="php"><![CDATA[
  152. // inside of AuthController / loginAction
  153. $result = $this->_auth->authenticate($adapter);
  154. switch ($result->getCode()) {
  155. case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
  156. /** do stuff for nonexistent identity **/
  157. break;
  158. case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
  159. /** do stuff for invalid credential **/
  160. break;
  161. case Zend_Auth_Result::SUCCESS:
  162. /** do stuff for successful authentication **/
  163. break;
  164. default:
  165. /** do stuff for other failure **/
  166. break;
  167. }
  168. ]]></programlisting>
  169. </sect2>
  170. <sect2 id="zend.auth.introduction.persistence">
  171. <title>Identity Persistence</title>
  172. <para>
  173. Authenticating a request that includes authentication credentials is useful per se, but
  174. it is also important to support maintaining the authenticated identity without having
  175. to present the authentication credentials with each request.
  176. </para>
  177. <para>
  178. <acronym>HTTP</acronym> is a stateless protocol, however, and techniques such as
  179. cookies and sessions have been developed in order to facilitate maintaining state
  180. across multiple requests in server-side web applications.
  181. </para>
  182. <sect3 id="zend.auth.introduction.persistence.default">
  183. <title>Default Persistence in the PHP Session</title>
  184. <para>
  185. By default, <classname>Zend_Auth</classname> provides persistent storage of the
  186. identity from a successful authentication attempt using the <acronym>PHP</acronym>
  187. session. Upon a successful authentication attempt,
  188. <methodname>Zend_Auth::authenticate()</methodname> stores the identity from the
  189. authentication result into persistent storage. Unless configured otherwise,
  190. <classname>Zend_Auth</classname> uses a storage class named
  191. <classname>Zend_Auth_Storage_Session</classname>, which, in turn, uses
  192. <link linkend="zend.session"><classname>Zend_Session</classname></link>. A custom
  193. class may instead be used by providing an object that implements
  194. <classname>Zend_Auth_Storage_Interface</classname> to
  195. <methodname>Zend_Auth::setStorage()</methodname>.
  196. </para>
  197. <note>
  198. <para>
  199. If automatic persistent storage of the identity is not appropriate for a
  200. particular use case, then developers may forgot using the
  201. <classname>Zend_Auth</classname> class altogether, instead using an adapter
  202. class directly.
  203. </para>
  204. </note>
  205. <example id="zend.auth.introduction.persistence.default.example">
  206. <title>Modifying the Session Namespace</title>
  207. <para>
  208. <classname>Zend_Auth_Storage_Session</classname> uses a session namespace of
  209. '<classname>Zend_Auth</classname>'. This namespace may be overridden by passing
  210. a different value to the constructor of
  211. <classname>Zend_Auth_Storage_Session</classname>, and this value is internally
  212. passed along to the constructor of
  213. <classname>Zend_Session_Namespace</classname>. This should occur before
  214. authentication is attempted, since
  215. <methodname>Zend_Auth::authenticate()</methodname> performs the automatic
  216. storage of the identity.
  217. </para>
  218. <programlisting language="php"><![CDATA[
  219. // Save a reference to the Singleton instance of Zend_Auth
  220. $auth = Zend_Auth::getInstance();
  221. // Use 'someNamespace' instead of 'Zend_Auth'
  222. $auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));
  223. /**
  224. * @todo Set up the auth adapter, $authAdapter
  225. */
  226. // Authenticate, saving the result, and persisting the identity on
  227. // success
  228. $result = $auth->authenticate($authAdapter);
  229. ]]></programlisting>
  230. </example>
  231. </sect3>
  232. <sect3 id="zend.auth.introduction.persistence.custom">
  233. <title>Implementing Customized Storage</title>
  234. <para>
  235. Sometimes developers may need to use a different identity storage mechanism than
  236. that provided by <classname>Zend_Auth_Storage_Session</classname>. For such cases
  237. developers may simply implement <classname>Zend_Auth_Storage_Interface</classname>
  238. and supply an instance of the class to
  239. <methodname>Zend_Auth::setStorage()</methodname>.
  240. </para>
  241. <example id="zend.auth.introduction.persistence.custom.example">
  242. <title>Using a Custom Storage Class</title>
  243. <para>
  244. In order to use an identity persistence storage class other than
  245. <classname>Zend_Auth_Storage_Session</classname>, a developer implements
  246. <classname>Zend_Auth_Storage_Interface</classname>:
  247. </para>
  248. <programlisting language="php"><![CDATA[
  249. class MyStorage implements Zend_Auth_Storage_Interface
  250. {
  251. /**
  252. * Returns true if and only if storage is empty
  253. *
  254. * @throws Zend_Auth_Storage_Exception If it is impossible to
  255. * determine whether storage
  256. * is empty
  257. * @return boolean
  258. */
  259. public function isEmpty()
  260. {
  261. /**
  262. * @todo implementation
  263. */
  264. }
  265. /**
  266. * Returns the contents of storage
  267. *
  268. * Behavior is undefined when storage is empty.
  269. *
  270. * @throws Zend_Auth_Storage_Exception If reading contents from
  271. * storage is impossible
  272. * @return mixed
  273. */
  274. public function read()
  275. {
  276. /**
  277. * @todo implementation
  278. */
  279. }
  280. /**
  281. * Writes $contents to storage
  282. *
  283. * @param mixed $contents
  284. * @throws Zend_Auth_Storage_Exception If writing $contents to
  285. * storage is impossible
  286. * @return void
  287. */
  288. public function write($contents)
  289. {
  290. /**
  291. * @todo implementation
  292. */
  293. }
  294. /**
  295. * Clears contents from storage
  296. *
  297. * @throws Zend_Auth_Storage_Exception If clearing contents from
  298. * storage is impossible
  299. * @return void
  300. */
  301. public function clear()
  302. {
  303. /**
  304. * @todo implementation
  305. */
  306. }
  307. }
  308. ]]></programlisting>
  309. <para>
  310. In order to use this custom storage class,
  311. <methodname>Zend_Auth::setStorage()</methodname> is invoked before an
  312. authentication query is attempted:
  313. </para>
  314. <programlisting language="php"><![CDATA[
  315. // Instruct Zend_Auth to use the custom storage class
  316. Zend_Auth::getInstance()->setStorage(new MyStorage());
  317. /**
  318. * @todo Set up the auth adapter, $authAdapter
  319. */
  320. // Authenticate, saving the result, and persisting the identity on
  321. // success
  322. $result = Zend_Auth::getInstance()->authenticate($authAdapter);
  323. ]]></programlisting>
  324. </example>
  325. </sect3>
  326. </sect2>
  327. <sect2 id="zend.auth.introduction.using">
  328. <title>Usage</title>
  329. <para>
  330. There are two provided ways to use <classname>Zend_Auth</classname> adapters:
  331. </para>
  332. <orderedlist>
  333. <listitem>
  334. <para>
  335. indirectly, through <methodname>Zend_Auth::authenticate()</methodname>
  336. </para>
  337. </listitem>
  338. <listitem>
  339. <para>
  340. directly, through the adapter's <methodname>authenticate()</methodname> method
  341. </para>
  342. </listitem>
  343. </orderedlist>
  344. <para>
  345. The following example illustrates how to use a <classname>Zend_Auth</classname> adapter
  346. indirectly, through the use of the <classname>Zend_Auth</classname> class:
  347. </para>
  348. <programlisting language="php"><![CDATA[
  349. // Get a reference to the singleton instance of Zend_Auth
  350. $auth = Zend_Auth::getInstance();
  351. // Set up the authentication adapter
  352. $authAdapter = new MyAuthAdapter($username, $password);
  353. // Attempt authentication, saving the result
  354. $result = $auth->authenticate($authAdapter);
  355. if (!$result->isValid()) {
  356. // Authentication failed; print the reasons why
  357. foreach ($result->getMessages() as $message) {
  358. echo "$message\n";
  359. }
  360. } else {
  361. // Authentication succeeded; the identity ($username) is stored
  362. // in the session
  363. // $result->getIdentity() === $auth->getIdentity()
  364. // $result->getIdentity() === $username
  365. }
  366. ]]></programlisting>
  367. <para>
  368. Once authentication has been attempted in a request, as in the above example, it is a
  369. simple matter to check whether a successfully authenticated identity exists:
  370. </para>
  371. <programlisting language="php"><![CDATA[
  372. $auth = Zend_Auth::getInstance();
  373. if ($auth->hasIdentity()) {
  374. // Identity exists; get it
  375. $identity = $auth->getIdentity();
  376. }
  377. ]]></programlisting>
  378. <para>
  379. To remove an identity from persistent storage, simply use the
  380. <methodname>clearIdentity()</methodname> method. This typically would be used for
  381. implementing an application "logout" operation:
  382. </para>
  383. <programlisting language="php"><![CDATA[
  384. Zend_Auth::getInstance()->clearIdentity();
  385. ]]></programlisting>
  386. <para>
  387. When the automatic use of persistent storage is inappropriate for a particular use
  388. case, a developer may simply bypass the use of the <classname>Zend_Auth</classname>
  389. class, using an adapter class directly. Direct use of an adapter class involves
  390. configuring and preparing an adapter object and then calling its
  391. <methodname>authenticate()</methodname> method. Adapter-specific details are discussed
  392. in the documentation for each adapter. The following example directly utilizes
  393. <classname>MyAuthAdapter</classname>:
  394. </para>
  395. <programlisting language="php"><![CDATA[
  396. // Set up the authentication adapter
  397. $authAdapter = new MyAuthAdapter($username, $password);
  398. // Attempt authentication, saving the result
  399. $result = $authAdapter->authenticate();
  400. if (!$result->isValid()) {
  401. // Authentication failed; print the reasons why
  402. foreach ($result->getMessages() as $message) {
  403. echo "$message\n";
  404. }
  405. } else {
  406. // Authentication succeeded
  407. // $result->getIdentity() === $username
  408. }
  409. ]]></programlisting>
  410. </sect2>
  411. </sect1>
  412. <!--
  413. vim:se ts=4 sw=4 et:
  414. -->