[英]Does Zend ACL suit my needs?
I have based my application upon the Zend Framework. 我的应用程序基于Zend Framework。 I am using
Zend_Auth
for authentication, but I'm not sure if Zend_Acl
will work for me because, frankly, the examples I've seen are either too simplistic for my needs or confuse me. 我使用
Zend_Auth
进行身份验证,但我不确定Zend_Acl
是否适合我,因为坦白说,我看到的例子对我的需求来说太简单了或者让我感到困惑。
I'm thinking of elements in my application as Resources and these Resources can have have Privileges. 我正在考虑将我的应用程序中的元素作为资源,这些资源可以拥有权限。 Roles containing Resource Privileges are dynamically defined assigned to users.
包含资源权限的角色是动态定义的,分配给用户。 I'm storing this information in normalized tables.
我将这些信息存储在规范化表格中。
Roles are really just collections of Resource Privileges with no hierarchy. 角色实际上只是资源权限的集合,没有层次结构。 An example of a Resource would be 'Page'.
资源的一个例子是'Page'。 Everyone can view the pages, but a authenticated user would need 'add', 'edit', or 'delete' privileges to do anything else with pages.
每个人都可以查看页面,但经过身份验证的用户需要“添加”,“编辑”或“删除”权限才能对页面执行任何其他操作。
Does this mesh with Zend ACL? 这与Zend ACL相匹配吗? Am I thinking ACL in a way that's going to create problems for me?
我是否会以一种会给我带来问题的方式思考ACL?
My Solution 我的解决方案
Typeonerror gets the credit, but here's my specific solution. Typeonerror获得了荣誉,但这是我的具体解决方案。
I extended Zend_Acl
to simplify my usage because I only load the role of the current user: 我扩展了
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);
}
}
To populate the the ACL I execute a query which returns resource
, privilege
, and role_id
columns. 要填充ACL,我执行一个返回
resource
, privilege
和role_id
列的查询。 The role_id
column is null in the result set if the user's role does not have that privilege. 如果用户的角色没有该特权,则
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']);
}
}
That's exactly how it works and I think you're thinking about it in an accurate way. 这正是它的工作方式,我认为你正在准确地思考它。 You can add your resources and then add privileges to allow certain user roles to access them.
您可以添加资源,然后添加权限以允许某些用户角色访问它们。 For example, in my CMS, I have "developers", "admins", and "users".
例如,在我的CMS中,我有“开发人员”,“管理员”和“用户”。 In the code below I add general access and then remove some actions and specific methods from certain user's access.
在下面的代码中,我添加了一般访问权限,然后从某些用户的访问中删除了一些操作和特定方法。 Of course this is pretty specific to my application but basically, you'd have to get the user's role from auth->getIdentity() (or similar) and then add your roles/resources from the database.
当然这对我的应用程序非常具体,但基本上,你必须从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 编辑
Guess I should also explain that I have an Typeoneerror_Controller_Plugin_Acl
which is used whenever any resource is requested. 猜猜我还应该解释一下,我有一个
Typeoneerror_Controller_Plugin_Acl
,只要请求任何资源就会使用它。 Here I create the "tag" that the requested resource makes and check whether the user has access to that tag: 在这里,我创建了所请求资源的“标记”,并检查用户是否有权访问该标记:
$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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.