| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.acl.introduction">
- <title>Введение</title>
- <para>
- <classname>Zend_Acl</classname> предоставляет легковесную и гибкую реализацию списка прав
- доступа (<acronym>ACL</acronym>) и управления привилегиями. Приложение может использовать
- <acronym>ACL</acronym> для контроля доступа одних объектов к другим - защищенным.
- </para>
- <para>
- В рамках данной документации:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>Ресурс</emphasis> - объект, доступ к
- которому контролируется.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Роль</emphasis> - объект, который
- может запрашивать доступ к ресурсу.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Говоря проще, <emphasis>роли запрашивают доступ к ресурсам</emphasis>.
- Например, если парковщик запрашивает доступ к автомобилю, то
- парковщик - это роль, а автомобиль - ресурс, поскольку доступ к
- автомобилю не может предоставляться всем без исключения.
- </para>
- <para>
- Благодаря спецификации и использованию списка прав доступа (<acronym>ACL</acronym>)
- приложение может контролировать предоставление ролям доступа к ресурсам.
- </para>
- <sect2 id="zend.acl.introduction.resources">
- <title>Ресурсы</title>
- <para>
- Создать ресурс в <classname>Zend_Acl</classname> очень просто.
- <classname>Zend_Acl</classname> предоставляет
- интерфейс ресурса <classname>Zend_Acl_Resource_Interface</classname> для
- облегчения процесса создания ресурса. Этот интерфейс содержит только
- один метод, <methodname>getResourceId()</methodname>. Классу достаточно
- реализовывать этот интерфейс для того, чтобы <classname>Zend_Acl</classname>
- рассматривал объект этого класса как ресурс. Кроме того, <classname>Zend_Acl</classname>
- предоставляет <classname>Zend_Acl_Resource</classname> в качестве базового
- класса, который разработчики могут расширять по желанию.
- </para>
- <para>
- <classname>Zend_Acl</classname> предоставляет древовидную структуру, в которую могут
- добавляться различные ресурсы. В этой структуре они могут быть
- организованы от общих (корень дерева) к специфическим
- (листья дерева). При запросах к определенным ресурсам в иерархии
- будет выполнен автоматический поиск правил, относящихся
- к ресурсам-предкам, учитывающий простое наследование правил.
- Например, если некое общее
- правило должно действовать в каждом здании города, то проще
- прикрепить его к городу, чем крепить к каждому зданию в городе.
- Однако, для некоторых зданий могут потребоваться исключения из этого
- правила, в <classname>Zend_Acl</classname> это достигается путем закрепления исключений
- за каждым зданием, требующим исключений из правила.
- Ресурс может наследовать только от одного родительского ресурса,
- однако сам родительский ресурс может,
- в свою очередь, наследовать от другого родительского ресурса и т.д.
- </para>
- <para>
- <classname>Zend_Acl</classname> также поддерживает права доступа к ресурсам (например,
- "создание", "чтение", "обновление", "удаление"),
- разработчик может присваивать правила, которые будут влиять на все
- или определенные права доступа к ресурсу.
- </para>
- </sect2>
- <sect2 id="zend.acl.introduction.roles">
- <title>Роли</title>
- <para>
- Как и в случае с ресурсами, создавать роль тоже очень просто.
- Все роли должны реализовывать интерфейс
- <classname>Zend_Acl_Role_Interface</classname>. Этот интерфейс содержит
- единственный метод <methodname>getRoleId()</methodname>. Кроме того,
- <classname>Zend_Acl</classname>
- предоставляет <classname>Zend_Acl_Role</classname> в качестве базового класса,
- который разработчики могут расширять по желанию.
- </para>
- <para>
- В <classname>Zend_Acl</classname> роль может наследовать от одной или от нескольких
- ролей. Это реализовано для поддержки
- наследования правил между ролями. Например, пользовательская роль,
- такая как "Салли", может принадлежать одной или нескольким
- родительским ролям, таким как "редактор" и "администратор".
- Разработчик может привязывать правила к "редактору" и
- "администратору" раздельно, и "Салли" будет наследовать правила
- обоих ролей. Нет необходимости привязывать правила непосредственно
- к "Салли".
- </para>
- <para>
- Хотя множественное наследование ролей - очень полезная возможность,
- она также усложняет разработку. Следующий пример демонстрирует
- неопределенное условие и показывает, как <classname>Zend_Acl</classname> решает эту
- проблему.
- </para>
- <example id="zend.acl.introduction.roles.example.multiple_inheritance">
- <title>Множественное наследование ролей</title>
- <para>
- Следующий код определяет три базовые роли:
- "guest", "member" и
- "admin", от которых будут наследовать другие роли.
- Далее создается "someUser", он наследует от этих
- только что созданных трех ролей. Порядок, в котором эти роли
- появляются в массиве <varname>$parents</varname>,
- важен. При необходимости <classname>Zend_Acl</classname> ищет правила доступа не
- только для запрашиваемых ролей (в нашем случае,
- "someUser"), но и для ролей, от которых
- запрашиваемая роль унаследована
- (в нашем примере, "guest", "member" и
- "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') ? 'разрешен' : 'запрещен';
- ]]></programlisting>
- <para>
- Поскольку нет правил, определенных специально для роли
- "someUser" и ресурса
- "someResource", то <classname>Zend_Acl</classname> должен производить
- поиск правил, которые могут быть определены для ролей,
- от которых "someUser" наследуется. Сперва
- проверяется роль "admin", и обнаруживается, что
- для нее не определены правила доступа. Затем проверяется роль
- "member", и <classname>Zend_Acl</classname> обнаруживает, что есть правило
- разрешающее доступ для "member" к
- "someResource".
- </para>
- <para>
- Если бы <classname>Zend_Acl</classname> продолжил поиск правил, определенных для
- родительских ролей, то обнаружил бы, что для
- "guest" запрещен доступ к
- "someResource". Это пример показывает противоречие,
- так как теперь для "someUser" доступ к
- "someResource" разрешен и запрещен одновременно.
- Конфликт произошел по причине наследования от нескольких ролей.
- </para>
- <para>
- <classname>Zend_Acl</classname> решает эту неоднозначность, завершая запрос, как
- только находит первое правило, которое может быть применено к запросу.
- В этом случае, если роль "member"
- проверяется раньше, чем роль "guest", то
- данный пример выведет "разрешен".
- </para>
- </example>
- <note>
- <para>
- При определении нескольких родительских ролей, не
- забывайте, что последний указанный родитель
- будет первым в списке поиска правил для запроса авторизации.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.acl.introduction.creating">
- <title>Создание списка контроля доступа (ACL)</title>
- <para>
- Список контроля доступа (<acronym>ACL</acronym>) может представлять собой любое
- множество физических или виртуальных объектов. В целях
- демонстрации, мы создадим базовый
- функционал <acronym>ACL</acronym> для системы управления содержимым
- (<acronym>CMS</acronym>), который будет поддерживать нескольких уровней групп к
- множеству областей. Чтобы создать новый объект <acronym>ACL</acronym>, производим
- инстанцирование <acronym>ACL</acronym> без параметров:
- </para>
- <programlisting language="php"><![CDATA[
- $acl = new Zend_Acl();
- ]]></programlisting>
- <note>
- <para>
- До тех пор, пока разработчик не определит какое-либо правило,
- разрешающее доступ, <classname>Zend_Acl</classname> отказывает всем ролям в доступе
- ко всем привилегиям на все ресурсы.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.acl.introduction.role_registry">
- <title>Регистрация ролей</title>
- <para>
- <acronym>CMS</acronym> почти всегда нуждаются в иерархии
- доступа для определения авторских возможностей своих пользователей.
- Это может быть группа "Гость",
- предоставляющая ограниченный доступ для демонстрации, группа
- "Сотрудник" - группа большинства пользователей <acronym>CMS</acronym>,
- которые производят каждодневные операции, группа "Редактор" - для
- тех кто публикует и редактирует, архивирует и удаляет контент, и,
- наконец, группа "Администратор", участники которой могут выполнять
- все операции, которые доступны участникам других групп, а также
- управлять закрытой информацией, пользователями,
- конфигурацией адинистративной части, делать резервное
- копирование данных и их экспорт.
- Этот набор прав доступа может быть представлен в реестре ролей,
- позволяя каждой группе наследовать привилегии
- родительской группы, при этом имея индивидуальные права доступа.
- Права доступа могут быть изображены в следующем виде:
- </para>
- <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
- <title>Контроль за доступом для демонстрационной CMS</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Название</entry>
- <entry>Индивидуальные права</entry>
- <entry>Права, унаследованные от</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>Гость (guest)</entry>
- <entry>Просмотр (view)</entry>
- <entry>Не определено</entry>
- </row>
- <row>
- <entry>Сотрудник (staff)</entry>
- <entry>Редактирование (edit), предложение на публикацию (submit), исправление
- (revise)</entry>
- <entry>Гость</entry>
- </row>
- <row>
- <entry>Редактор (editor)</entry>
- <entry>Публикация (publish), архивирование (archive), удаление (delete)</entry>
- <entry>Сотрудник</entry>
- </row>
- <row>
- <entry>Администратор (administrator)</entry>
- <entry>(Обладает всеми правами)</entry>
- <entry>Не определено</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Для этого примера мы используем <classname>Zend_Acl_Role</classname>, но можно
- было бы использовать любой другой класс,
- реализующий интерфейс <classname>Zend_Acl_Role_Interface</classname>.
- Эти группы могут быть добавлены в реестр ролей
- следующим образом:
- </para>
- <programlisting language="php"><![CDATA[
- $acl = new Zend_Acl();
- // Добавление групп в реестр ролей с использованием Zend_Acl_Role
- // Гость не наследует управление доступом
- $roleGuest = new Zend_Acl_Role('guest');
- $acl->addRole($roleGuest);
- // Сотрудник наследует от гостя
- $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
- /*
- Делает то же самое, что и
- $acl->addRole(new Zend_Acl_Role('staff'), 'guest');
- */
- // Редактор наследует от сотрудника
- $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
- // Администатор не наследует управление доступом
- $acl->addRole(new Zend_Acl_Role('administrator'));
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.acl.introduction.defining">
- <title>Определение контроля доступа</title>
- <para>
- Теперь, когда <acronym>ACL</acronym> содержит все необходимые роли, можно определить
- правила, по которым роли будут иметь доступ к ресурсам. Вы, должно
- быть, заметили, что мы не определили ни одного отдельного ресурса
- для этого примера, это упрощает демонстрацию того, что правила
- применяются ко всем ресурсам. <classname>Zend_Acl</classname> предоставляет реализацию,
- посредством которой правила должны передаваться
- от общих к специфическим, минимизируя таким образом количество
- необходимых правил, так как
- ресурсы и роли наследуют правила, которые определены для их предков.
- </para>
- <note>
- <para>
- В целом, <classname>Zend_Acl</classname> подчиняется правилу, только если более
- точное правило не применимо.
- </para>
- </note>
- <para>
- В результате мы можем определить умеренно сложный набор правил
- минимальным кодом. Чтобы определить базовые права доступа, описанные
- выше:
- </para>
- <programlisting language="php"><![CDATA[<?php
- require_once 'Zend/Acl.php';
- $acl = new Zend_Acl();
- require_once 'Zend/Acl/Role.php';
- $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'));
- // Гость может только просматривать контент
- $acl->allow($roleGuest, null, 'view');
- /* другим способом, предыдущий блок кода может быть записан в таком виде:
- $acl->allow('guest', null, 'view');
- //*/
- // Сотрудник наследует привилегии просмотра у Гостя,
- // но также нуждается в дополнительных привилегиях
- $acl->allow('staff', null, array('edit', 'submit', 'revise'));
- // Редактор наследует привилегии просмотра, редактирования,
- // отправки и исправлений у Посетителя
- // но также нуждается в дополнительных привилегиях
- $acl->allow('editor', null, array('publish', 'archive', 'delete'));
- // Администратор не наследует ничего, но обладает всеми привилегиями
- $acl->allow('administrator');]]></programlisting>
- <para>
- Значение <constant>NULL</constant> в вызовах
- <methodname>allow()</methodname> в этом примере используется для
- указания того, что правила, предоставляющие доступ,
- действительны для всех ресурсов.
- </para>
- </sect2>
- <sect2 id="zend.acl.introduction.querying">
- <title>Запросы к ACL</title>
- <para>
- Теперь у нас есть гибкий <acronym>ACL</acronym>, который может использоваться для
- определения того, достаточно ли прав имеет запрашивающий, чтобы
- производить действия в веб-приложении. Используя метод
- <methodname>isAllowed()</methodname>, производить запросы довольно просто:
- </para>
- <programlisting language="php"><![CDATA[
- echo $acl->isAllowed('guest', null, 'view') ?
- "разрешен" : "запрещен";
- // разрешен
- echo $acl->isAllowed('staff', null, 'publish') ?
- "разрешен" : "запрещен";
- // запрещен
- echo $acl->isAllowed('staff', null, 'revise') ?
- "разрешен" : "запрещен";
- // разрешен
- echo $acl->isAllowed('editor', null, 'view') ?
- "разрешен" : "запрещен";
- // разрешен потому, что редактор наследует от гостя
- echo $acl->isAllowed('editor', null, 'update') ?
- "разрешен" : "запрещен";
- // запрещен потому, что нет правила, разрешающего обновление (update)
- echo $acl->isAllowed('administrator', null, 'view') ?
- "разрешен" : "запрещен";
- // разрешен потому, что администратор обладает всеми привилегиями
- echo $acl->isAllowed('administrator') ?
- "разрешен" : "запрещен";
- // разрешен потому, что администратор обладает всеми привилегиями
- echo $acl->isAllowed('administrator', null, 'update') ?
- "разрешен" : "запрещен";
- // разрешен потому, что администратор обладает всеми привилегиями
- ]]></programlisting>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|