| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.acl.introduction">
- <title>Wprowadzenie</title>
- <para>
- <classname>Zend_Acl</classname> zapewnia lekką i elastyczną obsługę
- implementacji list kontroli dostępu (<acronym>ACL</acronym>) do zarządzania
- uprawnieniami. Ogólnie rzecz biorąc, aplikacja może używać list
- <acronym>ACL</acronym> do kontrolowania dostępu do określonych chronionych
- obiektów przez inne obiekty.
- </para>
- <para>
- Dla celów tej dokumentacji:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>zasób</emphasis> jest obiektem do
- którego dostęp jest kontrolowany.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>rola</emphasis> jest obiektem, który
- może zażądać dostępu do zasobu.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Przystępnie mówiąc, <emphasis>role żądają dostępu do zasobów</emphasis>.
- Na przykład, jeśli obsługujący parking samochodow zażąda dostępu do
- samochodu, to ta osoba jest rolą, a samochód jest zasobem, więc dostęp
- do samochodu nie musi zostać przyznany każdemu.
- </para>
- <para>
- Dzięki określeniu i użyciu list kontroli dostępu (<acronym>ACL</acronym>),
- aplikacja może kontrolować to, w jaki sposób żądające obiekty (role) mają
- przydzielany dostęp do chronionych obiektów (zasobów).
- </para>
- <sect2 id="zend.acl.introduction.resources">
- <title>O zasobach</title>
- <para>
- Tworzenie zasobu w Zend_Acl jest bardzo proste. <classname>Zend_Acl</classname> zapewnia
- interfejs <classname>Zend_Acl_Resource_Interface</classname> aby ułatwić
- programistom tworzenie zasobów w aplikacji. Klasa jedynie implementuje ten
- interfejs, który składa się z jednej metody, <methodname>getResourceId()</methodname>,
- dzięki ktorej <classname>Zend_Acl</classname> wie, że obiekt jest zasobem. Dodatkowo w
- <classname>Zend_Acl</classname> dołączona jest klasa <classname>Zend_Acl_Resource</classname>,
- która jest podstawową implementacją zasobu do użycia przez
- programistów gdy jest to potrzebne.
- </para>
- <para>
- <classname>Zend_Acl</classname> zapewnia drzewiastą strukturę, w której
- mogą być dodawane zasoby (lub inaczej "obszary będące pod kontrolą").
- Dzięki temu, że zasoby są przechowywane w strukturze drzewiastej, mogą
- być one organizowane od ogólnych (od korzeni) do szczegółowych (do gałęzi).
- Zapytanie do konkretnego zasobu automatycznie przeszuka całą
- hierarchię zasobów, dla reguł przypisanych do przodka zasobów,
- pozwalając na proste dziedziczenie reguł. Na przykład, jeśli
- domyślna reguła ma być zastosowana do każdego budynku w mieście,
- wystarczy przypisać regułę do miasta, zamiast przypisywać regułę to
- każdego z budynków z osobna. Niektóre z budynków mogą wymagać
- wyjątków od tej reguły i może być to osiągnięte w łatwy sposób w
- <classname>Zend_Acl</classname> poprzez przypisanie takiej wyjątkowej reguły dla każdego z
- budynków wymagających wyjątku. Zasób może dziedziczyć tylko od
- jednego zasobu rodzica, a ten rodzic może także dziedziczyć tylko od
- jednego zasobu itd.
- </para>
- <para>
- <classname>Zend_Acl</classname> także obsługuje przywileje dla zasobów
- (np., "create", "read", "update", "delete") i programista może przypisać
- reguły, które mają zastosowanie do wszystkich przywilejów, lub dla
- konkretnych przywilejów dla jednego lub więcej zasobów.
- </para>
- </sect2>
- <sect2 id="zend.acl.introduction.roles">
- <title>O rolach</title>
- <para>
- Tak jak tworzenie zasobów, tworzenie ról także jest bardzo proste.
- Wszystkie role muszą implementować interfejs <classname>Zend_Acl_Role_Interface</classname>
- Ten interfejs składa się z jednej metody, <methodname>getRoleId()</methodname>,
- dzięki ktorej Zend_Acl wie, że obiekt jest rolą. Dodatkowo w
- Zend_Acl dołączona jest klasa <classname>Zend_Acl_Role</classname>,
- która jest podstawową implementacją roli do użycia przez
- programistów gdy jest to potrzebne.
- </para>
- <para>
- W <classname>Zend_Acl</classname> rola może dziedziczyć z jednej lub więcej ról. Jest to po
- to, aby możliwe było dziedziczenie zasad dla ról. Na przykład rola,
- użytkownik "sally", może dziedziczyć z jednej lub więcej ról
- rodziców, takich jak na przykład "editor" oraz "administrator".
- Programista może przypisać reguły dla ról "editor" oraz
- "administrator" osobno, a "sally" będzie dziedziczyć te reguły od
- obu ról, bez konieczności przypisania reguł bezpośrednio dla
- "sally".
- </para>
- <para>
- Chociaż możliwość dziedziczenia po wielu rolach jest bardzo
- użyteczna, to takie dziedziczenie wprowadza pewien stopień
- złożoności. Poniższy przykład ilustruje niejasny przypadek
- dziedziczenia i pokazuje w jaki sposób <classname>Zend_Acl</classname> go rozwiązuje.
- </para>
- <example id="zend.acl.introduction.roles.example.multiple_inheritance">
- <title>Dziedziczenie po wielu rolach</title>
- <para>
- Poniższy kod definiuje trzy podstawowe role, po których inne role
- mogą dziedziczyć - "guest", "member",
- oraz "admin". Następnie definiowana jest rola o
- nazwie "someUser", ktora dziedziczy po zdefiniowanych
- wcześniej trzech rolach. Ważna jest kolejność zdefiniowania tych
- trzech ról w tablicy <varname>$parents</varname>. Gdy sprawdzamy
- reguły dostępu, <classname>Zend_Acl</classname> szuka reguł zdefiniowanych nie tylko dla
- danej roli (w tym przypadku someUser"), ale także
- dla ról, po których ta rola dziedziczy (w tym przypadku
- "guest", "member" oraz "admin"):
- </para>
- <programlisting language="php"><![CDATA[
- $acl = new Zend_Acl();
- $acl->addRole(new Zend_Acl_Role('guest'))
- ->addRole(new Zend_Acl_Role('member'))
- ->addRole(new Zend_Acl_Role('admin'));
- $parents = array('guest', 'member', 'admin');
- $acl->addRole(new Zend_Acl_Role('someUser'), $parents);
- $acl->add(new Zend_Acl_Resource('someResource'));
- $acl->deny('guest', 'someResource');
- $acl->allow('member', 'someResource');
- echo $acl->isAllowed('someUser', 'someResource') ? 'allowed' : 'denied';
- ]]></programlisting>
- <para>
- Z tego względu, że nie ma zdefiniowanych reguł konkretnie dla
- roli "someUser" oraz dla zasobu "someResource",
- <classname>Zend_Acl</classname> musi szukać zasad, ktore mogą być zdefiniowane dla ról,
- po których dziedziczy rola "someUser>". Wpierw
- sprawdzana jest rola "admin", a dla niej nie ma
- zdefiniowanej żadnej reguły dostępu. Następnie sprawdzana jest
- rola "member" i <classname>Zend_Acl</classname> znajduje zdefiniowaną
- regułę zezwalająca roli "member" na dostęp do zasobu
- "someResource".
- </para>
- <para>
- Jeśli <classname>Zend_Acl</classname> kontynuowałby sprawdzanie reguł zdefiniowanych dla
- innych ról rodziców, znalazłby regułę zabraniającą roli
- "guest" dostępu do zasobu "someResource".
- Ten fakt wprowadza niejaność, ponieważ teraz rola
- "someUser" ma zarówno dozwolony jak i zabroniony
- dostęp do zasobu "someResource", z tego powodu, że
- posiada odziedziczone po dwóch rolach reguły, które są ze sobą
- sprzeczne.
- </para>
- <para>
- <classname>Zend_Acl</classname> rozwiązuje tę niejaśność kończąc
- zapytanie wtedy, gdy znajdzie pierwszą regułę, wprost pasującą do
- zapytania. W tym przypadku, z tego względu, że rola "member" jest
- sprawdzana przed rolą "guest", przykładowy kod
- wyświetliłby "allowed".
- </para>
- </example>
- <note>
- <para>
- Gdy określasz wielu rodziców dla roli, pamiętaj, że ostatni
- rodzic na liście jest pierwszym przeszukiwanym rodzicem w
- celu znalezienia ról pasujących do zapytania autoryzacyjnego.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.acl.introduction.creating">
- <title>Tworzenie list kontroli dostępu</title>
- <para>
- <acronym>ACL</acronym> może reprezentować dowolny zestaw fizycznych lub wirtualnych
- obiektów których potrzebujesz. Dla celów prezentacji utworzymy <acronym>ACL</acronym>
- dla prostego Systemu Zarządzania Treścią (Content Management System
- - <acronym>CMS</acronym>), w którym różnymi obszarami zarządza kilka poziomów grup.
- Aby utworzyć nowy obiekt <acronym>ACL</acronym>, utwórzmy instancję <acronym>ACL</acronym> bez parametrów:
- </para>
- <programlisting language="php"><![CDATA[
- $acl = new Zend_Acl();
- ]]></programlisting>
- <note>
- <para>
- Dopóki programista nie określi reguły "allow", <classname>Zend_Acl</classname> zabroni
- dostępu wszystkim rolom do wszystkich przywilejów dla wszystkich
- zasobów.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.acl.introduction.role_registry">
- <title>Rejestrowanie ról</title>
- <para>
- System Zarządzania Treścią prawie zawsze potrzebuje hierarchii
- uprawnień aby określić możliwości jego użytkowników.
- Może być tu grupa 'Guest' aby pozwolić na limitowany dostęp
- dla celów demonstracyjnych, grupa 'Staff' dla większości
- użytkowników aplikacji <acronym>CMS</acronym>, którzy przeprowadzają najczęstsze
- codzienne operacje, grupa 'Editor' dla tych odpowiedzialnych za
- publikowanie, przeglądanie, archiwizowanie i usuwanie zawartości i
- ostatecznie grupa 'Administrator', której zadania obejmują zarówno
- zadania wszystkich innych grup, jak i zarządzanie ważnymi
- informacjami, zarządzanie użytkownikami, konfigurację baz danych
- oraz przeprowadzanie kopii zapasowych/eksportu danych.
- Ten zestaw pozwoleń może być reprezentowany w rejestrze ról,
- pozwalając każdej grupie dziedziczyć uprawnienia z grup rodziców,
- a także umożliwiając każdej z grup posiadanie własnych unikalnych
- uprawnień. Uprawnienia mogą być wyrażone w taki sposób:
- </para>
- <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
- <title>Kontrola dostępu dla przykładowego CMS</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Nazwa</entry>
- <entry>Unikalne uprawnienia</entry>
- <entry>Dzidziczy uprawnienia od</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>Guest</entry>
- <entry>View</entry>
- <entry>N/A</entry>
- </row>
- <row>
- <entry>Staff</entry>
- <entry>Edit, Submit, Revise</entry>
- <entry>Guest</entry>
- </row>
- <row>
- <entry>Editor</entry>
- <entry>Publish, Archive, Delete</entry>
- <entry>Staff</entry>
- </row>
- <row>
- <entry>Administrator</entry>
- <entry>(posiada cały dostęp)</entry>
- <entry>N/A</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- W tym przykładzie użyty jest obiekt <classname>Zend_Acl_Role</classname>, ale
- dozwolony jest dowolny obiekt, który implementuje interfejs
- <classname>Zend_Acl_Role_Interface</classname>. Te grupy mogą być dodane
- do rejestru ról w taki sposób:
- </para>
- <programlisting language="php"><![CDATA[
- $acl = new Zend_Acl();
- // Dodajemy grupy do rejestru ról używając obiektu Zend_Acl_Role
- // Grupa guest nie dziedziczy kontroli dostępu
- $roleGuest = new Zend_Acl_Role('guest');
- $acl->addRole($roleGuest);
- // Grupa staff dzidziczy od grupy guest
- $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
- /*
- alternatywnie, powyższe mogłoby wyglądać tak:
- $acl->addRole(new Zend_Acl_Role('staff'), 'guest');
- */
- // Grupa editor dziedziczy od grupy staff
- $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
- // Administrator nie dziedziczy kontroli dostępu
- $acl->addRole(new Zend_Acl_Role('administrator'));
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.acl.introduction.defining">
- <title>Definiowanie kontroli dostępu</title>
- <para>
- Teraz gdy <acronym>ACL</acronym> zawiera stosowne role, możemy ustalić reguły, które
- definiują w jaki sposób role mają uzyskiwać dostęp do zasobów.
- Mogłeś zauważyć, że nie zdefiniowaliśmy w tym przykładzie żadnych
- konkretnych zasobów, co jest uproszczone w celu zilustrowania, że
- reguły mają zastosowanie do wszystkich zasobów. <classname>Zend_Acl</classname> zapewnia
- implementację dzięki której reguły mogą być przypisane od ogólnych
- do szczegółowych, minimalizując ilość potrzebnych reguł, ponieważ
- zasoby oraz role dziedziczą reguły, które są definiowane dla ich
- przodków.
- </para>
- <note>
- <para>
- W zasadzie <classname>Zend_Acl</classname> przestrzega danej reguły tylko wtedy, gdy
- nie ma zastosowania bardziej szczegółowa reguła.
- </para>
- </note>
- <para>
- Możemy więc zdefiniować rozsądny kompleksowy zestaw reguł przy
- minimalnej ilości kodu. Aby zastosować podstawowe uprawnienia
- zdefiniowane wyżej zrób tak:
- </para>
- <programlisting language="php"><![CDATA[
- $acl = new Zend_Acl();
- $roleGuest = new Zend_Acl_Role('guest');
- $acl->addRole($roleGuest);
- $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
- $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
- $acl->addRole(new Zend_Acl_Role('administrator'));
- // Grupa guest może tylko oglądać zawartość
- $acl->allow($roleGuest, null, 'view');
- /*
- alternatywnie, powyższe mogłoby wyglądać tak:
- $acl->allow('guest', null, 'view');
- */
- // Grupa staff dzidziczy uprawnienia view od grupy guest,
- // ale także potrzebuje dodatkowych uprawnień
- $acl->allow('staff', null, array('edit', 'submit', 'revise'));
- // Grupa editor dziedziczy uprawnienia view, edit, submit,
- // oraz revise od grupy staff, ale także potrzebuje dodatkowych uprawnień
- $acl->allow('editor', null, array('publish', 'archive', 'delete'));
- // Administrator nie dziedziczy niczego, ale ma dostęp do wszystkich zasobów
- $acl->allow('administrator');
- ]]></programlisting>
- <para>
- Wartości <constant>NULL</constant> w powyższych wywołaniach metod
- <methodname>allow()</methodname> oznaczają, że reguły dotyczą wszystkich zasobów.
- </para>
- </sect2>
- <sect2 id="zend.acl.introduction.querying">
- <title>Zapytania ACL</title>
- <para>
- Posiadamy teraz elastyczne <acronym>ACL</acronym>, ktore mogą być użyte do określenia,
- czy żądająca osoba posiada uprawnienia do przeprowadzenia określonej
- akcji w aplikacji web. Przeprowadzenie zapytań jest bardzo proste
- poprzez użycie metody <methodname>isAllowed()</methodname>:
- </para>
- <programlisting language="php"><![CDATA[
- echo $acl->isAllowed('guest', null, 'view') ?
- "allowed" : "denied";
- // dozwolone
- echo $acl->isAllowed('staff', null, 'publish') ?
- "allowed" : "denied";
- // zabronione
- echo $acl->isAllowed('staff', null, 'revise') ?
- "allowed" : "denied";
- // dozwolone
- echo $acl->isAllowed('editor', null, 'view') ?
- "allowed" : "denied";
- // dozwolone ponieważ jest dziedziczone od gościa
- echo $acl->isAllowed('editor', null, 'update') ?
- "allowed" : "denied";
- // zabronione ponieważ nie ma reguły dla 'update'
- echo $acl->isAllowed('administrator', null, 'view') ?
- "allowed" : "denied";
- // dozwolone ponieważ administrator ma wszystkie uprawnienia
- echo $acl->isAllowed('administrator') ?
- "allowed" : "denied";
- // dozwolone ponieważ administrator ma wszystkie uprawnienia
- echo $acl->isAllowed('administrator', null, 'update') ?
- "allowed" : "denied";
- // dozwolone ponieważ administrator ma wszystkie uprawnienia
- ]]></programlisting>
- </sect2>
- </sect1>
|