Соответствует ли Zend ACL моим потребностям?

Я основывал свое приложение на Zend Framework. Я использую Zend_Auth для аутентификации, но я не уверен, что Zend_Acl будет работать для меня, потому что, откровенно говоря, примеры, которые я видел, слишком упрощены для моих нужд или смущают меня.

Я рассматриваю элементы в своем приложении как ресурсы, и эти ресурсы могут иметь Привилегии. Роли, содержащие ресурсные привилегии, динамически определяются для пользователей. Я храню эту информацию в нормализованных таблицах.

  1. Пользователи имеют роль
  2. Роль может иметь несколько ресурсов
  3. Ресурсы могут иметь несколько Привилегий

Роли – это действительно просто коллекции ресурсных привилегий без иерархии. Примером ресурса будет «Страница». Каждый может просматривать страницы, но аутентифицированный пользователь должен будет «добавлять», «редактировать» или «удалять» привилегии, чтобы делать что-либо еще со страницами.

Является ли это сеткой с Zend ACL? Думаю ли я ACL таким образом, что это создаст проблемы для меня?


Мое решение

Typeonerror получает кредит, но вот мое конкретное решение.

Я расширил Zend_Acl чтобы упростить мое использование, потому что я загружаю только роль текущего пользователя:

 class My_Acl extends Zend_Acl { protected $_role_id; public function setRole($role_id) { $this->_role_id = $role_id; return $this->addRole($role_id); } public function getRole() { return $this->_role_id; } public function deny($resource, $privilege) { return parent::deny($this->_role_id, $resource, $privilege); } public function allow($resource, $privilege) { return parent::allow($this->_role_id, $resource, $privilege); } public function isAllowed($resource, $privilege) { return parent::isAllowed($this->_role_id, $resource, $privilege); } } 

Чтобы заполнить ACL, я выполняю запрос, который возвращает столбцы resource , privilege и role_id . role_id имеет значение null в результирующем наборе, если роль пользователя не имеет этой привилегии.

 $acl = new My_Acl(); $auth = Zend_Auth::getInstance(); if ($auth->hasIdentity()) { $userInfo = $auth->getStorage()->read(); $acl->setRole($userInfo->role_id); } else { $acl->setRole(''); } // QUERY HERE foreach ($privileges as $privilege) { if (!$acl->has($privilege['resource'])) { $acl->addResource($privilege['resource']); } if (is_null($privilege['role_id'])) { $acl->deny($privilege['resource'], $privilege['privilege']); } else { $acl->allow($privilege['resource'], $privilege['privilege']); } } 

Related of "Соответствует ли Zend ACL моим потребностям?"

Именно так оно и работает, и я думаю, что вы думаете об этом точно. Вы можете добавить свои ресурсы, а затем добавить привилегии, чтобы разрешить доступ к определенным ролям пользователей. Например, в моей CMS у меня есть «разработчики», «администраторы» и «пользователи». В приведенном ниже коде я добавляю общий доступ, а затем удаляю некоторые действия и определенные методы из определенного доступа пользователя. Конечно, это довольно специфично для моего приложения, но в основном вам нужно получить роль пользователя из auth-> getIdentity () (или аналогичного), а затем добавить свои роли / ресурсы из базы данных.

 <?php /** * @author Benjamin Borowski <ben.borowski@typeoneerror.com> * @copyright Copyright (c) Typeoneerror Studios http://typeoneerror.com * @version $Id$ * @category Typeoneerror * @package Acl */ /** * Defines basic roles and resources for an application as * well as a Content Management System (CMS). * * Zend_Acl provides a lightweight and flexible access control list * (ACL) implementation for privileges management. * * {@inheritdoc} * * @author Benjamin Borowski <ben.borowski@typeoneerror.com> * @copyright Copyright (c) Typeoneerror Studios http://typeoneerror.com * @version $Id$ * @category Typeoneerror * @package Acl */ class Typeoneerror_Acl extends Zend_Acl { /** * Constructor function. * * Creates basic roles and resources and adds them to Acl. * * {@inheritdoc} * * @return Typeoneerror_Acl */ public function __construct() { //--------------------------------------- // ROLES //--------------------------------------- $this->_addRole("guest") ->_addRole("member", "guest") ->_addRole("admin", "member") ->_addRole("developer", "admin"); //--------------------------------------- // FRONT-END RESOURCES //--------------------------------------- $this->_add("default"); //--------------------------------------- // BACK-END RESOURCES //--------------------------------------- $this->_add("cms") ->_add("cms:articles", "cms") ->_add("cms:auth", "cms") ->_add("cms:bug-report", "cms") ->_add("cms:calendar", "cms") ->_add("cms:categories", "cms") ->_add("cms:comments", "cms") ->_add("cms:error", "cms") ->_add("cms:galleries", "cms") ->_add("cms:pages", "cms") ->_add("cms:photos", "cms") ->_add("cms:tags", "cms") ->_add("cms:users", "cms"); //--------------------------------------- // GUEST PERMISSIONS //--------------------------------------- $this->allow("guest", "default") ->allow("guest", "cms:auth") // -- guests can attempt to log-in ->allow("guest", "cms:error") // -- guests can break stuff ->allow("guest", "cms:bug-report"); // -- guests can report bugs //--------------------------------------- // ADMIN PERMISSIONS //--------------------------------------- $this->allow("admin") ->deny("admin", null, "purge") // -- admins cannot purge (normally) ->deny("admin", "cms:comments", "create"); // -- only devs can create a comment //--------------------------------------- // DEVELOPER PERMISSIONS //--------------------------------------- $this->allow("developer"); // -- unrestricted access return $this; } /** * Adds a Resource having an identifier unique to the ACL. * * @param Zend_Acl_Resource_Interface $resource The resource to add * @param Zend_Acl_Resource_Interface|string $parent A parent resource it inherits from * @return Typeoneerror_Acl Reference to Acl class */ protected function _add($resource, $parent = null) { $this->add(new Zend_Acl_Resource($resource), $parent); return $this; } /** * Wrapper for <code>addRole</code> * * @param Zend_Acl_Resource_Interface $resource The resource to add * @param Zend_Acl_Resource_Interface|string $parents Parent resources it inherits from * @return Typeoneerror_Acl Reference to Acl class */ protected function _addRole($role, $parents = null) { $this->addRole(new Zend_Acl_Role($role, $parents)); return $this; } } по <?php /** * @author Benjamin Borowski <ben.borowski@typeoneerror.com> * @copyright Copyright (c) Typeoneerror Studios http://typeoneerror.com * @version $Id$ * @category Typeoneerror * @package Acl */ /** * Defines basic roles and resources for an application as * well as a Content Management System (CMS). * * Zend_Acl provides a lightweight and flexible access control list * (ACL) implementation for privileges management. * * {@inheritdoc} * * @author Benjamin Borowski <ben.borowski@typeoneerror.com> * @copyright Copyright (c) Typeoneerror Studios http://typeoneerror.com * @version $Id$ * @category Typeoneerror * @package Acl */ class Typeoneerror_Acl extends Zend_Acl { /** * Constructor function. * * Creates basic roles and resources and adds them to Acl. * * {@inheritdoc} * * @return Typeoneerror_Acl */ public function __construct() { //--------------------------------------- // ROLES //--------------------------------------- $this->_addRole("guest") ->_addRole("member", "guest") ->_addRole("admin", "member") ->_addRole("developer", "admin"); //--------------------------------------- // FRONT-END RESOURCES //--------------------------------------- $this->_add("default"); //--------------------------------------- // BACK-END RESOURCES //--------------------------------------- $this->_add("cms") ->_add("cms:articles", "cms") ->_add("cms:auth", "cms") ->_add("cms:bug-report", "cms") ->_add("cms:calendar", "cms") ->_add("cms:categories", "cms") ->_add("cms:comments", "cms") ->_add("cms:error", "cms") ->_add("cms:galleries", "cms") ->_add("cms:pages", "cms") ->_add("cms:photos", "cms") ->_add("cms:tags", "cms") ->_add("cms:users", "cms"); //--------------------------------------- // GUEST PERMISSIONS //--------------------------------------- $this->allow("guest", "default") ->allow("guest", "cms:auth") // -- guests can attempt to log-in ->allow("guest", "cms:error") // -- guests can break stuff ->allow("guest", "cms:bug-report"); // -- guests can report bugs //--------------------------------------- // ADMIN PERMISSIONS //--------------------------------------- $this->allow("admin") ->deny("admin", null, "purge") // -- admins cannot purge (normally) ->deny("admin", "cms:comments", "create"); // -- only devs can create a comment //--------------------------------------- // DEVELOPER PERMISSIONS //--------------------------------------- $this->allow("developer"); // -- unrestricted access return $this; } /** * Adds a Resource having an identifier unique to the ACL. * * @param Zend_Acl_Resource_Interface $resource The resource to add * @param Zend_Acl_Resource_Interface|string $parent A parent resource it inherits from * @return Typeoneerror_Acl Reference to Acl class */ protected function _add($resource, $parent = null) { $this->add(new Zend_Acl_Resource($resource), $parent); return $this; } /** * Wrapper for <code>addRole</code> * * @param Zend_Acl_Resource_Interface $resource The resource to add * @param Zend_Acl_Resource_Interface|string $parents Parent resources it inherits from * @return Typeoneerror_Acl Reference to Acl class */ protected function _addRole($role, $parents = null) { $this->addRole(new Zend_Acl_Role($role, $parents)); return $this; } } 

редактировать

Думаю, я должен также объяснить, что у меня есть Typeoneerror_Controller_Plugin_Acl который используется всякий раз, когда запрашивается какой-либо ресурс. Здесь я создаю «тег», который запрашивает запрашиваемый ресурс, и проверяет, имеет ли пользователь доступ к этому тегу:

  $controller = $request->controller; $action = $request->action; $module = (empty($request->module)) ? "default" : $request->module; // -- this ends up like "cms:articles" just like my resources $resource = $module . ":" . $controller; if (!$this->__acl->has($resource)) { $resource = $module; } // -- the good stuff. check if the user's role can access the resource and action if (!$this->__acl->isAllowed($role, $resource, $action)) { //more code }