1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 20763 -->
4 <sect1 id="zend.auth.introduction">
5 <title>Introducción</title>
7 <classname>Zend_Auth</classname> provee una <acronym>API</acronym> para
8 autenticación e incluye adaptadores concretos de autenticación para
9 escenarios de casos de uso común. </para>
11 <classname>Zend_Auth</classname> es concerniente sólo con
12 <emphasis>autenticación</emphasis> y no con
13 <emphasis>autorización</emphasis> . Autenticación es vagamente
14 definido como: determinar si una entidad realmente es lo que pretende
15 ser (o sea, identificación), basandose en un grupo de credenciales.
16 Autorización, el proceso de decidir si se permite a una entidad: acceso
17 a, o el realizar operaciones en, otras entidades esta fuera del alcance
18 de <classname>Zend_Auth</classname> . Para más información sobre
19 autorización y control de acceso con Zend Framework, por favor vea <link
20 linkend="zend.acl">Zend_Acl</link> . </para>
22 <para> La clase <classname>Zend_Auth</classname> implementa el patrón
23 Singleton - sólo una instancia de la clase está disponible - a
24 través de su método estático <methodname>getInstance()</methodname>
25 . Esto significa que usar el operador <emphasis>new</emphasis> y la
26 keyword <emphasis>clone</emphasis> no va a funcionar con la clase
27 <classname>Zend_Auth</classname> : use
28 <methodname>Zend_Auth::getInstance()</methodname> en su lugar.
31 <sect2 id="zend.auth.introduction.adapters">
33 <title>Adaptadores</title>
35 <para> Un adaptador <classname>Zend_Auth</classname> es usado para
36 autenticar en contra de un tipo particular de servicio de
37 autenticación, como <acronym>LDAP</acronym> ,
38 <acronym>RDBMS</acronym> , o almacenamiento basado en ficheros.
39 Diferentes adaptadores pueden tener opciones y compotamientos muy
40 diferentes, pero algunas cosas básicas son comunes entre los
41 adaptadores de autenticación. Por ejemplo, aceptar credenciales de
42 autenticación (incluyendo una identidad supuesta), realizar
43 consultas ante el servicio de autenticación, y regresar resultados,
44 son comunes para los adaptadores <classname>Zend_Auth</classname> . </para>
46 <para> Cada clase adaptadora <classname>Zend_Auth</classname> implementa
47 <classname>Zend_Auth_Adapter_Interface</classname> . Esta
48 interface define un metodo, <methodname>authenticate()</methodname>
49 , que la clase adaptadora debe implementar para realizar una
50 peticion de autenticación. Cada clase adaptadora debe ser preparada
51 antes de llamar a <methodname>authenticate()</methodname> . Esta
52 preparación del adaptador incluye la creación de credenciales (p.ej.
53 nombre de usuario y contraseña) y la definición de valores para
54 opciones de configuración especificos del adaptador, como valores de
55 coneccion a base de datos para un adaptador de tabla de base de
58 <para>El siguente ejemplo es un adaptador de autenticación que requiere
59 que un nombre de usuario y contraseña sean especificados para la
60 autenticación. Otros detalles, como la forma de realizar peticiones
61 al servicio de autenticación, han sido omitídos por brevedad: </para>
63 <programlisting language="php"><![CDATA[
64 class MyAuthAdapter implements Zend_Auth_Adapter_Interface
67 * Establece nombre de usuario y contraseña para autenticacón
71 public function __construct($username, $password)
77 * Realiza un intento de autenticación
79 * @throws Zend_Auth_Adapter_Exception Si la autenticación no puede
81 * @return Zend_Auth_Result
83 public function authenticate()
90 <para> Como se ha indicado en su docblock,
91 <methodname>authenticate()</methodname> debe regresar una
92 instancia de <classname>Zend_Auth_Result</classname> (o de una clase
93 derivada de <classname>Zend_Auth_Result</classname> ). Si por alguna
94 razón es imposible realizar una petición de autenticación,
95 <methodname>authenticate()</methodname> debería arrojar una
96 excepción que se derive de
97 <classname>Zend_Auth_Adapter_Exception</classname> . </para>
101 <sect2 id="zend.auth.introduction.results">
103 <title>Resultados</title>
105 <para> Los adaptadores <classname>Zend_Auth</classname> regresan una
106 instancia de <classname>Zend_Auth_Result</classname> con
107 <methodname>authenticate()</methodname> para representar el
108 resultado de un intento de autenticación. Los adaptadores llenan el
109 objeto <classname>Zend_Auth_Result</classname> en cuanto se
110 construye, así que los siguientes cuatro métodos proveen un grupo
111 básico de operaciones "frente al usuario" que son comunes a los
112 resultados de adaptadores Zend_Auth: </para>
117 <methodname>isValid()</methodname> - regresa true si y solo
118 si el resultado representa un intento de autenticación
123 <methodname>getCode()</methodname> - regresa una constante
124 identificadora <classname>Zend_Auth_Result</classname> para
125 determinar el tipo de fallo en la autenticación o si ha sido
126 exitosa. Este puede ser usado en situaciones cuando el
127 desarrollador desea distinguir entre varios tipos de
128 resultados de autenticación. Esto permite a los
129 desarrolladores, por ejemplo, mantener estadísticas
130 detalladas de los resultados de autenticación. Otro uso de
131 esta característica es: proporcionar al usuario mensajes
132 específicos detallados por razones de usabilidad, aunque los
133 desarrolladores son exhortados a considerar el riesgo de
134 proporcionar tales detalles a los usuarios, en vez de un
135 mensaje general de fallo en la autenticación. Para más
136 información, vea las siguientes notas: </para>
140 <methodname>getIdentity()</methodname> - regresa la
141 identidad del intento de autenticación </para>
145 <methodname>getMessages()</methodname> - regresa un arreglo
146 de mensajes pertinentes a un fallido intento de
147 autenticación </para>
151 <para>El desarrollador podría desear ramificar basado en el tipo de
152 resultado de la autenticación a fin de realizar operaciones mas
153 específicas. Algunas operaciones que los desarrolladores podrían
154 encontrar útiles son: bloquear cuentas despues de varios intentos
155 fallidos de ingresar una contraseña, marcar una dirección IP despues
156 de que ha intentado muchas identidades no existentes, y porporcionar
157 al usuario mensajes especificos resultados de la autenticación. Los
158 siguientes codigos de resultado están disponibles: </para>
160 <programlisting language="php"><![CDATA[
161 Zend_Auth_Result::SUCCESS
162 Zend_Auth_Result::FAILURE
163 Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
164 Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
165 Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
166 Zend_Auth_Result::FAILURE_UNCATEGORIZED
169 <para>El siguiente ejemplo ilustra como un desarrollador podría
170 ramificar basado en el código resultado: </para>
171 <programlisting language="php"><![CDATA[
172 // debtri de AuthController / loginAction
173 $result = $this->_auth->authenticate($adapter);
175 switch ($result->getCode()) {
177 case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
178 /** realiza algo para identidad inexistente **/
181 case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
182 /** realiza algo para credencial invalida **/
185 case Zend_Auth_Result::SUCCESS:
186 /** realiza algo para autenticación exitosa **/
190 /** realiza algo para otras fallas **/
197 <sect2 id="zend.auth.introduction.persistence">
199 <title>Persistencia de Identidad</title>
201 <para>Autenticar una petición que incluye credenciales de autenticación
202 es util por sí mismo, pero también es importante el soportar
203 mantener la identidad autenticada sin tener que presentar las
204 credenciales de autenticación con cada petición.</para>
207 <acronym>HTTP</acronym> es un protocolo sin estado, sin embargo, se
208 han desarrollado técnicas como las cookies y sesiones a fin de
209 facilitar mantener el estado a través de multiples peticiones en
210 aplicaciones web del lado del servidor. </para>
212 <sect3 id="zend.auth.introduction.persistence.default">
214 <title>Persistencia por Defecto en la Sesión PHP</title>
216 <para> Por defecto, <classname>Zend_Auth</classname> provee
217 almacenamiento persistente de la identidad desde un intento de
218 autenticación exitoso usando la sesión <acronym>PHP</acronym> .
219 En un intento de autenticación exitoso,
220 <methodname>end_Auth::authenticate()</methodname> almacena
221 la identidad del resultado de autenticación en almacenamiento
222 persistente. A menos que se configure diferente,
223 <classname>Zend_Auth</classname> usa una clase de
224 almacenamiento llamada
225 <classname>Zend_Auth_Storage_Session</classname> , la cual,
226 a su vez usa <link linkend="zend.session">
227 <classname>Zend_Session</classname>
228 </link> . Una clase diferente podría ser utilizada mediante
229 proveer un objeto que implemente
230 <classname>Zend_Auth_Storage_Interface</classname> a
231 <methodname>Zend_Auth::setStorage()</methodname>
235 <para> Si el automático almacenamiento persistente de la
236 identidad no es apropiado para un caso en particular,
237 entonces los desarrolladores podrían dejar de usar la clase
238 <classname>Zend_Auth</classname> al mismo tiempo,
239 utilizando en su lugar una clase adaptadora directamente.
243 <example id="zend.auth.introduction.persistence.default.example">
245 <title>Modifying the Session Namespace</title>
248 <classname>Zend_Auth_Storage_Session</classname> usa un
249 espacionombre (namespace) de sesión 'Zend_Auth'. Este
250 espacio-nombre podría ser OVERRIDDEN al pasar un valor
251 diferente al contructor de
252 <classname>Zend_Auth_Storage_Session</classname> , y
253 este valor es pasado internamente al constructor de
254 <classname>Zend_Session_Namespace</classname> . Esto
255 debería ocurrir antes de que se intente la autenticación, ya
256 que <methodname>Zend_Auth::authenticate()</methodname>
257 realiza el almacenamiento automático de la identidad. </para>
259 <programlisting language="php"><![CDATA[
260 // Almacena una referencia a la instancia Singleton de Zend_Auth
261 $auth = Zend_Auth::getInstance();
263 // Usa 'unEspacionombre' en lugar de 'Zend_Auth'
264 $auth->setStorage(new Zend_Auth_Storage_Session('unEspacionombre'));
267 * @todo Set up the auth adapter, $authAdapter
270 // Autenticar, almacenando el resultado, y persistiendo la identidad en
272 $result = $auth->authenticate($authAdapter);
279 <sect3 id="zend.auth.introduction.persistence.custom">
281 <title>Implementando Almacenamiento Personalizado</title>
283 <para> En ocaciones los desarrolladores podrían necesitar usar un
284 diferente comportamiento de persistencia de identidad que el
285 provisto por <classname>Zend_Auth_Storage_Session</classname> .
286 Para esos casos los desarrolladores podrían simplemente
287 implementar <classname>Zend_Auth_Storage_Interface</classname> y
288 suplir una instancia de la clase a
289 <methodname>Zend_Auth::setStorage()</methodname> . </para>
291 <example id="zend.auth.introduction.persistence.custom.example">
293 <title>Usando una Clase de Almacenamiento Personalizada</title>
295 <para> Para poder utilizar una clase de almacenamiento
296 persistente de identidad diferente a
297 <classname>Zend_Auth_Storage_Session</classname> , el
298 desarrollador implementa
299 <classname>Zend_Auth_Storage_Interface</classname> :
301 <programlisting language="php"><![CDATA[
302 class MyStorage implements Zend_Auth_Storage_Interface
305 * Regresa true si y solo si el almacenamiento esta vacio
307 * @arroja Zend_Auth_Storage_Exception Si es imposible
308 * determinar si el almacenamiento
312 public function isEmpty()
315 * @por hacer implementación
320 * Regresa el contenido del almacenamiento
322 * El comportamiento es indefinido cuando el almacenamiento esta vacio
324 * @arroja Zend_Auth_Storage_Exception Si leer contenido de
325 * almacenamiento es imposible
328 public function read()
331 * @por hacer implementación
336 * Escribe $contents al almacenamiento
338 * @parametros mezclado $contents
339 * @arroja Zend_Auth_Storage_Exception Si escribir $contents al
340 * almacenamiento es imposible
343 public function write($contents)
346 * @por hacer implementación
351 * limpia contenidos del almacenamiento
353 * @arroja Zend_Auth_Storage_Exception Si limpiar contenidos del
354 * almacenamiento es imposible
357 public function clear()
360 * @por hacer implementación
366 <para> A fin de poder usar esta clase de almacenamiento
368 <methodname>Zend_Auth::setStorage()</methodname> es
369 invocada antes de intentar una petición de autenticación: </para>
370 <programlisting language="php"><![CDATA[
371 // Instruye Zend_Auth para usar la clase de almacenamiento personalizada
372 Zend_Auth::getInstance()->setStorage(new MyStorage());
375 * @por hacer Configurar el adaptador de autenticación, $authAdapter
378 // Autenticar, almacenando el resultado, y persistiendo la identidad
380 $result = Zend_Auth::getInstance()->authenticate($authAdapter);
389 <sect2 id="zend.auth.introduction.using">
393 <para> Hay dos formas provistas de usar adaptadores
394 <classname>Zend_Auth</classname> : </para>
397 <para> indirectamente, a través de
398 <methodname>Zend_Auth::authenticate()</methodname>
402 <para> directamente, a través del metodo
403 <methodname>authenticate()</methodname> del adaptador
408 <para> El siguiente ejemplo ilustra como usar el adaptador
409 <classname>:Zend_Auth</classname> : indirectamente, a través del
410 uso de la clase <classname>Zend_Auth</classname> :
412 <programlisting language="php"><![CDATA[
413 // Recibe una referencia a la instancia singleton de Zend_Auth
414 $auth = Zend_Auth::getInstance();
416 // Configura el adaptador de autenticación
417 $authAdapter = new MyAuthAdapter($username, $password);
419 // Intenta la autenticación, almacenando el resultado
420 $result = $auth->authenticate($authAdapter);
422 if (!$result->isValid()) {
423 // Fautenticación fallida: imprime el por que
424 foreach ($result->getMessages() as $message) {
428 // Autenticación exitosa, la identidad ($username) es almacenada
430 // $result->getIdentity() === $auth->getIdentity()
431 // $result->getIdentity() === $username
435 <para>Una vez que la autenticación ha sido intentada en una petición,
436 como en el ejemplo anterior, es fácil verificar si existe una
437 identidad autenticada exitosamente: </para>
438 <programlisting language="php"><![CDATA[
439 $auth = Zend_Auth::getInstance();
440 if ($auth->hasIdentity()) {
441 // Existe la identidad; obtenla
442 $identity = $auth->getIdentity();
446 <para> Para remover una identidad del almacenamiento persistente,
447 simplemente usa el metodo <methodname>clearIdentity()</methodname>
448 method. Comunmente esto sería usado para implementar una operación
449 "cerrar sesión" en la aplicación:
451 <programlisting language="php"><![CDATA[
452 Zend_Auth::getInstance()->clearIdentity();
455 <para> Cuando el uso automático de almacenamiento persistente es
456 inapropiado para un caso en particular, el desarrollador podría
457 simplemente omitir el uso de la clase
458 <classname>Zend_Auth</classname> , usando una clase adaptadora
459 directamente. El uso directo de una clase adaptadora implica
460 configurar y preparar un objeto adaptador y despues llamar a su
461 metodo <methodname>authenticate()</methodname> . Los detalles
462 específicos del adaptador son discutidos en la documentación de cada
463 adaptador. El siguiente ejemplo utiliza directamente
464 <classname>MyAuthAdapter</classname> : </para>
466 <programlisting language="php"><![CDATA[
467 // Configura el adaptador de autenticación
468 $authAdapter = new MyAuthAdapter($username, $password);
470 // Intenta la autenticación, almacenando el resultado
471 $result = $authAdapter->authenticate();
473 if (!$result->isValid()) {
474 // Autenticación fallida, imprime el porque
475 foreach ($result->getMessages() as $message) {
479 // Autenticación exitosa
480 // $result->getIdentity() === $username