Zend_Acl.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. <sect1 id="zend.acl.introduction">
  2. <title>Introducción</title>
  3. <para>
  4. <classname>Zend_Acl</classname> provee la implementación de un sistema simple y
  5. flexible de Listas de Control de Acceso (ACL, por sus siglas en
  6. inglés) para la administración de privilegios. En general, una
  7. aplicación puede utilizar las ACL para controlar el acceso a
  8. ciertos objetos protegidos, que son requeridos por otros
  9. objetos.
  10. </para>
  11. <para>
  12. Para los propósitos de esta documentación,
  13. <itemizedlist>
  14. <listitem>
  15. <para>
  16. Un
  17. <emphasis role="strong">recurso</emphasis>
  18. es un objeto al cual el acceso esta controlado.
  19. </para>
  20. </listitem>
  21. <listitem>
  22. <para>
  23. Un
  24. <emphasis role="strong">rol</emphasis>
  25. es un objeto que puede solicitar acceso a un
  26. recurso.
  27. </para>
  28. </listitem>
  29. </itemizedlist>
  30. En términos generales,
  31. <emphasis role="strong">
  32. Los roles solicitan acceso a los recursos
  33. </emphasis>
  34. . Por ejemplo, si una persona solicita acceso a un automóvil,
  35. entonces la persona se convierte en el rol solicitante, y el
  36. automóvil en el recurso, puesto que el acceso al automóvil puede
  37. no estar disponible a cualquiera.
  38. </para>
  39. <para>
  40. A través de la especificación y uso de Listas de Control de
  41. Acceso (ACL), una aplicación puede controlar cómo los objetos
  42. solicitantes (roles) han obtenido acceso a objetos protegidos
  43. (recursos).
  44. </para>
  45. <sect2 id="zend.acl.introduction.resources">
  46. <title>Acerca de los Recursos</title>
  47. <para>
  48. En <classname>Zend_Acl</classname>, crear un recurso es muy sencillo. <classname>Zend_Acl</classname>
  49. proporciona el
  50. <classname>Zend_Acl_Resource_Interface</classname>
  51. para facilitar a los desarrolladores la creacción de
  52. recursos. Una clase solo necesita implementar su interfaz,
  53. la cual consiste en un método único,
  54. <code>getResourceId()</code>
  55. , para que <classname>Zend_Acl</classname> considere el objeto como un recurso.
  56. Adicionalmente,
  57. <classname>Zend_Acl_Resource</classname>
  58. es proporcionado por <classname>Zend_Acl</classname> como un recurso básico de
  59. aplicación para que los desarrolladores puedan extenderla hasta
  60. donde lo deseen.
  61. </para>
  62. <para>
  63. <classname>Zend_Acl</classname> provee un estructura de árbol a la cual pueden ser
  64. agregados múltiples recursos (o "Áreas con Controles de
  65. Acceso").Ya que los recursos son almacenados en esta
  66. estructura de árbol, estos pueden ser organizados desde lo
  67. general (hacia la raíz del árbol) a lo específico (hacia las
  68. ramas del árbol). Consultas sobre un recurso específico
  69. buscarán automáticamente, en la jerarquía del
  70. recurso, reglas asignadas a recursos anteriores a los que
  71. el recurso actual haga referencia, permitiendo la herencia
  72. simple de reglas. Por ejemplo, si una regla por defecto se
  73. aplica a cada edificio en una ciudad, uno simplemente
  74. podría asignar la regla a la ciudad, en lugar de asignar la
  75. misma regla a cada edificio. Algunos edificios pueden
  76. necesitar excepciones a la regla, sin embargo, y esto es
  77. fácil de hacer en <classname>Zend_Acl</classname> asignando esta excepción a
  78. cada edificio que necesite una excepción a la regla. Un
  79. recurso sólo puede heredar de un recurso padre, aunque este
  80. recurso padre puede tener a la vez su propio recurso padre,
  81. y así; sucesivamente.
  82. </para>
  83. <para>
  84. <classname>Zend_Acl</classname> también soporta privilegios sobre recursos (ej.
  85. "crear","leer","actualizar", "borrar"), y el desarrollador
  86. puede asignar reglas que afecten o a todos los privilegios o
  87. a privilegios específicos sobre un recurso.
  88. </para>
  89. </sect2>
  90. <sect2 id="zend.acl.introduction.roles">
  91. <title>Acerca de las Reglas</title>
  92. <para>
  93. Al igual que los recursos, la creación de un rol
  94. también es muy simple. <classname>Zend_Acl</classname> proporciona
  95. <classname>Zend_Acl_Role_Interface</classname>
  96. para facilitar a los desarrolladores la creación de
  97. roles. Una clase solo necesita la implementación de su
  98. interfaz, la cual consiste en un método único,
  99. <code>getRoleId()</code>
  100. , para que <classname>Zend_Acl</classname> considere que el objeto es un Rol.
  101. Adicionalmente,
  102. <classname>Zend_Acl_Role</classname>
  103. está incluido con <classname>Zend_Acl</classname> como una implementación principal
  104. del rol para que los desarrolladores la extiendan hasta
  105. donde lo deseen.
  106. </para>
  107. <para>
  108. En <classname>Zend_Acl</classname>, un Rol puede heredar de otro o más roles. Esto
  109. es para soportar herencia de reglas entre roles. Por ejemplo,
  110. un Rol de usuario, como "sally", puede estar bajo uno o más
  111. roles padre, como "editor" y "administrador". El
  112. desarrollador puede asignar reglas a "editor" y
  113. "administrador" por separado, y "sally" puede heredar tales
  114. reglas de ambos, sin tener que asignar reglas directamente a
  115. "sally".
  116. </para>
  117. <para>
  118. Dado que la habilidad de herencia desde múltiples roles es
  119. muy util, múltiples herencias tambien introduce cierto grado
  120. de complejidad. El siguiente ejemplo ilustra la condición de
  121. ambiguedad y como <classname>Zend_Acl</classname> soluciona esto.
  122. </para>
  123. <example
  124. id="zend.acl.introduction.roles.example.multiple_inheritance">
  125. <title>Herencia Multiple entre Roles</title>
  126. <para>
  127. El siguiente código define tres roles principales - "
  128. <code>invitado</code>
  129. ", "
  130. <code>miembro</code>
  131. ", y "
  132. <code>admin</code>
  133. " - de los cuales otros roles pueden heredar. Entonces,
  134. un rol identificado como "
  135. <code>unUsuario</code>
  136. " es colocado y hereda de los otros tres roles. El orden en
  137. el cual estos roles aparecen en el array
  138. <code>$parents</code>
  139. es importante. Cuando es necesario, <classname>Zend_Acl</classname> busca por
  140. reglas de acceso definidas no solo para el rol
  141. solicitado (aquí, "
  142. <code>unUsuario</code>
  143. "), sino también sobre los roles heredados (aquí, "
  144. <code>invitado</code>
  145. ", "
  146. <code>miembro</code>
  147. ", y "
  148. <code>admin</code>
  149. "):
  150. </para>
  151. <programlisting role="php"><![CDATA[
  152. require_once 'Zend/Acl.php';
  153. $acl = new Zend_Acl();
  154. require_once 'Zend/Acl/Role.php';
  155. $acl->addRole(new Zend_Acl_Role('invitado'))
  156. ->addRole(new Zend_Acl_Role('miembro'))
  157. ->addRole(new Zend_Acl_Role('admin'));
  158. $parents = array('invitado', 'miembro', 'admin');
  159. $acl->addRole(new Zend_Acl_Role('unUsuario'), $parents);
  160. require_once 'Zend/Acl/Resource.php';
  161. $acl->add(new Zend_Acl_Resource('unRecurso'));
  162. $acl->deny('invitado', 'unRecurso');
  163. $acl->allow('miembro', 'unRecurso');
  164. echo $acl->isAllowed('unUsuario', 'unRecurso') ? 'permitido' : 'denegado';]]>
  165. </programlisting>
  166. <para>
  167. Ya que no hay reglas específicamente definidas para
  168. el rol "
  169. <code>unUsuario</code>
  170. " y "
  171. <code>unRecurso</code>
  172. ", <classname>Zend_Acl</classname> debe buscar por reglas que puedan estar
  173. definidas para roles "
  174. <code>unUsuario</code>
  175. " hereda. Primero, el rol "
  176. <code>admin</code>
  177. " es visitado, y no hay regla de acceso definida
  178. para éste. Luego, el rol "
  179. <code>miembro</code>
  180. " es visitado, y <classname>Zend_Acl</classname> encuentra que aquí hay una
  181. regla especificando que "
  182. <code>miembro</code>
  183. " tiene permiso para acceder a "
  184. <code>unRecurso</code>
  185. ".
  186. </para>
  187. <para>
  188. Así, <classname>Zend_Acl</classname> va a seguir examinando las reglas definidas
  189. para otros roles padre, sin embargo, encontraría que "
  190. <code>invitado</code>
  191. " tiene el acceso denegado a "
  192. <code>unRecurso</code>
  193. ". Este hecho introduce una ambigüedad debido a que
  194. ahora "
  195. <code>unUsuario</code>
  196. " está tanto denegado como permitido para acceder a "
  197. <code>unRecurso</code>
  198. ", por la razon de tener un conflicto de reglas
  199. heredadas de diferentes roles padre.
  200. </para>
  201. <para>
  202. <classname>Zend_Acl</classname> resuelve esta ambiguedad completando la
  203. consulta cuando encuentra la primera regla que es
  204. directamente aplicable a la consulta. En este caso, dado
  205. que el rol "
  206. <code>miembro</code>
  207. " es examinado antes que el rol "
  208. <code>invitado</code>
  209. ", el código de ejemplo mostraría "
  210. <code>permitido</code>
  211. ".
  212. </para>
  213. </example>
  214. <note>
  215. <para>
  216. Cuando se especifican múltiples padres para un Rol, se
  217. debe tener en cuenta que el último padre listado es el
  218. primero en ser buscado por reglas aplicables para una
  219. solicitud de autorización.
  220. </para>
  221. </note>
  222. </sect2>
  223. <sect2 id="zend.acl.introduction.creating">
  224. <title>Creando las Listas de Control de Acceso (ACL)</title>
  225. <para>
  226. Una ACL puede representar cualquier grupo de objetos físicos
  227. o virtuales que desee. Para propósitos de demostración,
  228. sin embargo, crearemos un ACL básico para un Sistema de
  229. Administración de Contenido que mantendrá varias escalas de
  230. grupos sobre una amplia variedad de áreas. Para crear un
  231. nuevo objeto ACL, iniciamos la ACL sin parámetros:
  232. </para>
  233. <programlisting role="php"><![CDATA[
  234. require_once 'Zend/Acl.php';
  235. $acl = new Zend_Acl();]]>
  236. </programlisting>
  237. <note>
  238. <para>
  239. Hasta que un desarrollador especifique una regla
  240. "permitido", <classname>Zend_Acl</classname> deniega el acceso a cada privilegio
  241. sobre cada recurso para cada rol.
  242. </para>
  243. </note>
  244. </sect2>
  245. <sect2 id="zend.acl.introduction.role_registry">
  246. <title>Registrando Roles</title>
  247. <para>
  248. El Sistema de Administración de Contenido casi
  249. siempre necesita una jerarquía de permisos para determinar
  250. la capacidad de identificación de sus usuarios. Puede haber
  251. un grupo de 'Invitados' para permitir acceso limitado para
  252. demostraciones, un grupo de 'Personal' para la mayoría de
  253. usuarios del CMS quienes realizan la mayor parte de
  254. operaciones del día a día, un grupo 'Editores' para las
  255. responsabilidades de publicación, revisión, archivo y
  256. eliminación de contenido, y finalmente un grupo
  257. 'Administradores' cuyas tareas pueden incluir todas las de los
  258. otros grupos y también el mantenimiento de la información
  259. delicada, manejo de usuarios, configuración de los datos
  260. básicos y su respaldo/exportación. Este grupo de permisos
  261. pueden ser representados en un registro de roles,
  262. permitiendo a cada grupo heredar los privilegios de los
  263. grupos 'padre', al igual que proporcionando distintos
  264. privilegios solo para su grupo individual. Los permisos pueden
  265. ser expresados como:
  266. </para>
  267. <table
  268. id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
  269. <title>Controles de Acceso para un CMS de ejemplo</title>
  270. <tgroup cols="3">
  271. <thead>
  272. <row>
  273. <entry>Nombre</entry>
  274. <entry>Permisos Individuales</entry>
  275. <entry>Hereda permisos de</entry>
  276. </row>
  277. </thead>
  278. <tbody>
  279. <row>
  280. <entry>Invitado</entry>
  281. <entry>View</entry>
  282. <entry>N/A</entry>
  283. </row>
  284. <row>
  285. <entry>Personal</entry>
  286. <entry>Editar, Enviar, Revisar</entry>
  287. <entry>Invitado</entry>
  288. </row>
  289. <row>
  290. <entry>Editor</entry>
  291. <entry>Publicar, Archivar, Eliminar</entry>
  292. <entry>Personal</entry>
  293. </row>
  294. <row>
  295. <entry>Administrador</entry>
  296. <entry>(Todos los accesos permitidos)</entry>
  297. <entry>N/A</entry>
  298. </row>
  299. </tbody>
  300. </tgroup>
  301. </table>
  302. <para>
  303. Para este ejemplo, se usa
  304. <classname>Zend_Acl_Role</classname>
  305. , pero cualquier objeto que implemente
  306. <classname>Zend_Acl_Role_Interface</classname>
  307. es admisible. Estos grupos pueden ser agragados al registro
  308. de roles de la siguiente manera:
  309. </para>
  310. <programlisting role="php"><![CDATA[
  311. require_once 'Zend/Acl.php';
  312. $acl = new Zend_Acl();
  313. // Agregar grupos al registro de roles usando <classname>Zend_Acl</classname>_Role
  314. require_once 'Zend/Acl/Role.php';
  315. // Invitado no hereda controles de acceso
  316. $rolInvitado = new Zend_Acl_Role('invitado');
  317. $acl->addRole($rolInvitado);
  318. // Personal hereda de Invitado
  319. $acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
  320. /* alternativamente, lo de arriba puede ser escrito así:
  321. $rolInvitado = $acl->addRole(new Zend_Acl_Role('personal'), 'invitado');
  322. //*/
  323. // Editor hereda desde personal
  324. $acl->addRole(new Zend_Acl_Role('editor'), 'personal');
  325. // Administrador no hereda controles de acceso
  326. $acl->addRole(new Zend_Acl_Role('administrador'));]]>
  327. </programlisting>
  328. </sect2>
  329. <sect2 id="zend.acl.introduction.defining">
  330. <title>Definiendo Controles de Acceso</title>
  331. <para>
  332. Ahora que la ACL contiene los roles relevantes, se pueden
  333. establecer reglas que definan cómo los roles pueden acceder
  334. a los recursos. Tenga en cuenta que no definiremos ningún
  335. recurso en particular para este ejemplo, el cual está
  336. simplificado para ilustrar que las reglas se aplican a todos
  337. los recursos. <classname>Zend_Acl</classname> proporciona una forma práctica por la
  338. cual las reglas solo necesitan ser asignadas de lo general a
  339. lo especifico, minimizando el número de reglas necesarias,
  340. porque los recursos y roles heredan reglas que están
  341. definidas en sus padres.
  342. </para>
  343. <para>
  344. Consecuentemente, podemos definir un grupo razonablemente
  345. complejo de reglas con un mínimo de código. Para aplicar
  346. estos permisos básicos como están definidos arriba:
  347. </para>
  348. <programlisting role="php"><![CDATA[
  349. require_once 'Zend/Acl.php';
  350. $acl = new Zend_Acl();
  351. require_once 'Zend/Acl/Role.php';
  352. $rolInvitado = new Zend_Acl_Role('invitado');
  353. $acl->addRole($rolInvitado);
  354. $acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
  355. $acl->addRole(new Zend_Acl_Role('editor'), 'personal');
  356. $acl->addRole(new Zend_Acl_Role('administrador'));
  357. // Invitado solo puede ver el contenido
  358. $acl->allow($rolInvitado, null, 'ver');
  359. /* Lo de arriba puede ser escrito de la siguiente forma alternativa:
  360. $acl->allow('invitado', null, 'ver');
  361. //*/
  362. // Personal hereda el privilegio de ver de invitado, pero también necesita privilegios adicionales
  363. $acl->allow('personal', null, array('editar', 'enviar', 'revisar'));
  364. // Editor hereda los privilegios de ver, editar, enviar, y revisar de personal,
  365. // pero también necesita privilegios adicionales
  366. $acl->allow('editor', null, array('publicar', 'archivar', 'eliminar'));
  367. // Administrador no hereda nada, pero tiene todos los privilegios permitidos
  368. $acl->allow('administrador');]]>
  369. </programlisting>
  370. <para>
  371. El valor
  372. <code>null</code>
  373. en las llamadas de
  374. <code>allow()</code>
  375. es usado para indicar que las reglas de permiso se aplican a
  376. todos los recursos.
  377. </para>
  378. </sect2>
  379. <sect2 id="zend.acl.introduction.querying">
  380. <title>Consultando la ACL</title>
  381. <para>
  382. Ahora tenemos una ACL flexible que puede ser usada para
  383. determinar qué solicitantes tienen permisos para realizar
  384. funciones a través de la aplicacion web. Ejecutar
  385. consultas es la forma más simple de usar el método
  386. <code>isAllowed()</code>
  387. :
  388. </para>
  389. <programlisting role="php"><![CDATA[
  390. echo $acl->isAllowed('invitado', null, 'ver') ?
  391. "permitido" : "denegado"; // permitido
  392. echo $acl->isAllowed('personal', null, 'publicar') ?
  393. "permitido" : "denegado"; // denegado
  394. echo $acl->isAllowed('personal', null, 'revisar') ?
  395. "permitido" : "denegado"; // permitido
  396. echo $acl->isAllowed('editor', null, 'ver') ?
  397. "permitido" : "denegado"; // permitido debido a la herencia de invitado
  398. echo $acl->isAllowed('editor', null, 'actualizar') ?
  399. "permitido" : "denegado"; // denegado debido a que no hay regla de permiso para 'actualizar'
  400. echo $acl->isAllowed('administrador', null, 'ver') ?
  401. "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios
  402. echo $acl->isAllowed('administrador') ?
  403. "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios
  404. echo $acl->isAllowed('administrador', null, 'actualizar') ?
  405. "permitido" : "denegado"; // permitido porque administrador tiene permitidos todos los privilegios]]>
  406. </programlisting>
  407. </sect2>
  408. </sect1>
  409. <!--
  410. vim:se ts=4 sw=4 et:
  411. -->