• Zend_Acl


    Zend_Acl的误解

    很多人会误认为ACL的resource和privilege是controller和action,这是错误的。

    对Zend_Acl而言,resource可以是任何事物-一个controller,一个file,一个module...
    privilege就像resource一样,也可以是任何与resource相关的事物,例如,如果resource是一个controler,那privilege就可以是一个action,或者如果controller是一个file或者model,那么它就可能是read或者write。

    创建一个简单的ACL
    前面提到,Zend_Acl是由资源(resources)、权限(privileges)和角色(roles)构成的。privileges是访问resources的权限级别。roles就是以指定的访问权限(privilege)来访问resource的访问对象,可以是一个用户,用户组or anything you wish to associate such data with。

    下面是一个ACL的简单代码,只包含了少量的resources和roles

     1 class My_Acl extends Zend_Acl {
     2   public function __construct() {
     3     //Add a new role called "guest"
     4     $this->addRole(new Zend_Acl_Role('guest'));
     5  
     6     //Add a role called user, which inherits from guest
     7     $this->addRole(new Zend_Acl_Role('user'), 'guest');
     8  
     9     //Add a resource called page
    10     $this->add(new Zend_Acl_Resource('page'));
    11  
    12     //Add a resource called news, which inherits page
    13     $this->add(new Zend_Acl_Resource('news'), 'page');
    14  
    15     //Finally, we want to allow guests to view pages
    16     $this->allow('guest', 'page', 'view');
    17  
    18     //and users can comment news
    19     $this->allow('user', 'news', 'comment');
    20   }
    21 }

    此时创建一个My_Acl的实例,就可以对应一些简单的权限对应设定,但是具体那个角色拥有什么权限呢?

    guest角色对于page资源拥有一个view的权限,之后user角色继承了guest,所以user也拥有了page的view权限。news资源继承了page,所以所有用户对news资源都拥有与对page资源相同的权限。在构造函数的最后一行,我们为user角色在news资源上新增了一个comment的权限。而此时只有user角色拥有news资源的comment权限,guest没有。

    使用ACL
    使用一个ACL类非常简单。你只需要调用isAllowed方法,同时向它传递一个role,resource和一个privilege参数既可。而最大的难点在于你如何确定哪个是role, resource和privilege。

    该如何确定哪个是角色?一个非常简单的假设就是:如果这有一个登陆用户user,那么这个角色就是user,否则就是guest。

    那么资源呢?这取决于你的应用程序,这可以从你所包含的文件名中猜测出来。例如:对于上面的例子中,我们有一个page.php文件和一个news.php文件用来对应于page资源,而news对应于news资源。


    最后什么是权限呢?当我们简单的读取page的时候,你可以使用view权限。稍后代码会检测一些其它一些权限规则,例如comment权限以及显示comment box的权限等。

    下面是一个简单的实例

    1 $role = 'guest';
    2 if(isset($_SESSION['auth']))
    3 $role = 'user';
    4 
    5 $acl = new My_Acl();
    6 
    7 if($acl->isAllowed($role, 'news', 'comment')) {
    8 //Some code here to display a news box
    9 }

    在ZF项目中使用ACL
    在zf项目中,资源和权限通常会在请求资源中确定。
    通常我们可以创建一个检测权限的插件:

     1 class My_Plugin_Acl extends Zend_Controller_Plugin_Abstract {
     2   private $_acl = null;
     3  
     4   public function __construct(Zend_Acl $acl) {
     5     $this->_acl = $acl;
     6   }
     7  
     8   public function preDispatch(Zend_Controller_Request_Abstract $request) {
     9     //As in the earlier example, authed users will have the role user
    10     $role = (Zend_Auth::getInstance()->hasIdentity())
    11           ? 'user'
    12           : 'guest';
    13  
    14     //For this example, we will use the controller as the resource:
    15     $resource = $request->getControllerName();
    16  
    17     if(!$this->_acl->isAllowed($role, $resource, 'view')) {
    18       //If the user has no access we send him elsewhere by changing the request
    19       $request->setModuleName('auth')
    20               ->setControllerName('auth')
    21               ->setActionName('login');
    22     }
    23   }
    24 }

    我们可以在上面的例子中创建一个静态方法来代替构造函数。
    将上面的插件加载到前段控制器中:

    1 $acl = new My_Acl();
    2 
    3 //assuming $fc is the front controller
    4 $fc->registerPlugin(new My_Plugin_Acl($acl));

    此时每个请求都会核对权限控制列表,并且没有view权限的角色将会别拒绝访问。
    接下来就是关于如何检测comment权限
    在需要检测comment权限的controller中添加一些代码来向view中传递一个boolean值来确定权限。

    1 public function someAction() {
    2 $role = (Zend_Auth::getInstance()->hasIdentity())
    3 ? 'user'
    4 : 'guest';
    5 
    6 //assuming $this->_acl contains the acl
    7 $this->view->canComment = $this->_acl->isAllowed($role, 'news', 'comment');
    8 }

    创建自定义角色类
    通过扩展Zend_Acl_Role_Interface接口来定义角色类,使其具有更多的灵活性。该接口只包含一个方法getRoleId()

     1 class Common_Module_acl_user implements Zend_Acl_Role_Interface
     2 {
     3     protected $_name;
     4     
     5     public function __construct($name)
     6     {
     7         $this->_name = $name;
     8     }
     9     
    10     public function getRoleId()
    11     {
    12         return 'user_'. $this->_name;
    13     }
    14 }

    此时只需将该类的实例传递给Zend_Acl对象既可

    1 $acl = new Zend_Acl();
    2 //添加一个名为user_zh的角色
    3 $acl->addRole(new Common_Module_acl_user('zh'));

    创建自定义资源类
    通过扩展Zend_Acl_Resource_Interface接口来实现自定义资源类

    1 class Resource_Controller implements Zend_Acl_Resource_Interface {
    2     public function __construct($id) {
    3       $this->_id = $id;
    4     }
    5  
    6     public function getResourceId() {
    7       return 'controller-' . $this->_id; 
    8     }
    9 }

    实现方法同角色类一样

    PHP技术交流群 170855791

  • 相关阅读:
    Vim 使用设置
    stm32之CAN发送、接收详解
    stm32内部的CAN总线
    stm32之CAN总线基础
    JavaScript之Ajax
    JavaScript之insertBefore()和自定义insertAfter()的用法。
    JavaScript之向文档中添加元素和内容的方法
    JavaScript之共享onload
    JavaScrtip之JS最佳实践
    XX秘籍
  • 原文地址:https://www.cnblogs.com/gbyukg/p/2472855.html
Copyright © 2020-2023  润新知