Programmer's Reference Guide

Введение

Настройка управления доступом

Точное управление доступом

Базовый ACL, как было описано в предыдущем разделе, демонстрирует, как различные привилегии могут быть разрешены в ACL (ко всем ресурсам). Но на практике средства управления доступом имеют тенденцию к тому, чтобы иметь исключения из правил и различную степень сложности. Zend_Acl позволяет производить детализацию просто и гибко.

Для CMS из нашего примера было установлено, что хотя группа 'сотрудник' подходит большинству пользователей, возникла необходимость в новой группе 'маркетинг', которая имела бы доступ к подписке и последним новостям в CMS. Группа в некоторой степени самодостаточна и будет иметь возможность публиковать и удалять как подписки, так и последние новости.

Кроме этого, необходимо, чтобы группе 'сотрудник' было разрешено просматривать новости, но запрещено редактировать их. И наконец, должно быть запрещено всем (в том числе и администраторам) помещать в архив любые 'объявления', если с момента добавления прошло только 1-2 дня.

В первую очередь мы модифицируем реестр ролей для отражения этих изменений. Мы определили, что группа 'маркетинг' имеет те же базовые права, что и 'сотрудник', поэтому мы определим 'маркетинг' таким образом, чтобы она наследовала права группы 'сотрудник':

  1. // Новая группа 'маркетинг' наследует права от группы 'сотрудник'
  2. $acl->addRole(new Zend_Acl_Role('marketing'), 'staff');

Далее обратите внимание, что указанные выше права доступа имеют отношение к особым ресурсам (например, "подписка", "последние новости"). Теперь добавим эти ресурсы:

  1. // Создаем ресурсы для этих ролей
  2.  
  3. // подписка
  4. $acl->add(new Zend_Acl_Resource('newsletter'));
  5.  
  6. // новости
  7. $acl->add(new Zend_Acl_Resource('news'));
  8.  
  9. // последние новости
  10. $acl->add(new Zend_Acl_Resource('latest'), 'news');
  11.  
  12. // объявления
  13. $acl->add(new Zend_Acl_Resource('announcement'), 'news');

Затем определяются более точные правила для целевых областей ACL.

  1. // Маркетинг должен иметь возможность публиковать и удалять подписку
  2. // и последние новости
  3. $acl->allow('marketing',
  4.             array('newsletter', 'latest'),
  5.             array('publish', 'archive'));
  6.  
  7. // Пользователю (и маркетингу через наследование), запрещено редактировать
  8. // последние новости
  9. $acl->deny('staff', 'latest', 'revise');
  10.  
  11. // Всем, включая администраторов, не разрешается удалять объявления
  12. $acl->deny(null, 'announcement', 'archive');

Теперь мы можем производить запросы к ACL с учетом последних изменений:

  1. echo $acl->isAllowed('staff', 'newsletter', 'publish') ?
  2.      "разрешен" : "запрещен";
  3. // запрещен
  4.  
  5. echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
  6.      "разрешен" : "запрещен";
  7. // разрешен
  8.  
  9. echo $acl->isAllowed('staff', 'latest', 'publish') ?
  10.      "разрешен" : "запрещен";
  11. // запрещен
  12.  
  13. echo $acl->isAllowed('marketing', 'latest', 'publish') ?
  14.      "разрешен" : "запрещен";
  15. // разрешен
  16.  
  17. echo $acl->isAllowed('marketing', 'latest', 'archive') ?
  18.      "разрешен" : "запрещен";
  19. // разрешен
  20.  
  21. echo $acl->isAllowed('marketing', 'latest', 'revise') ?
  22.      "разрешен" : "запрещен";
  23. // запрещен
  24.  
  25. echo $acl->isAllowed('editor', 'announcement', 'archive') ?
  26.      "разрешен" : "запрещен";
  27. // запрещен
  28.  
  29. echo $acl->isAllowed('administrator', 'announcement', 'archive') ?
  30.      "разрешен" : "запрещен";
  31. // запрещен

Удаление правил доступа

Для того, чтобы удалить одно или несколько правил из ACL, используйте методы removeAllow() или removeDeny(). Как и в случае с allow() и deny(), вы можете передавать NULL в качестве параметра, чтобы применить метод ко всем ролям, ресурсам, и/или привилегиям:

  1. // Убираем запрет на редактирование последних новостей для 'пользователя'
  2. // (и маркетинга через наследование)
  3. $acl->removeDeny('staff', 'latest', 'revise');
  4.  
  5. echo $acl->isAllowed('marketing', 'latest', 'revise') ?
  6.      "разрешен" : "запрещен";
  7. // разрешен
  8.  
  9. // Убираем разрешение на публикацию и удаление подписки для маркетинга
  10. $acl->removeAllow('marketing',
  11.                   'newsletter',
  12.                   array('publish', 'archive'));
  13.  
  14. echo $acl->isAllowed('marketing', 'newsletter', 'publish') ?
  15.      "разрешен" : "запрещен";
  16. // запрещен
  17.  
  18. echo $acl->isAllowed('marketing', 'newsletter', 'archive') ?
  19.      "разрешен" : "запрещен";
  20. // запрещен

Привилегии могут модифицироваться в порядке возрастания, как показано выше, но параметр NULL для привилегий переопределяет такой порядок изменений:

  1. // Разрешить маркетингу все действия над последними новостями
  2. $acl->allow('marketing', 'latest');
  3.  
  4. echo $acl->isAllowed('marketing', 'latest', 'publish') ?
  5.      "разрешен" : "запрещен";
  6. // разрешен
  7.  
  8. echo $acl->isAllowed('marketing', 'latest', 'archive') ?
  9.      "разрешен" : "запрещен";
  10. // разрешен
  11.  
  12. echo $acl->isAllowed('marketing', 'latest', 'anything') ?
  13.      "разрешен" : "запрещен";
  14. // разрешен

Введение

Comments

1.
$acl->allow('marketing',

array('newsletter', 'latest'),
array('publish', 'archive'));
Can the above statement be rewritten as
2.
$acl->allow('marketing','newsletter',array('publish', 'archive'));
$acl->allow('marketing','latest',array('publish', 'archive'));

I tested it. It didn't give any error but i'm asking this because does 2. will allocate more memory space then 1.?

Regards,
Shah Mubashir Hussain.
1.
$acl->allow('marketing',

array('newsletter', 'latest'),
array('publish', 'archive'));
Can the above statement be rewritten as
2.
$acl->allow('marketing','newsletter',array('publish', 'archive'));
$acl->allow('marketing','latest',array('publish', 'archive'));

I tested it. It didn't give any error but i'm asking this because does 2. will allocate more memory space then 1.?

Regards,
Shah Mubashir Hussain.
any suggestins on how to implement acl in a multitenant system where the roleid is unique within the scope of the tenant. the acl is complaining about the role already being added. i could think of appending the tenantid to the roleid before adding the role to the acl.
I wrote a simple two part tutorial on implementing Zend_Auth and Zend_ACL. Check it out at <a href="http://blog.intervestcorp.com/?p=12">blog.intervestcorp.com</a>.

+ Add A Comment

Please do not report issues via comments; use the ZF Issue Tracker.

If you have a JIRA/Crowd account, we suggest you login first before commenting.

  • BBCode is allowed in the comment markup

  • Select a Version

    Languages Available

    Components

    Search the Manual