Zend_Auth.xml 17 KB

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