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