Zend_Auth.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <sect1 id="zend.auth.introduction">
  3. <title>Introducción</title>
  4. <para>
  5. Zend_Auth provee una API para autenticación e incluye adaptadores concretos de autenticación para
  6. escenarios de casos de uso común.
  7. </para>
  8. <para>
  9. Zend_Auth es concerniente sólo con <emphasis role="strong">autenticación</emphasis> y no con
  10. <emphasis role="strong">autorización</emphasis>. Autenticación es vagamente definido como: determinar
  11. si una entidad realmente es lo que pretende ser (o sea, identificación), basandose en un grupo de
  12. credenciales. Autorización, el proceso de decidir si se permite a una entidad: acceso a, o el
  13. realizar operaciones en, otras entidades esta fuera del alcance de Zend_Auth. Para más información sobre
  14. autorización y control de acceso con Zend Framework, por favor vea
  15. <link linkend="zend.acl">Zend_Acl</link>.
  16. </para>
  17. <note>
  18. <para>
  19. La clase <code>Zend_Auth</code> implementa el patrón Singleton - sólo una instancia de la clase está
  20. disponible - a través de su método estático <code>getInstance()</code>. Esto significa que usar el operador <code>new</code>
  21. y la keyword <code>clone</code> no va a funcionar con la clase <code>Zend_Auth</code> : use
  22. <code>Zend_Auth::getInstance()</code> en su lugar.
  23. </para>
  24. </note>
  25. <sect2 id="zend.auth.introduction.adapters">
  26. <title>Adaptadores</title>
  27. <para>
  28. Un adaptador Zend_Auth es usado para autenticar en contra de un tipo particular de servicio de autenticación,
  29. como LDAP, RDBMS, o almacenamiento basado en ficheros. Diferentes adaptadores pueden tener opciones y compotamientos
  30. muy diferentes, pero algunas cosas básicas son comunes entre los adaptadores de autenticación. Por ejemplo,
  31. aceptar credenciales de autenticación (incluyendo una identidad supuesta), realizar consultas ante el
  32. servicio de autenticación, y regresar resultados, son comunes para los adaptadores Zend_Auth.
  33. </para>
  34. <para>
  35. Cada clase adaptadora Zend_Auth implementa <code>Zend_Auth_Adapter_Interface</code>. Esta interface define un
  36. metodo, <code>authenticate()</code>, que la clase adaptadora debe implementar para realizar una peticion de
  37. autenticación. Cada clase adaptadora debe ser preparada antes de llamar a <code>authenticate()</code>. Esta preparación
  38. del adaptador incluye la creación de credenciales (p.ej. nombre de usuario y contraseña) y la definición de valores para opciones
  39. de configuración especificos del adaptador, como valores de coneccion a base de datos para un adaptador de tabla de base de datos.
  40. </para>
  41. <para>
  42. El siguente ejemplo es un adaptador de autenticación que requiere que un nombre de usuario y contraseña sean especificados
  43. para la autenticación. Otros detalles, como la forma de realizar peticiones al servicio de autenticación, han sido
  44. omitídos por brevedad:
  45. <programlisting role="php"><![CDATA[
  46. class MyAuthAdapter implements Zend_Auth_Adapter_Interface
  47. {
  48. /**
  49. * Establece nombre de usuario y contraseña para autenticacón
  50. *
  51. * @return void
  52. */
  53. public function __construct($username, $password)
  54. {
  55. // ...
  56. }
  57. /**
  58. * Realiza un intento de autenticación
  59. *
  60. * @throws Zend_Auth_Adapter_Exception Si la autenticación no puede
  61. * ser realizada
  62. * @return Zend_Auth_Result
  63. */
  64. public function authenticate()
  65. {
  66. // ...
  67. }
  68. }
  69. ]]>
  70. </programlisting>
  71. Como se ha indicado en su docblock, <code>authenticate()</code> debe regresar una instancia de
  72. <code>Zend_Auth_Result</code> (o de una clase derivada de <code>Zend_Auth_Result</code>). Si por alguna
  73. razón es imposible realizar una petición de autenticación, <code>authenticate()</code> debería arrojar
  74. una excepción que se derive de <code>Zend_Auth_Adapter_Exception</code>.
  75. </para>
  76. </sect2>
  77. <sect2 id="zend.auth.introduction.results">
  78. <title>Resultados</title>
  79. <para>
  80. Los adaptadores Zend_Auth regresan una instancia de <code>Zend_Auth_Result</code> con
  81. <code>authenticate()</code> para representar el resultado de un intento de autenticación. Los adaptadores
  82. llenan el objeto <code>Zend_Auth_Result</code> en cuanto se construye, así que los siguientes cuatro métodos
  83. proveen un grupo básico de operaciones "frente al usuario" que son comunes a los resultados de adaptadores Zend_Auth:
  84. <itemizedlist>
  85. <listitem>
  86. <para>
  87. <code>isValid()</code> - regresa true si y solo si el resultado representa un
  88. intento de autenticación exitoso
  89. </para>
  90. </listitem>
  91. <listitem>
  92. <para>
  93. <code>getCode()</code> - regresa una constante identificadora <code>Zend_Auth_Result</code> para
  94. determinar el tipo de fallo en la autenticación o si ha sido exitosa. Este puede ser usado
  95. en situaciones cuando el desarrollador desea distinguir entre varios tipos de resultados
  96. de autenticación. Esto permite a los desarrolladores, por ejemplo, mantener estadísticas
  97. detalladas de los resultados de autenticación. Otro uso de esta característica es: proporcionar
  98. al usuario mensajes específicos detallados por razones de usabilidad, aunque los desarrolladores
  99. son exhortados a considerar el riesgo de proporcionar tales detalles a los usuarios, en vez de
  100. un mensaje general de fallo en la autenticación. Para más información, vea las siguientes notas:
  101. </para>
  102. </listitem>
  103. <listitem>
  104. <para>
  105. <code>getIdentity()</code> - regresa la identidad del intento de autenticación
  106. </para>
  107. </listitem>
  108. <listitem>
  109. <para>
  110. <code>getMessages()</code> - regresa un arreglo de mensajes pertinentes a un fallido
  111. intento de autenticación
  112. </para>
  113. </listitem>
  114. </itemizedlist>
  115. </para>
  116. <para>
  117. El desarrollador podría desear ramificar basado en el tipo de resultado de la autenticación a fin de
  118. realizar operaciones mas específicas. Algunas operaciones que los desarrolladores podrían encontrar útiles
  119. son: bloquear cuentas despues de varios intentos fallidos de ingresar una contraseña, marcar una dirección IP
  120. despues de que ha intentado muchas identidades no existentes, y porporcionar al usuario mensajes especificos
  121. resultados de la autenticación. Los siguientes codigos de resultado están disponibles:
  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. ]]>
  130. </programlisting>
  131. </para>
  132. <para>
  133. El siguiente ejemplo ilustra como un desarrollador podría ramificar basado en el código resultado:
  134. <programlisting role="php"><![CDATA[
  135. // debtri de AuthController / loginAction
  136. $result = $this->_auth->authenticate($adapter);
  137. switch ($result->getCode()) {
  138. case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
  139. /** realiza algo para identidad inexistente **/
  140. break;
  141. case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
  142. /** realiza algo para credencial invalida **/
  143. break;
  144. case Zend_Auth_Result::SUCCESS:
  145. /** realiza algo para autenticación exitosa **/
  146. break;
  147. default:
  148. /** realiza algo para otras fallas **/
  149. break;
  150. }
  151. ]]>
  152. </programlisting>
  153. </para>
  154. </sect2>
  155. <sect2 id="zend.auth.introduction.persistence">
  156. <title>Persistencia de Identidad</title>
  157. <para>
  158. Autenticar una petición que incluye credenciales de autenticación es util por sí mismo, pero también
  159. es importante el soportar mantener la identidad autenticada sin tener que presentar las credenciales
  160. de autenticación con cada petición.
  161. </para>
  162. <para>
  163. HTTP es un protocolo sin estado, sin embargo, se han desarrollado técnicas como las cookies y sesiones
  164. a fin de facilitar mantener el estado a través de multiples peticiones en aplicaciones web del lado del servidor.
  165. </para>
  166. <sect3 id="zend.auth.introduction.persistence.default">
  167. <title>Persistencia por Defecto en la Sesión PHP</title>
  168. <para>
  169. Por defecto, <code>Zend_Auth</code> provee almacenamiento persistente de la identidad desde un intento
  170. de autenticación exitoso usando la sesión PHP. En un intento de autenticación exitoso,
  171. <code>Zend_Auth::authenticate()</code> almacena la identidad del resultado de autenticación en
  172. almacenamiento persistente. A menos que se configure diferente, <code>Zend_Auth</code> usa una clase de
  173. almacenamiento llamada <code>Zend_Auth_Storage_Session</code>, la cual, a su vez usa
  174. <link linkend="zend.session">Zend_Session</link>. Una clase diferente podría ser utilizada mediante
  175. proveer un objeto que implemente <code>Zend_Auth_Storage_Interface</code> a <code>Zend_Auth::setStorage()</code>
  176. </para>
  177. <note>
  178. <para>
  179. Si el automático almacenamiento persistente de la identidad no es apropiado para un caso en particular,
  180. entonces los desarrolladores podrían dejar de usar la clase <code>Zend_Auth</code> al mismo tiempo,
  181. utilizando en su lugar una clase adaptadora directamente.
  182. </para>
  183. </note>
  184. <example id="zend.auth.introduction.persistence.default.example">
  185. <title>Modifying the Session Namespace</title>
  186. <para>
  187. <code>Zend_Auth_Storage_Session</code> usa un espacionombre (namespace) de sesión <code>'Zend_Auth'</code>.
  188. Este espacio-nombre podría ser OVERRIDDEN al pasar un valor diferente al contructor de
  189. <code>Zend_Auth_Storage_Session</code>, y este valor es pasado internamente al constructor de
  190. <code>Zend_Session_Namespace</code>. Esto debería ocurrir antes de que se intente la autenticación, ya que
  191. <code>Zend_Auth::authenticate()</code> realiza el almacenamiento automático de la identidad.
  192. <programlisting role="php"><![CDATA[
  193. // Almacena una referencia a la instancia Singleton de Zend_Auth
  194. $auth = Zend_Auth::getInstance();
  195. // Usa 'unEspacionombre' en lugar de 'Zend_Auth'
  196. $auth->setStorage(new Zend_Auth_Storage_Session('unEspacionombre'));
  197. /**
  198. * @todo Set up the auth adapter, $authAdapter
  199. */
  200. // Autenticar, almacenando el resultado, y persistiendo la identidad en
  201. // suceso
  202. $result = $auth->authenticate($authAdapter);
  203. ]]>
  204. </programlisting>
  205. </para>
  206. </example>
  207. </sect3>
  208. <sect3 id="zend.auth.introduction.persistence.custom">
  209. <title>Implementando Almacenamiento Personalizado</title>
  210. <para>
  211. En ocaciones los desarrolladores podrían necesitar usar un diferente comportamiento de persistencia de identidad
  212. que el provisto por <code>Zend_Auth_Storage_Session</code>. Para esos casos los desarrolladores podrían simplemente
  213. implementar <code>Zend_Auth_Storage_Interface</code> y suplir una instancia de la clase a
  214. <code>Zend_Auth::setStorage()</code>.
  215. </para>
  216. <example id="zend.auth.introduction.persistence.custom.example">
  217. <title>Usando una Clase de Almacenamiento Personalizada</title>
  218. <para>
  219. Para poder utilizar una clase de almacenamiento persistente de identidad diferente a
  220. <code>Zend_Auth_Storage_Session</code>, el desarrollador implementa <code>Zend_Auth_Storage_Interface</code>:
  221. <programlisting role="php"><![CDATA[
  222. class MyStorage implements Zend_Auth_Storage_Interface
  223. {
  224. /**
  225. * Regresa true si y solo si el almacenamiento esta vacio
  226. *
  227. * @arroja Zend_Auth_Storage_Exception Si es imposible
  228. * determinar si el almacenamiento
  229. * esta vacio
  230. * @regresa boleano
  231. */
  232. public function isEmpty()
  233. {
  234. /**
  235. * @por hacer implementación
  236. */
  237. }
  238. /**
  239. * Regresa el contenido del almacenamiento
  240. *
  241. * El comportamiento es indefinido cuando el almacenamiento esta vacio
  242. *
  243. * @arroja Zend_Auth_Storage_Exception Si leer contenido de
  244. * almacenamiento es imposible
  245. * @regresa mixto
  246. */
  247. public function read()
  248. {
  249. /**
  250. * @por hacer implementación
  251. */
  252. }
  253. /**
  254. * Escribe $contents al almacenamiento
  255. *
  256. * @parametros mezclado $contents
  257. * @arroja Zend_Auth_Storage_Exception Si escribir $contents al
  258. * almacenamiento es imposible
  259. * @regresa boleano
  260. */
  261. public function write($contents)
  262. {
  263. /**
  264. * @por hacer implementación
  265. */
  266. }
  267. /**
  268. * limpia contenidos del almacenamiento
  269. *
  270. * @arroja Zend_Auth_Storage_Exception Si limpiar contenidos del
  271. * almacenamiento es imposible
  272. * @regresa void
  273. */
  274. public function clear()
  275. {
  276. /**
  277. * @por hacer implementación
  278. */
  279. }
  280. }
  281. ]]>
  282. </programlisting>
  283. </para>
  284. <para>
  285. A fin de poder usar esta clase de almacenamiento personalizada, <code>Zend_Auth::setStorage()</code>
  286. es invocada antes de intentar una petición de autenticación:
  287. <programlisting role="php"><![CDATA[
  288. // Instruye Zend_Auth para usar la clase de almacenamiento personalizada
  289. Zend_Auth::getInstance()->setStorage(new MyStorage());
  290. /**
  291. * @por hacer Configurar el adaptador de autenticación, $authAdapter
  292. */
  293. // Autenticar, almacenando el resultado, y persistiendo la identidad
  294. // si hay exito
  295. $result = Zend_Auth::getInstance()->authenticate($authAdapter);
  296. ]]>
  297. </programlisting>
  298. </para>
  299. </example>
  300. </sect3>
  301. </sect2>
  302. <sect2 id="zend.auth.introduction.using">
  303. <title>Usando Zend_Auth</title>
  304. <para>
  305. Hay dos formas provistas de usar adaptadores Zend_Auth:
  306. <orderedlist>
  307. <listitem>
  308. <para>
  309. indirectamente, a través de <code>Zend_Auth::authenticate()</code>
  310. </para>
  311. </listitem>
  312. <listitem>
  313. <para>
  314. directamente, a través del metodo<code>authenticate()</code> del adaptador
  315. </para>
  316. </listitem>
  317. </orderedlist>
  318. </para>
  319. <para>
  320. El siguiente ejemplo ilustra como usar el adaptador Zend_Auth indirectamente, a través
  321. del uso de la clase <code>Zend_Auth</code>:
  322. <programlisting role="php"><![CDATA[
  323. // Recibe una referencia a la instancia singleton de Zend_Auth
  324. $auth = Zend_Auth::getInstance();
  325. // Configura el adaptador de autenticación
  326. $authAdapter = new MyAuthAdapter($username, $password);
  327. // Intenta la autenticación, almacenando el resultado
  328. $result = $auth->authenticate($authAdapter);
  329. if (!$result->isValid()) {
  330. // Fautenticación fallida: imprime el por que
  331. foreach ($result->getMessages() as $message) {
  332. echo "$message\n";
  333. }
  334. } else {
  335. // Autenticación exitosa, la identidad ($username) es almacenada
  336. // en la sesión
  337. // $result->getIdentity() === $auth->getIdentity()
  338. // $result->getIdentity() === $username
  339. }
  340. ]]>
  341. </programlisting>
  342. </para>
  343. <para>
  344. Una vez que la autenticación ha sido intentada en una petición, como en el ejemplo anterior,
  345. es fácil verificar si existe una identidad autenticada exitosamente:
  346. <programlisting role="php"><![CDATA[
  347. $auth = Zend_Auth::getInstance();
  348. if ($auth->hasIdentity()) {
  349. // Existe la identidad; obtenla
  350. $identity = $auth->getIdentity();
  351. }
  352. ]]>
  353. </programlisting>
  354. </para>
  355. <para>
  356. Para remover una identidad del almacenamiento persistente, simplemente usa el metodo <code>clearIdentity()</code>method.
  357. Comunmente esto sería usado para implementar una operación "cerrar sesión" en la aplicación:
  358. <programlisting role="php"><![CDATA[
  359. Zend_Auth::getInstance()->clearIdentity();
  360. ]]>
  361. </programlisting>
  362. </para>
  363. <para>
  364. Cuando el uso automático de almacenamiento persistente es inapropiado para un caso en particular,
  365. el desarrollador podría simplemente omitir el uso de la clase <code>Zend_Auth</code>, usando una
  366. clase adaptadora directamente. El uso directo de una clase adaptadora implica configurar y preparar
  367. un objeto adaptador y despues llamar a su metodo <code>authenticate()</code>. Los detalles específicos
  368. del adaptador son discutidos en la documentación de cada adaptador. El siguiente ejemplo utiliza
  369. directamente <code>MyAuthAdapter</code>:
  370. <programlisting role="php"><![CDATA[
  371. // Configura el adaptador de autenticación
  372. $authAdapter = new MyAuthAdapter($username, $password);
  373. // Intenta la autenticación, almacenando el resultado
  374. $result = $authAdapter->authenticate();
  375. if (!$result->isValid()) {
  376. // Autenticación fallida, imprime el porque
  377. foreach ($result->getMessages() as $message) {
  378. echo "$message\n";
  379. }
  380. } else {
  381. // Autenticación exitosa
  382. // $result->getIdentity() === $username
  383. }
  384. ]]>
  385. </programlisting>
  386. </para>
  387. </sect2>
  388. </sect1>
  389. <!--
  390. vim:se ts=4 sw=4 et:
  391. -->