Zend_Auth.xml 18 KB

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