問題描述
我的應用程序基于 Zend 框架.我正在使用 Zend_Auth
進行身份驗證,但我不確定 Zend_Acl
是否適合我,因為坦率地說,我所看到的示例對于我的需求來說太簡單了或者讓我困惑.
I have based my application upon the 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.
我將應用程序中的元素視為資源,并且這些資源可以擁有特權.包含資源特權的角色是動態定義的,分配給用戶.我將此信息存儲在規范化表中.
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'. Everyone can view the pages, but a authenticated user would need 'add', 'edit', or 'delete' privileges to do anything else with pages.
這是否與 Zend ACL 匹配?我是否會以一種會給我帶來問題的方式考慮 ACL?
Does this mesh with Zend ACL? Am I thinking ACL in a way that's going to create problems for me?
我的解決方案
Typeonerror 值得稱贊,但這是我的具體解決方案.
Typeonerror gets the credit, but here's my specific solution.
我擴展了 Zend_Acl
以簡化我的使用,因為我只加載當前用戶的角色:
I extended Zend_Acl
to simplify my usage because I only load the role of the current user:
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
列為空.
To populate the the ACL I execute a query which returns resource
, privilege
, and role_id
columns. The role_id
column is null in the result set if the user's role does not have that privilege.
$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()(或類似的)獲取用戶的角色,然后從數據庫中添加您的角色/資源.
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". 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.
<?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
,每當請求任何資源時都會使用它.在這里,我創建了請求資源制作的標簽"并檢查用戶是否有權訪問該標簽:
Guess I should also explain that I have an Typeoneerror_Controller_Plugin_Acl
which is used whenever any resource is requested. 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
}
這篇關于Zend ACL 是否適合我的需求?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!