1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.acl.introduction">
4 <title>Wprowadzenie</title>
7 <classname>Zend_Acl</classname> zapewnia lekką i elastyczną obsługę
8 implementacji list kontroli dostępu (<acronym>ACL</acronym>) do zarządzania
9 uprawnieniami. Ogólnie rzecz biorąc, aplikacja może używać list
10 <acronym>ACL</acronym> do kontrolowania dostępu do określonych chronionych
11 obiektów przez inne obiekty.
15 Dla celów tej dokumentacji:
21 <emphasis>zasób</emphasis> jest obiektem do
22 którego dostęp jest kontrolowany.
27 <emphasis>rola</emphasis> jest obiektem, który
28 może zażądać dostępu do zasobu.
34 Przystępnie mówiąc, <emphasis>role żądają dostępu do zasobów</emphasis>.
35 Na przykład, jeśli obsługujący parking samochodow zażąda dostępu do
36 samochodu, to ta osoba jest rolą, a samochód jest zasobem, więc dostęp
37 do samochodu nie musi zostać przyznany każdemu.
41 Dzięki określeniu i użyciu list kontroli dostępu (<acronym>ACL</acronym>),
42 aplikacja może kontrolować to, w jaki sposób żądające obiekty (role) mają
43 przydzielany dostęp do chronionych obiektów (zasobów).
46 <sect2 id="zend.acl.introduction.resources">
47 <title>O zasobach</title>
49 Tworzenie zasobu w Zend_Acl jest bardzo proste. <classname>Zend_Acl</classname> zapewnia
50 interfejs <classname>Zend_Acl_Resource_Interface</classname> aby ułatwić
51 programistom tworzenie zasobów w aplikacji. Klasa jedynie implementuje ten
52 interfejs, który składa się z jednej metody, <methodname>getResourceId()</methodname>,
53 dzięki ktorej <classname>Zend_Acl</classname> wie, że obiekt jest zasobem. Dodatkowo w
54 <classname>Zend_Acl</classname> dołączona jest klasa <classname>Zend_Acl_Resource</classname>,
55 która jest podstawową implementacją zasobu do użycia przez
56 programistów gdy jest to potrzebne.
59 <classname>Zend_Acl</classname> zapewnia drzewiastą strukturę, w której
60 mogą być dodawane zasoby (lub inaczej "obszary będące pod kontrolą").
61 Dzięki temu, że zasoby są przechowywane w strukturze drzewiastej, mogą
62 być one organizowane od ogólnych (od korzeni) do szczegółowych (do gałęzi).
63 Zapytanie do konkretnego zasobu automatycznie przeszuka całą
64 hierarchię zasobów, dla reguł przypisanych do przodka zasobów,
65 pozwalając na proste dziedziczenie reguł. Na przykład, jeśli
66 domyślna reguła ma być zastosowana do każdego budynku w mieście,
67 wystarczy przypisać regułę do miasta, zamiast przypisywać regułę to
68 każdego z budynków z osobna. Niektóre z budynków mogą wymagać
69 wyjątków od tej reguły i może być to osiągnięte w łatwy sposób w
70 <classname>Zend_Acl</classname> poprzez przypisanie takiej wyjątkowej reguły dla każdego z
71 budynków wymagających wyjątku. Zasób może dziedziczyć tylko od
72 jednego zasobu rodzica, a ten rodzic może także dziedziczyć tylko od
76 <classname>Zend_Acl</classname> także obsługuje przywileje dla zasobów
77 (np., "create", "read", "update", "delete") i programista może przypisać
78 reguły, które mają zastosowanie do wszystkich przywilejów, lub dla
79 konkretnych przywilejów dla jednego lub więcej zasobów.
83 <sect2 id="zend.acl.introduction.roles">
84 <title>O rolach</title>
86 Tak jak tworzenie zasobów, tworzenie ról także jest bardzo proste.
87 Wszystkie role muszą implementować interfejs <classname>Zend_Acl_Role_Interface</classname>
88 Ten interfejs składa się z jednej metody, <methodname>getRoleId()</methodname>,
89 dzięki ktorej Zend_Acl wie, że obiekt jest rolą. Dodatkowo w
90 Zend_Acl dołączona jest klasa <classname>Zend_Acl_Role</classname>,
91 która jest podstawową implementacją roli do użycia przez
92 programistów gdy jest to potrzebne.
95 W <classname>Zend_Acl</classname> rola może dziedziczyć z jednej lub więcej ról. Jest to po
96 to, aby możliwe było dziedziczenie zasad dla ról. Na przykład rola,
97 użytkownik "sally", może dziedziczyć z jednej lub więcej ról
98 rodziców, takich jak na przykład "editor" oraz "administrator".
99 Programista może przypisać reguły dla ról "editor" oraz
100 "administrator" osobno, a "sally" będzie dziedziczyć te reguły od
101 obu ról, bez konieczności przypisania reguł bezpośrednio dla
105 Chociaż możliwość dziedziczenia po wielu rolach jest bardzo
106 użyteczna, to takie dziedziczenie wprowadza pewien stopień
107 złożoności. Poniższy przykład ilustruje niejasny przypadek
108 dziedziczenia i pokazuje w jaki sposób <classname>Zend_Acl</classname> go rozwiązuje.
110 <example id="zend.acl.introduction.roles.example.multiple_inheritance">
111 <title>Dziedziczenie po wielu rolach</title>
113 Poniższy kod definiuje trzy podstawowe role, po których inne role
114 mogą dziedziczyć - "guest", "member",
115 oraz "admin". Następnie definiowana jest rola o
116 nazwie "someUser", ktora dziedziczy po zdefiniowanych
117 wcześniej trzech rolach. Ważna jest kolejność zdefiniowania tych
118 trzech ról w tablicy <varname>$parents</varname>. Gdy sprawdzamy
119 reguły dostępu, <classname>Zend_Acl</classname> szuka reguł zdefiniowanych nie tylko dla
120 danej roli (w tym przypadku someUser"), ale także
121 dla ról, po których ta rola dziedziczy (w tym przypadku
122 "guest", "member" oraz "admin"):
124 <programlisting language="php"><![CDATA[
125 $acl = new Zend_Acl();
127 $acl->addRole(new Zend_Acl_Role('guest'))
128 ->addRole(new Zend_Acl_Role('member'))
129 ->addRole(new Zend_Acl_Role('admin'));
131 $parents = array('guest', 'member', 'admin');
132 $acl->addRole(new Zend_Acl_Role('someUser'), $parents);
134 $acl->add(new Zend_Acl_Resource('someResource'));
136 $acl->deny('guest', 'someResource');
137 $acl->allow('member', 'someResource');
139 echo $acl->isAllowed('someUser', 'someResource') ? 'allowed' : 'denied';
142 Z tego względu, że nie ma zdefiniowanych reguł konkretnie dla
143 roli "someUser" oraz dla zasobu "someResource",
144 <classname>Zend_Acl</classname> musi szukać zasad, ktore mogą być zdefiniowane dla ról,
145 po których dziedziczy rola "someUser>". Wpierw
146 sprawdzana jest rola "admin", a dla niej nie ma
147 zdefiniowanej żadnej reguły dostępu. Następnie sprawdzana jest
148 rola "member" i <classname>Zend_Acl</classname> znajduje zdefiniowaną
149 regułę zezwalająca roli "member" na dostęp do zasobu
153 Jeśli <classname>Zend_Acl</classname> kontynuowałby sprawdzanie reguł zdefiniowanych dla
154 innych ról rodziców, znalazłby regułę zabraniającą roli
155 "guest" dostępu do zasobu "someResource".
156 Ten fakt wprowadza niejaność, ponieważ teraz rola
157 "someUser" ma zarówno dozwolony jak i zabroniony
158 dostęp do zasobu "someResource", z tego powodu, że
159 posiada odziedziczone po dwóch rolach reguły, które są ze sobą
163 <classname>Zend_Acl</classname> rozwiązuje tę niejaśność kończąc
164 zapytanie wtedy, gdy znajdzie pierwszą regułę, wprost pasującą do
165 zapytania. W tym przypadku, z tego względu, że rola "member" jest
166 sprawdzana przed rolą "guest", przykładowy kod
167 wyświetliłby "allowed".
172 Gdy określasz wielu rodziców dla roli, pamiętaj, że ostatni
173 rodzic na liście jest pierwszym przeszukiwanym rodzicem w
174 celu znalezienia ról pasujących do zapytania autoryzacyjnego.
179 <sect2 id="zend.acl.introduction.creating">
180 <title>Tworzenie list kontroli dostępu</title>
183 <acronym>ACL</acronym> może reprezentować dowolny zestaw fizycznych lub wirtualnych
184 obiektów których potrzebujesz. Dla celów prezentacji utworzymy <acronym>ACL</acronym>
185 dla prostego Systemu Zarządzania Treścią (Content Management System
186 - <acronym>CMS</acronym>), w którym różnymi obszarami zarządza kilka poziomów grup.
187 Aby utworzyć nowy obiekt <acronym>ACL</acronym>, utwórzmy instancję <acronym>ACL</acronym> bez parametrów:
190 <programlisting language="php"><![CDATA[
191 $acl = new Zend_Acl();
196 Dopóki programista nie określi reguły "allow", <classname>Zend_Acl</classname> zabroni
197 dostępu wszystkim rolom do wszystkich przywilejów dla wszystkich
203 <sect2 id="zend.acl.introduction.role_registry">
204 <title>Rejestrowanie ról</title>
207 System Zarządzania Treścią prawie zawsze potrzebuje hierarchii
208 uprawnień aby określić możliwości jego użytkowników.
209 Może być tu grupa 'Guest' aby pozwolić na limitowany dostęp
210 dla celów demonstracyjnych, grupa 'Staff' dla większości
211 użytkowników aplikacji <acronym>CMS</acronym>, którzy przeprowadzają najczęstsze
212 codzienne operacje, grupa 'Editor' dla tych odpowiedzialnych za
213 publikowanie, przeglądanie, archiwizowanie i usuwanie zawartości i
214 ostatecznie grupa 'Administrator', której zadania obejmują zarówno
215 zadania wszystkich innych grup, jak i zarządzanie ważnymi
216 informacjami, zarządzanie użytkownikami, konfigurację baz danych
217 oraz przeprowadzanie kopii zapasowych/eksportu danych.
218 Ten zestaw pozwoleń może być reprezentowany w rejestrze ról,
219 pozwalając każdej grupie dziedziczyć uprawnienia z grup rodziców,
220 a także umożliwiając każdej z grup posiadanie własnych unikalnych
221 uprawnień. Uprawnienia mogą być wyrażone w taki sposób:
224 <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
225 <title>Kontrola dostępu dla przykładowego CMS</title>
230 <entry>Unikalne uprawnienia</entry>
231 <entry>Dzidziczy uprawnienia od</entry>
242 <entry>Edit, Submit, Revise</entry>
246 <entry>Editor</entry>
247 <entry>Publish, Archive, Delete</entry>
251 <entry>Administrator</entry>
252 <entry>(posiada cały dostęp)</entry>
260 W tym przykładzie użyty jest obiekt <classname>Zend_Acl_Role</classname>, ale
261 dozwolony jest dowolny obiekt, który implementuje interfejs
262 <classname>Zend_Acl_Role_Interface</classname>. Te grupy mogą być dodane
263 do rejestru ról w taki sposób:
266 <programlisting language="php"><![CDATA[
267 $acl = new Zend_Acl();
269 // Dodajemy grupy do rejestru ról używając obiektu Zend_Acl_Role
270 // Grupa guest nie dziedziczy kontroli dostępu
271 $roleGuest = new Zend_Acl_Role('guest');
272 $acl->addRole($roleGuest);
274 // Grupa staff dzidziczy od grupy guest
275 $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
278 alternatywnie, powyższe mogłoby wyglądać tak:
279 $acl->addRole(new Zend_Acl_Role('staff'), 'guest');
282 // Grupa editor dziedziczy od grupy staff
283 $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
285 // Administrator nie dziedziczy kontroli dostępu
286 $acl->addRole(new Zend_Acl_Role('administrator'));
291 <sect2 id="zend.acl.introduction.defining">
292 <title>Definiowanie kontroli dostępu</title>
295 Teraz gdy <acronym>ACL</acronym> zawiera stosowne role, możemy ustalić reguły, które
296 definiują w jaki sposób role mają uzyskiwać dostęp do zasobów.
297 Mogłeś zauważyć, że nie zdefiniowaliśmy w tym przykładzie żadnych
298 konkretnych zasobów, co jest uproszczone w celu zilustrowania, że
299 reguły mają zastosowanie do wszystkich zasobów. <classname>Zend_Acl</classname> zapewnia
300 implementację dzięki której reguły mogą być przypisane od ogólnych
301 do szczegółowych, minimalizując ilość potrzebnych reguł, ponieważ
302 zasoby oraz role dziedziczą reguły, które są definiowane dla ich
308 W zasadzie <classname>Zend_Acl</classname> przestrzega danej reguły tylko wtedy, gdy
309 nie ma zastosowania bardziej szczegółowa reguła.
314 Możemy więc zdefiniować rozsądny kompleksowy zestaw reguł przy
315 minimalnej ilości kodu. Aby zastosować podstawowe uprawnienia
316 zdefiniowane wyżej zrób tak:
319 <programlisting language="php"><![CDATA[
320 $acl = new Zend_Acl();
322 $roleGuest = new Zend_Acl_Role('guest');
323 $acl->addRole($roleGuest);
324 $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
325 $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
326 $acl->addRole(new Zend_Acl_Role('administrator'));
328 // Grupa guest może tylko oglądać zawartość
329 $acl->allow($roleGuest, null, 'view');
332 alternatywnie, powyższe mogłoby wyglądać tak:
333 $acl->allow('guest', null, 'view');
336 // Grupa staff dzidziczy uprawnienia view od grupy guest,
337 // ale także potrzebuje dodatkowych uprawnień
338 $acl->allow('staff', null, array('edit', 'submit', 'revise'));
340 // Grupa editor dziedziczy uprawnienia view, edit, submit,
341 // oraz revise od grupy staff, ale także potrzebuje dodatkowych uprawnień
342 $acl->allow('editor', null, array('publish', 'archive', 'delete'));
344 // Administrator nie dziedziczy niczego, ale ma dostęp do wszystkich zasobów
345 $acl->allow('administrator');
349 Wartości <constant>NULL</constant> w powyższych wywołaniach metod
350 <methodname>allow()</methodname> oznaczają, że reguły dotyczą wszystkich zasobów.
355 <sect2 id="zend.acl.introduction.querying">
356 <title>Zapytania ACL</title>
359 Posiadamy teraz elastyczne <acronym>ACL</acronym>, ktore mogą być użyte do określenia,
360 czy żądająca osoba posiada uprawnienia do przeprowadzenia określonej
361 akcji w aplikacji web. Przeprowadzenie zapytań jest bardzo proste
362 poprzez użycie metody <methodname>isAllowed()</methodname>:
365 <programlisting language="php"><![CDATA[
366 echo $acl->isAllowed('guest', null, 'view') ?
367 "allowed" : "denied";
370 echo $acl->isAllowed('staff', null, 'publish') ?
371 "allowed" : "denied";
374 echo $acl->isAllowed('staff', null, 'revise') ?
375 "allowed" : "denied";
378 echo $acl->isAllowed('editor', null, 'view') ?
379 "allowed" : "denied";
380 // dozwolone ponieważ jest dziedziczone od gościa
382 echo $acl->isAllowed('editor', null, 'update') ?
383 "allowed" : "denied";
384 // zabronione ponieważ nie ma reguły dla 'update'
386 echo $acl->isAllowed('administrator', null, 'view') ?
387 "allowed" : "denied";
388 // dozwolone ponieważ administrator ma wszystkie uprawnienia
390 echo $acl->isAllowed('administrator') ?
391 "allowed" : "denied";
392 // dozwolone ponieważ administrator ma wszystkie uprawnienia
394 echo $acl->isAllowed('administrator', null, 'update') ?
395 "allowed" : "denied";
396 // dozwolone ponieważ administrator ma wszystkie uprawnienia