Zend_Acl.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- EN-Revision: 15101 -->
  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 role="strong">ressource</emphasis> est un objet dont l'accès
  18. est contrôlé,
  19. </para>
  20. </listitem>
  21. <listitem>
  22. <para>
  23. un <emphasis role="strong">rôle</emphasis> est un objet qui peut demander
  24. l'accès à une ressource.
  25. </para>
  26. </listitem>
  27. </itemizedlist>Dit simplement, <emphasis role="strong"> 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 - "invite", "membre", et
  101. "admin" - desquels d'autres rôles peuvent hériter. Ensuite, un rôle identifié par
  102. "unUser" est créé et hérite des trois autres rôles. L'ordre selon lequel ces rôles
  103. 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 "unUser"), mais aussi pour les autres rôles desquels le
  107. rôle recherché hérite (ici "invite", "membre", et "admin")&#160;:
  108. </para>
  109. <programlisting role="php"><![CDATA[
  110. $acl = new Zend_Acl();
  111. $acl->addRole(new Zend_Acl_Role('invite'))
  112. ->addRole(new Zend_Acl_Role('membre'))
  113. ->addRole(new Zend_Acl_Role('admin'));
  114. $parents = array('invite', 'membre', 'admin');
  115. $acl->addRole(new Zend_Acl_Role('unUtilisateur'), $parents);
  116. $acl->add(new Zend_Acl_Resource('uneResource'));
  117. $acl->deny('invite', 'uneResource');
  118. $acl->allow('membre', 'uneResource');
  119. echo $acl->isAllowed('unUtilisateur', 'uneResource') ? 'autorisé' : 'refusé';
  120. ]]></programlisting>
  121. <para>
  122. Puisqu'il n'y a pas de règle spécifiquement définie pour le rôle
  123. "unUtilisateur" et "uneRessource", <classname>Zend_Acl</classname> doit rechercher
  124. des règles qui pourraient être définies pour des rôles dont "unUtilisateur" hérite.
  125. Premièrement, le rôle "admin" est contrôlé, et il n'y a pas de règle d'accès
  126. définie pour lui. Ensuite, le rôle "membre" est visité, et
  127. <classname>Zend_Acl</classname> trouve qu'il y a une règle qui spécifie que
  128. "membre" a un accès autorisé à "uneRessource".
  129. </para>
  130. <para>
  131. Si <classname>Zend_Acl</classname> continuait à examiner toutes les règles de
  132. tous les rôles parents, il trouverait que "invite" est interdit d'accès à
  133. "uneRessource". Ceci introduit une ambiguïté puisque maintenant "unUtilisateur" est
  134. à la fois autorisé et interdit d'accès à "uneRessource", puisqu'il hérite de règles
  135. opposées de ses différents parents.
  136. </para>
  137. <para>
  138. <classname>Zend_Acl</classname> résout cette ambiguïté en arrêtant la
  139. recherche de règles d'accès dès qu'une première règle est découverte. Dans notre
  140. exemple, puisque le rôle "membre" est examiné avant le rôle "invite", le résultat
  141. devrait afficher "autorisé".
  142. </para>
  143. </example>
  144. <note>
  145. <para>
  146. Lorsque vous spécifiez plusieurs parents pour un rôle, conservez à l'esprit
  147. que le dernier parent listé est le premier dans lequel une règle utilisable sera
  148. recherchée.
  149. </para>
  150. </note>
  151. </sect2>
  152. <sect2 id="zend.acl.introduction.creating">
  153. <title>Créer la Liste de Contrôle d'Accès</title>
  154. <para>
  155. Une ACL peut représenter n'importe quel ensemble d'objets physiques ou virtuels
  156. que vous souhaitez. Pour les besoins de la démonstration, nous allons créer un système
  157. basique d'ACL pour une Gestion de Contenus (CMS) qui comporte plusieurs niveaux de
  158. groupes au sein d'une grande variété de zones. Pour créer un nouvel objet ACL, nous
  159. créons une nouvelle instance d'ACL sans paramètres&#160;:
  160. </para>
  161. <programlisting role="php"><![CDATA[
  162. $acl = new Zend_Acl();
  163. ]]></programlisting>
  164. <note>
  165. <para>
  166. Jusqu'à ce que le développeur spécifie une règle "allow",
  167. <classname>Zend_Acl</classname> refuse l'accès pour tous les privilèges sur chaque
  168. ressource pour chaque rôle.
  169. </para>
  170. </note>
  171. </sect2>
  172. <sect2 id="zend.acl.introduction.role_registry">
  173. <title>Registre des rôles</title>
  174. <para>
  175. Les systèmes de gestion de contenu vont pratiquement toujours nécessiter une
  176. hiérarchie de permissions afin de déterminer les droits de rédaction de ses
  177. utilisateurs. Il pourrait y avoir un groupe "Invités" qui donne accès aux
  178. démonstrations, un groupe "Staff" pour la majorité des utilisateurs du CMS qui
  179. réalisent la plupart du travail quotidien, un groupe "Éditeur" pour ceux qui sont
  180. responsables de la publication, l'archivage, la relecture et la suppression, et enfin
  181. un groupe "Administrateur" dont les tâches incluent toutes les tâches des autres
  182. groupes plus des tâches de maintenance, de gestion des utilisateurs, configuration et
  183. backup/export. Cet ensemble de permissions peut être représenté dans un registre de
  184. rôles, permettant à chaque groupe d'hériter des privilèges des groupes "parents". Les
  185. permissions peuvent être rendues de la manière suivante&#160;:
  186. </para>
  187. <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
  188. <title>Contrôles d'Accès pour un exemple de CMS</title>
  189. <tgroup cols="3">
  190. <thead>
  191. <row>
  192. <entry>Nom</entry>
  193. <entry>Permissions</entry>
  194. <entry>Permissions héritées de</entry>
  195. </row>
  196. </thead>
  197. <tbody>
  198. <row>
  199. <entry>Invité</entry>
  200. <entry>Voir</entry>
  201. <entry>N/A</entry>
  202. </row>
  203. <row>
  204. <entry>Staff</entry>
  205. <entry>Modifier, Soumettre, Relire</entry>
  206. <entry>Invité</entry>
  207. </row>
  208. <row>
  209. <entry>Éditeur</entry>
  210. <entry>Publier, Archiver, Supprimer</entry>
  211. <entry>Staff</entry>
  212. </row>
  213. <row>
  214. <entry>Administrateur</entry>
  215. <entry>(Reçoit tous les accès)</entry>
  216. <entry>N/A</entry>
  217. </row>
  218. </tbody>
  219. </tgroup>
  220. </table>
  221. <para>
  222. Pour cet exemple, <classname>Zend_Acl_Role</classname> est utilisé, mais
  223. n'importe quel objet qui implémente <classname>Zend_Acl_Role_Interface</classname> est
  224. acceptable. Ces groupes peuvent être ajoutés au registre des rôles comme suit&#160;:
  225. </para>
  226. <programlisting role="php"><![CDATA[
  227. $acl = new Zend_Acl();
  228. // Ajoute des groupes au registre des rôles en utilisant Zend_Acl_Role
  229. // Invité n'hérite d'aucun accès
  230. $roleinvite = new Zend_Acl_Role('invite');
  231. $acl->addRole($roleinvite);
  232. // Staff hérite de Invité
  233. $acl->addRole(new Zend_Acl_Role('staff'), $roleinvite);
  234. // Ce que précède pourrait aussi être écrit:
  235. // $acl->addRole(new Zend_Acl_Role('staff'), 'invite');
  236. // Editeur hérite de staff
  237. $acl->addRole(new Zend_Acl_Role('editeur'), 'staff');
  238. // Administrateur n'hérite pas d'accès
  239. $acl->addRole(new Zend_Acl_Role('administrateur'));
  240. ]]></programlisting>
  241. </sect2>
  242. <sect2 id="zend.acl.introduction.defining">
  243. <title>Définir les Contrôles d'Accès</title>
  244. <para>
  245. Maintenant que l'ACL contient les rôles nécessaires, on peut établir des règles
  246. qui définissent comment les ressources accèdent aux rôles. Vous avez sans doute noté
  247. que nous n'avons défini aucune ressource particulière pour cet exemple, ce qui est plus
  248. simple pour illustrer comment les règles s'appliquent à toutes les ressources.
  249. <classname>Zend_Acl</classname> fournit une implémentation dans laquelle les règles
  250. doivent simplement être assignées du général au particulier, ce qui réduit le nombre de
  251. règles spécifiques à ajouter. Ceci grâce à l'héritage.
  252. </para>
  253. <note>
  254. <para>
  255. Généralement <classname>Zend_Acl</classname> se conforme à une règle donnée
  256. si et seulement si une règle plus spécifique ne s'applique pas.
  257. </para>
  258. </note>
  259. <para>
  260. En conséquence, on peut définir un nombre assez complexe de règles avec un nombre
  261. minimal de code. Pour définir les permissions comme définies ci-dessus&#160;:
  262. </para>
  263. <programlisting role="php"><![CDATA[
  264. $acl = new Zend_Acl();
  265. $roleinvite = new Zend_Acl_Role('invité');
  266. $acl->addRole($roleinvite);
  267. $acl->addRole(new Zend_Acl_Role('staff'), $roleinvite);
  268. $acl->addRole(new Zend_Acl_Role('editeur'), 'staff');
  269. $acl->addRole(new Zend_Acl_Role('administrateur'));
  270. // Invité peut uniquement voir le contenu
  271. $acl->allow($roleinvite, null, 'voir');
  272. /*
  273. ce qui précède peut aussi être écrit :
  274. $acl->allow('invité', null, 'voir');
  275. */
  276. // Staff hérite des privilèges de Invité, mais a aussi ses propres
  277. // privilèges
  278. $acl->allow('staff', null, array('edit', 'submit', 'relire'));
  279. // Editeur hérite les privilèges voir, modifier, soumettre,
  280. // et relire de Staff, mais a aussi besoin de certains privilèges
  281. $acl->allow('editeur', null, array('publier', 'archiver', 'supprimer'));
  282. // Administrateur hérite de rien, mais reçoit tous les privilèges
  283. $acl->allow('administrateur');
  284. ]]></programlisting>
  285. <para>
  286. Les valeurs <code>null</code> dans les appels <code>allow()</code> ci-dessus sont
  287. utilisées pour indiquer que les règles s'appliquent à toutes les ressources.
  288. </para>
  289. </sect2>
  290. <sect2 id="zend.acl.introduction.querying">
  291. <title>Interroger les ACL</title>
  292. <para>
  293. Nous avons maintenant une ACL flexible, qui peut être utilisée pour déterminer si
  294. l'objet appelant a les permissions pour réaliser les fonctions au sein de l'application
  295. web. Interroger l'ACL est assez simple en utilisant la méthode
  296. <code>isAllowed()</code>&#160;:
  297. </para>
  298. <programlisting role="php"><![CDATA[
  299. echo $acl->isAllowed('invité', null, 'voir') ?
  300. "autorisé" : "refusé";
  301. // autorisé
  302. echo $acl->isAllowed('staff', null, 'publier') ?
  303. "autorisé" : "refusé";
  304. // refusé
  305. echo $acl->isAllowed('staff', null, 'relire') ?
  306. "autorisé" : "refusé";
  307. // autorisé
  308. echo $acl->isAllowed('editeur', null, 'voir') ?
  309. "autorisé" : "refusé";
  310. // autorisé parce que hérité de Invité
  311. echo $acl->isAllowed('editeur', null, 'modifier') ?
  312. "autorisé" : "refusé";
  313. // refusé parce qu'il n'y a pas de règle pour 'modifier'
  314. echo $acl->isAllowed('administrateur', null, 'voir') ?
  315. "autorisé" : "refusé";
  316. // autorisé car administrateur est autorisé pour tout
  317. echo $acl->isAllowed('administrateur') ?
  318. "autorisé" : "refusé";
  319. // autorisé car administrateur est autorisé pour tout
  320. echo $acl->isAllowed('administrateur', null, 'modifier') ?
  321. "autorisé" : "refusé";
  322. // autorisé car administrateur est autorisé pour tout
  323. ]]></programlisting>
  324. </sect2>
  325. </sect1>