Я основывал свое приложение на Платформе Зенда. Я использую Zend_Auth
для аутентификации, но я не уверен если Zend_Acl
будет работать на меня, потому что, откровенно говоря, примеры, которые я видел, или слишком упрощенны для моих потребностей или смущают меня.
Я думаю об элементах в своем приложении как Ресурсы, и эти Ресурсы могут иметь, имеют Полномочия. Роли, содержащие Полномочия Ресурса, динамично определяются присвоенные пользователям. Я храню эту информацию в нормализованных таблицах.
Роли являются действительно просто наборами Полномочий Ресурса без иерархии. Примером Ресурса был бы 'Page'. Все могут просмотреть страницы, но аутентифицируемый пользователь должен был бы 'добавить', 'отредактируйте' или 'удалите' полномочия сделать что-либо еще со страницами.
Это поймало в сети с Пехлеви 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
столбец является пустым в наборе результатов, если роль пользователя не имеет того полномочия.
$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']);
}
}
Именно так это работает, и я думаю, вы правильно об этом думаете. Вы можете добавить свои ресурсы, а затем добавить привилегии, чтобы разрешить доступ к ним определенным ролям пользователей. Например, в моей 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;
}
}
Edit
Думаю, я должен также объяснить, что у меня есть 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
}