Zend_Acl.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- EN-Revision: 15346 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.acl.introduction">
  5. <title>Introduction</title>
  6. <para>
  7. <classname>Zend_Acl</classname> fournit une implémentation légère et flexible de
  8. listes de contrôle d'accès (ACL : Access Control List) pour la gestion de privilèges. En
  9. général, une application peut utiliser une telle fonctionnalité pour contrôler l'accès à
  10. certains objets par d'autres objets demandeurs.
  11. </para>
  12. <para>
  13. Dans le cadre de cette documentation,
  14. <itemizedlist>
  15. <listitem>
  16. <para>
  17. une <emphasis>ressource</emphasis> est un objet dont l'accès
  18. est contrôlé,
  19. </para>
  20. </listitem>
  21. <listitem>
  22. <para>
  23. un <emphasis>rôle</emphasis> est un objet qui peut demander
  24. l'accès à une ressource.
  25. </para>
  26. </listitem>
  27. </itemizedlist>Dit simplement, <emphasis> les rôles demandent l'accès à des
  28. ressources</emphasis>. Par exemple, si une personne demande l'accès à une voiture, alors la
  29. personne est le rôle demandeur et la voiture est la ressource, puisque l'accès à la voiture
  30. est soumis à un contrôle.
  31. </para>
  32. <para>
  33. Grâce à la définition et à la mise en oeuvre d'une liste de contrôle d'accès (ACL),
  34. une application peut contrôler comment les objets demandeurs (rôles) reçoivent l'accès (ou
  35. non) à des objets protégés (ressources).
  36. </para>
  37. <sect2 id="zend.acl.introduction.resources">
  38. <title>A propos des ressources</title>
  39. <para>
  40. Avec <classname>Zend_Acl</classname>, créer une ressource est très simple.
  41. <classname>Zend_Acl</classname> fournit
  42. <classname>Zend_Acl_Resource_Interface</classname> pour faciliter la tâche aux
  43. développeurs. Une classe a simplement besoin d'implémenter cette interface, qui
  44. consiste en une seule méthode, <code>getResourceId()</code>, pour que
  45. <classname>Zend_Acl</classname> reconnaît l'objet comme étant une ressource. Par
  46. ailleurs, <classname>Zend_Acl_Resource</classname> est fourni par
  47. <classname>Zend_Acl</classname> comme une implémentation basique de ressource que les
  48. développeurs peuvent étendre si besoin.
  49. </para>
  50. <para>
  51. <classname>Zend_Acl</classname> fournit une structure en arbre à laquelle
  52. plusieurs ressources (ou "zone sous contrôle d'accès") peuvent être ajoutées. Puisque
  53. les ressources sont sauvées dans cet arbre, elles peuvent être organisées du général
  54. (via la racine de l'arbre) jusqu'au particulier (via les feuilles de l'arbre). Les
  55. requêtes envers une ressource spécifique vont automatiquement entraîner la recherche de
  56. règles sur ses parents au sein de la structure hiérarchique des ressources, ce qui
  57. permet un héritage simple des règles. Par exemple, si une règle par défaut doit être
  58. appliquée à tous les bâtiments d'une ville, on pourra simplement assigner la règle à la
  59. ville elle-même, au lieu de la répéter à tous les bâtiments. Mais certains bâtiments
  60. peuvent nécessiter des règles spécifiques, et ceci peut se faire aisément avec
  61. <classname>Zend_Acl</classname> en assignant les règles nécessaires à chaque bâtiment
  62. de la ville qui nécessite une exception. Une ressource peut hériter d'un seul parent
  63. ressource, qui hérite lui même de son propre parent, et ainsi de suite.
  64. </para>
  65. <para>
  66. <classname>Zend_Acl</classname> supporte aussi des privilèges pour chaque
  67. ressource (par exemple : "créer", "lire", "modifier", "supprimer"), et le développeur
  68. peut assigner des règles qui affectent tous les privilèges ou seuls certains privilèges
  69. d'une ressource.
  70. </para>
  71. </sect2>
  72. <sect2 id="zend.acl.introduction.roles">
  73. <title>A propos des rôles</title>
  74. <para>
  75. Comme pour les ressources, créer un rôle est très simple.
  76. <classname>Zend_Acl</classname> propose <classname>Zend_Acl_Role_Interface</classname>
  77. pour faciliter le travail des développeurs. Une classe doit uniquement implémenter
  78. cette interface qui consiste en une seule méthode <code>getRoleId()</code>, pour que
  79. <classname>Zend_Acl</classname> considère l'objet comme un rôle. De plus,
  80. <classname>Zend_Acl_Role</classname> est inclus dans <classname>Zend_Acl</classname>
  81. comme une implémentation basique de rôle que les développeurs peuvent étendre si
  82. besoin.
  83. </para>
  84. <para>
  85. Dans <classname>Zend_Acl</classname>, un rôle peut hériter de un ou plusieurs
  86. rôles. Ceci permet de supporter l'héritage de règles à travers plusieurs rôles. Par
  87. exemple, un rôle utilisateur, comme "Éric", peut appartenir à un ou plusieurs rôles
  88. d'action, tels que "éditeur" ou "administrateur". Le développeur peut créer des règles
  89. pour "éditeur" et "administrateur" séparément, et "Éric" va hériter des règles des deux
  90. sans avoir à définir des règles directement pour "Éric".
  91. </para>
  92. <para>
  93. Bien que la possibilité d'hériter de plusieurs rôles soit très utile, l'héritage
  94. multiple introduit aussi un certain degré de complexité. L'exemple ci-dessous illustre
  95. l'ambiguïté et la manière de la résoudre.
  96. </para>
  97. <example id="zend.acl.introduction.roles.example.multiple_inheritance">
  98. <title>Héritages multiples entre rôles</title>
  99. <para>
  100. Le code ci-dessous définit trois rôles de base - "<code>guest</code>",
  101. "<code>member</code>", et "<code>admin</code>" - desquels d'autres rôles peuvent
  102. hériter. Ensuite, un rôle identifié par "<code>someUser</code>" est créé et hérite
  103. des trois autres rôles. L'ordre selon lequel ces rôles apparaissent dans le tableau
  104. <code>$parents</code> est important. Lorsque cela est nécessaire
  105. <classname>Zend_Acl</classname> recherche les règles d'accès définies non seulement
  106. pour le rôle demandé (ici "<code>someUser</code>"), mais aussi pour les autres rôles
  107. desquels le rôle recherché hérite (ici "<code>guest</code>",
  108. "<code>member</code>", et "<code>admin</code>")&#160;:
  109. </para>
  110. <programlisting language="php"><![CDATA[
  111. $acl = new Zend_Acl();
  112. $acl->addRole(new Zend_Acl_Role('guest'))
  113. ->addRole(new Zend_Acl_Role('member'))
  114. ->addRole(new Zend_Acl_Role('admin'));
  115. $parents = array('guest', 'member', 'admin');
  116. $acl->addRole(new Zend_Acl_Role('someUser'), $parents);
  117. $acl->add(new Zend_Acl_Resource('someResource'));
  118. $acl->deny('invite', 'someResource');
  119. $acl->allow('membre', 'someResource');
  120. echo $acl->isAllowed('unUtilisateur', 'someResource') ? 'autorisé' : 'refusé';
  121. ]]></programlisting>
  122. <para>
  123. Puisqu'il n'y a pas de règle spécifiquement définie pour le rôle
  124. "unUtilisateur" et "uneRessource", <classname>Zend_Acl</classname> doit rechercher
  125. des règles qui pourraient être définies pour des rôles dont "someUser" hérite.
  126. Premièrement, le rôle "admin" est contrôlé, et il n'y a pas de règle d'accès
  127. définie pour lui. Ensuite, le rôle "membre" est visité, et
  128. <classname>Zend_Acl</classname> trouve qu'il y a une règle qui spécifie que
  129. "member" a un accès autorisé à "someResource".
  130. </para>
  131. <para>
  132. Si <classname>Zend_Acl</classname> continuait à examiner toutes les règles de
  133. tous les rôles parents, il trouverait que "someResource" est interdit d'accès à
  134. "someResource". Ceci introduit une ambiguïté puisque maintenant "someUser" est
  135. à la fois autorisé et interdit d'accès à "someResource", puisqu'il hérite de règles
  136. opposées de ses différents parents.
  137. </para>
  138. <para>
  139. <classname>Zend_Acl</classname> résout cette ambiguïté en arrêtant la
  140. recherche de règles d'accès dès qu'une première règle est découverte. Dans notre
  141. exemple, puisque le rôle "member" est examiné avant le rôle "invite", le résultat
  142. devrait afficher "<code>autorisé</code>".
  143. </para>
  144. </example>
  145. <note>
  146. <para>
  147. Lorsque vous spécifiez plusieurs parents pour un rôle, conservez à l'esprit
  148. que le dernier parent listé est le premier dans lequel une règle utilisable sera
  149. recherchée.
  150. </para>
  151. </note>
  152. </sect2>
  153. <sect2 id="zend.acl.introduction.creating">
  154. <title>Créer la Liste de Contrôle d'Accès</title>
  155. <para>
  156. Une ACL peut représenter n'importe quel ensemble d'objets physiques ou virtuels
  157. que vous souhaitez. Pour les besoins de la démonstration, nous allons créer un système
  158. basique d'ACL pour une Gestion de Contenus (CMS) qui comporte plusieurs niveaux de
  159. groupes au sein d'une grande variété de zones. Pour créer un nouvel objet ACL, nous
  160. créons une nouvelle instance d'ACL sans paramètres&#160;:
  161. </para>
  162. <programlisting language="php"><![CDATA[
  163. $acl = new Zend_Acl();
  164. ]]></programlisting>
  165. <note>
  166. <para>
  167. Jusqu'à ce que le développeur spécifie une règle "allow",
  168. <classname>Zend_Acl</classname> refuse l'accès pour tous les privilèges sur chaque
  169. ressource pour chaque rôle.
  170. </para>
  171. </note>
  172. </sect2>
  173. <sect2 id="zend.acl.introduction.role_registry">
  174. <title>Registre des rôles</title>
  175. <para>
  176. Les systèmes de gestion de contenu vont pratiquement toujours nécessiter une
  177. hiérarchie de permissions afin de déterminer les droits de rédaction de ses
  178. utilisateurs. Il pourrait y avoir un groupe "Invités" qui donne accès aux
  179. démonstrations, un groupe "Staff" pour la majorité des utilisateurs du CMS qui
  180. réalisent la plupart du travail quotidien, un groupe "Éditeur" pour ceux qui sont
  181. responsables de la publication, l'archivage, la relecture et la suppression, et enfin
  182. un groupe "Administrateur" dont les tâches incluent toutes les tâches des autres
  183. groupes plus des tâches de maintenance, de gestion des utilisateurs, configuration et
  184. backup/export. Cet ensemble de permissions peut être représenté dans un registre de
  185. rôles, permettant à chaque groupe d'hériter des privilèges des groupes "parents". Les
  186. permissions peuvent être rendues de la manière suivante&#160;:
  187. </para>
  188. <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
  189. <title>Contrôles d'Accès pour un exemple de CMS</title>
  190. <tgroup cols="3">
  191. <thead>
  192. <row>
  193. <entry>Nom</entry>
  194. <entry>Permissions</entry>
  195. <entry>Permissions héritées de</entry>
  196. </row>
  197. </thead>
  198. <tbody>
  199. <row>
  200. <entry>Invité</entry>
  201. <entry>Voir</entry>
  202. <entry>N/A</entry>
  203. </row>
  204. <row>
  205. <entry>Staff</entry>
  206. <entry>Modifier, Soumettre, Relire</entry>
  207. <entry>Invité</entry>
  208. </row>
  209. <row>
  210. <entry>Éditeur</entry>
  211. <entry>Publier, Archiver, Supprimer</entry>
  212. <entry>Staff</entry>
  213. </row>
  214. <row>
  215. <entry>Administrateur</entry>
  216. <entry>(Reçoit tous les accès)</entry>
  217. <entry>N/A</entry>
  218. </row>
  219. </tbody>
  220. </tgroup>
  221. </table>
  222. <para>
  223. Pour cet exemple, <classname>Zend_Acl_Role</classname> est utilisé, mais
  224. n'importe quel objet qui implémente <classname>Zend_Acl_Role_Interface</classname> est
  225. acceptable. Ces groupes peuvent être ajoutés au registre des rôles comme suit&#160;:
  226. </para>
  227. <programlisting language="php"><![CDATA[
  228. $acl = new Zend_Acl();
  229. // Ajoute des groupes au registre des rôles en utilisant Zend_Acl_Role
  230. // Invité n'hérite d'aucun accès
  231. $roleinvite = new Zend_Acl_Role('invite');
  232. $acl->addRole($roleinvite);
  233. // Staff hérite de Invité
  234. $acl->addRole(new Zend_Acl_Role('staff'), $roleinvite);
  235. // Ce que précède pourrait aussi être écrit:
  236. // $acl->addRole(new Zend_Acl_Role('staff'), 'invite');
  237. // Editeur hérite de staff
  238. $acl->addRole(new Zend_Acl_Role('editeur'), 'staff');
  239. // Administrateur n'hérite pas d'accès
  240. $acl->addRole(new Zend_Acl_Role('administrateur'));
  241. ]]></programlisting>
  242. </sect2>
  243. <sect2 id="zend.acl.introduction.defining">
  244. <title>Définir les Contrôles d'Accès</title>
  245. <para>
  246. Maintenant que l'ACL contient les rôles nécessaires, on peut établir des règles
  247. qui définissent comment les ressources accèdent aux rôles. Vous avez sans doute noté
  248. que nous n'avons défini aucune ressource particulière pour cet exemple, ce qui est plus
  249. simple pour illustrer comment les règles s'appliquent à toutes les ressources.
  250. <classname>Zend_Acl</classname> fournit une implémentation dans laquelle les règles
  251. doivent simplement être assignées du général au particulier, ce qui réduit le nombre de
  252. règles spécifiques à ajouter. Ceci grâce à l'héritage.
  253. </para>
  254. <note>
  255. <para>
  256. Généralement <classname>Zend_Acl</classname> se conforme à une règle donnée
  257. si et seulement si une règle plus spécifique ne s'applique pas.
  258. </para>
  259. </note>
  260. <para>
  261. En conséquence, on peut définir un nombre assez complexe de règles avec un nombre
  262. minimal de code. Pour définir les permissions comme définies ci-dessus&#160;:
  263. </para>
  264. <programlisting language="php"><![CDATA[
  265. $acl = new Zend_Acl();
  266. $roleinvite = new Zend_Acl_Role('invité');
  267. $acl->addRole($roleinvite);
  268. $acl->addRole(new Zend_Acl_Role('staff'), $roleinvite);
  269. $acl->addRole(new Zend_Acl_Role('editeur'), 'staff');
  270. $acl->addRole(new Zend_Acl_Role('administrateur'));
  271. // Invité peut uniquement voir le contenu
  272. $acl->allow($roleinvite, null, 'voir');
  273. /*
  274. ce qui précède peut aussi être écrit :
  275. $acl->allow('invité', null, 'voir');
  276. */
  277. // Staff hérite des privilèges de Invité, mais a aussi ses propres
  278. // privilèges
  279. $acl->allow('staff', null, array('edit', 'submit', 'relire'));
  280. // Editeur hérite les privilèges voir, modifier, soumettre,
  281. // et relire de Staff, mais a aussi besoin de certains privilèges
  282. $acl->allow('editeur', null, array('publier', 'archiver', 'supprimer'));
  283. // Administrateur hérite de rien, mais reçoit tous les privilèges
  284. $acl->allow('administrateur');
  285. ]]></programlisting>
  286. <para>
  287. Les valeurs <code>null</code> dans les appels <code>allow()</code> ci-dessus sont
  288. utilisées pour indiquer que les règles s'appliquent à toutes les ressources.
  289. </para>
  290. </sect2>
  291. <sect2 id="zend.acl.introduction.querying">
  292. <title>Interroger les ACL</title>
  293. <para>
  294. Nous avons maintenant une ACL flexible, qui peut être utilisée pour déterminer si
  295. l'objet appelant a les permissions pour réaliser les fonctions au sein de l'application
  296. web. Interroger l'ACL est assez simple en utilisant la méthode
  297. <code>isAllowed()</code>&#160;:
  298. </para>
  299. <programlisting language="php"><![CDATA[
  300. echo $acl->isAllowed('invité', null, 'voir') ?
  301. "autorisé" : "refusé";
  302. // autorisé
  303. echo $acl->isAllowed('staff', null, 'publier') ?
  304. "autorisé" : "refusé";
  305. // refusé
  306. echo $acl->isAllowed('staff', null, 'relire') ?
  307. "autorisé" : "refusé";
  308. // autorisé
  309. echo $acl->isAllowed('editeur', null, 'voir') ?
  310. "autorisé" : "refusé";
  311. // autorisé parce que hérité de Invité
  312. echo $acl->isAllowed('editeur', null, 'modifier') ?
  313. "autorisé" : "refusé";
  314. // refusé parce qu'il n'y a pas de règle pour 'modifier'
  315. echo $acl->isAllowed('administrateur', null, 'voir') ?
  316. "autorisé" : "refusé";
  317. // autorisé car administrateur est autorisé pour tout
  318. echo $acl->isAllowed('administrateur') ?
  319. "autorisé" : "refusé";
  320. // autorisé car administrateur est autorisé pour tout
  321. echo $acl->isAllowed('administrateur', null, 'modifier') ?
  322. "autorisé" : "refusé";
  323. // autorisé car administrateur est autorisé pour tout
  324. ]]></programlisting>
  325. </sect2>
  326. </sect1>