Zend Framework:需要ACL的典型示例

发布于 2024-10-20 06:29:12 字数 74 浏览 4 评论 0原文

有人可以指导我 ACL 的典型实施示例吗?就像“管理员”可以访问“管理”模块,“用户”可以访问“用户模块”,访客可以访问“打开”页面。

Can some one guide me for typical implementation example of ACL. Like 'admin' can access 'admin' module, 'user' can access 'user module', and guest can access 'open' pages.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

﹂绝世的画 2024-10-27 06:29:12

我可以把我的 ACL 贴给你。它由三个元素组成:acl.ini、ACL 控制器插件 (My_Controller_Plugin_Acl) 和 My_Acl 类以及 USER 表。然而,它不处理模块,而是处理控制器和操作。不过,它可能会让您对 ACL 有一些总体了解。我对 ACL 的使用基于一本名为“Zend Framework in Action”的书中的内容。

USER表(权限字段用于ACL):

CREATE  TABLE IF NOT EXISTS `USER` (
  `user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `email` VARCHAR(85) NOT NULL ,
  `password` CHAR(32) NOT NULL,
  `phone` VARCHAR(45) NULL ,
  `phone_public` TINYINT(1) NULL DEFAULT 0 ,     
  `first_name` VARCHAR(45) NULL ,
  `last_name` VARCHAR(45) NULL ,
  `last_name_public` TINYINT(1) NULL DEFAULT 1 ,
  `is_enabled` TINYINT(1) NOT NULL DEFAULT 1 ,
  `created` TIMESTAMP NOT NULL,
  `privilage` ENUM('BASIC','PREMIUM','ADMIN') NOT NULL DEFAULT 'BASIC' ,
  PRIMARY KEY (`user_id`) ,
  UNIQUE INDEX `email_UNIQUE` (`email` ASC) )
ENGINE = InnoDB;

acl.ini(我有四种权限,基本权限继承自guest,高级权限继承基本权限,高级权限继承管理员权限) :

; roles
acl.roles.guest = null
acl.roles.basic = guest
acl.roles.premium = basic
acl.roles.administrator = premium

; resources
acl.resources.deny.all.all = guest


acl.resources.allow.index.all = guest
acl.resources.allow.error.all = guest
acl.resources.allow.user.login = guest
acl.resources.allow.user.logout = guest
acl.resources.allow.user.create = guest

acl.resources.allow.user.index = basic
acl.resources.allow.user.success = basic

My_Acl 类(根据 ini 文件创建 ACL 角色和资源):

class My_Acl extends Zend_Acl {

    public function __construct() {
        $aclConfig = Zend_Registry::get('acl');
        $roles = $aclConfig->acl->roles;
        $resources = $aclConfig->acl->resources;
        $this->_addRoles($roles);
        $this->_addResources($resources);
    }

    protected function _addRoles($roles) {

        foreach ($roles as $name => $parents) {
            if (!$this->hasRole($name)) {
                if (empty($parents)) {
                    $parents = null;
                } else {
                    $parents = explode(',', $parents);
                }                    
                $this->addRole(new Zend_Acl_Role($name), $parents);             
            }
        }       
    }

    protected function _addResources($resources) {          

        foreach ($resources as $permissions => $controllers) {         

            foreach ($controllers as $controller => $actions) {
                if ($controller == 'all') {
                    $controller = null;
                } else {
                    if (!$this->has($controller)) {
                        $this->add(new Zend_Acl_Resource($controller));
                    }
                }

                foreach ($actions as $action => $role) {
                    if ($action == 'all') {
                        $action = null;
                    }
                    if ($permissions == 'allow') {
                        $this->allow($role, $controller, $action);
                    }
                    if ($permissions == 'deny') {                           
                        $this->deny($role, $controller, $action);
                    }
                }
            }
        }
    }

}

My_Controller_Plugin_Acl

class My_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract {

    /**
     *
     * @var Zend_Auth
     */
    protected $_auth;

    protected $_acl;
    protected $_action;
    protected $_controller;
    protected $_currentRole;

    public function __construct(Zend_Acl $acl, array $options = array()) {
        $this->_auth = Zend_Auth::getInstance();
        $this->_acl = $acl;

    }

   public function preDispatch(Zend_Controller_Request_Abstract $request) {

        $this->_init($request);        

        // if the current user role is not allowed to do something
        if (!$this->_acl->isAllowed($this->_currentRole, $this->_controller, $this->_action)) {

            if ('guest' == $this->_currentRole) {
                $request->setControllerName('user');
                $request->setActionName('login');
            } else {
                $request->setControllerName('error');
                $request->setActionName('noauth');
            }
        }
    }

    protected function _init($request) {
        $this->_action = $request->getActionName();
        $this->_controller = $request->getControllerName();
        $this->_currentRole = $this->_getCurrentUserRole();
    }

    protected function _getCurrentUserRole() {      

        if ($this->_auth->hasIdentity()) {
            $authData = $this->_auth->getIdentity();
            $role = isset($authData->property->privilage)?strtolower($authData->property->privilage): 'guest';
        } else {
            $role = 'guest';
        }

        return $role;
    }

}

最后是 Bootstrap.php 的一部分,其中所有内容均已初始化:

protected function _initLoadAclIni() {
    $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/acl.ini');
    Zend_Registry::set('acl', $config);
}

protected function _initAclControllerPlugin() {
    $this->bootstrap('frontcontroller');
    $this->bootstrap('loadAclIni');

    $front = Zend_Controller_Front::getInstance();

    $aclPlugin = new My_Controller_Plugin_Acl(new My_Acl());

    $front->registerPlugin($aclPlugin);
}

I can paste you my ACL. It consists of three elements: acl.ini, ACL controller plugin (My_Controller_Plugin_Acl) and My_Acl class, and USER table. However it does not deal with modules, but with controllers and actions. Nevertheless it may give you some general idea about ACL. My use of ACL is based on the one in a book called "Zend Framework in Action".

USER table (privilege field is used for ACL):

CREATE  TABLE IF NOT EXISTS `USER` (
  `user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `email` VARCHAR(85) NOT NULL ,
  `password` CHAR(32) NOT NULL,
  `phone` VARCHAR(45) NULL ,
  `phone_public` TINYINT(1) NULL DEFAULT 0 ,     
  `first_name` VARCHAR(45) NULL ,
  `last_name` VARCHAR(45) NULL ,
  `last_name_public` TINYINT(1) NULL DEFAULT 1 ,
  `is_enabled` TINYINT(1) NOT NULL DEFAULT 1 ,
  `created` TIMESTAMP NOT NULL,
  `privilage` ENUM('BASIC','PREMIUM','ADMIN') NOT NULL DEFAULT 'BASIC' ,
  PRIMARY KEY (`user_id`) ,
  UNIQUE INDEX `email_UNIQUE` (`email` ASC) )
ENGINE = InnoDB;

acl.ini (I have four privileges, such that basic inherits from guest, premium inherits form basic and administrator for premium):

; roles
acl.roles.guest = null
acl.roles.basic = guest
acl.roles.premium = basic
acl.roles.administrator = premium

; resources
acl.resources.deny.all.all = guest


acl.resources.allow.index.all = guest
acl.resources.allow.error.all = guest
acl.resources.allow.user.login = guest
acl.resources.allow.user.logout = guest
acl.resources.allow.user.create = guest

acl.resources.allow.user.index = basic
acl.resources.allow.user.success = basic

My_Acl class (creates ACL roles and resources based on the ini file):

class My_Acl extends Zend_Acl {

    public function __construct() {
        $aclConfig = Zend_Registry::get('acl');
        $roles = $aclConfig->acl->roles;
        $resources = $aclConfig->acl->resources;
        $this->_addRoles($roles);
        $this->_addResources($resources);
    }

    protected function _addRoles($roles) {

        foreach ($roles as $name => $parents) {
            if (!$this->hasRole($name)) {
                if (empty($parents)) {
                    $parents = null;
                } else {
                    $parents = explode(',', $parents);
                }                    
                $this->addRole(new Zend_Acl_Role($name), $parents);             
            }
        }       
    }

    protected function _addResources($resources) {          

        foreach ($resources as $permissions => $controllers) {         

            foreach ($controllers as $controller => $actions) {
                if ($controller == 'all') {
                    $controller = null;
                } else {
                    if (!$this->has($controller)) {
                        $this->add(new Zend_Acl_Resource($controller));
                    }
                }

                foreach ($actions as $action => $role) {
                    if ($action == 'all') {
                        $action = null;
                    }
                    if ($permissions == 'allow') {
                        $this->allow($role, $controller, $action);
                    }
                    if ($permissions == 'deny') {                           
                        $this->deny($role, $controller, $action);
                    }
                }
            }
        }
    }

}

My_Controller_Plugin_Acl:

class My_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract {

    /**
     *
     * @var Zend_Auth
     */
    protected $_auth;

    protected $_acl;
    protected $_action;
    protected $_controller;
    protected $_currentRole;

    public function __construct(Zend_Acl $acl, array $options = array()) {
        $this->_auth = Zend_Auth::getInstance();
        $this->_acl = $acl;

    }

   public function preDispatch(Zend_Controller_Request_Abstract $request) {

        $this->_init($request);        

        // if the current user role is not allowed to do something
        if (!$this->_acl->isAllowed($this->_currentRole, $this->_controller, $this->_action)) {

            if ('guest' == $this->_currentRole) {
                $request->setControllerName('user');
                $request->setActionName('login');
            } else {
                $request->setControllerName('error');
                $request->setActionName('noauth');
            }
        }
    }

    protected function _init($request) {
        $this->_action = $request->getActionName();
        $this->_controller = $request->getControllerName();
        $this->_currentRole = $this->_getCurrentUserRole();
    }

    protected function _getCurrentUserRole() {      

        if ($this->_auth->hasIdentity()) {
            $authData = $this->_auth->getIdentity();
            $role = isset($authData->property->privilage)?strtolower($authData->property->privilage): 'guest';
        } else {
            $role = 'guest';
        }

        return $role;
    }

}

Finally a part of Bootstrap.php where everything is initialized:

protected function _initLoadAclIni() {
    $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/acl.ini');
    Zend_Registry::set('acl', $config);
}

protected function _initAclControllerPlugin() {
    $this->bootstrap('frontcontroller');
    $this->bootstrap('loadAclIni');

    $front = Zend_Controller_Front::getInstance();

    $aclPlugin = new My_Controller_Plugin_Acl(new My_Acl());

    $front->registerPlugin($aclPlugin);
}
画▽骨i 2024-10-27 06:29:12

我有一个可能适合您需求的简单示例

class Dagho_Acl_Main extends Zend_Acl {
    public function   __construct() {
        $anonymous = new Zend_Acl_Role("anonymous");
        $customer = new Zend_Acl_Role("customer");
        $admin = new Zend_Acl_Role("admin");
        $anonymousResource  = new Zend_Acl_Resource("acl");
        $defaultResource = new Zend_Acl_Resource("default");
        $customerResource  = new Zend_Acl_Resource("user");
        $adminResource  = new Zend_Acl_Resource("manage");


        $this->addRole($anonymous)
             ->addRole($customer)
             ->addRole($admin);
        $this->addResource($anonymousResource)
             ->addResource($defaultResource)
             ->addResource($customerResource)
             ->addResource($adminResource);


        $this->allow($anonymous, $anonymousResource);
        $this->allow($anonymous, $defaultResource);
        $this->deny($anonymous, $customerResource);
        $this->deny($anonymous, $adminResource);

        $this->allow($customer, $anonymousResource);
        $this->allow($customer, $defaultResource);
        $this->allow($customer, $customerResource);
        $this->deny($customer, $adminResource);

        $this->allow($admin, $defaultResource);
        $this->allow($admin, $anonymousResource);
        $this->allow($admin, $adminResource);
        $this->deny($admin, $customerResource);
       return $this ;
    }
}

,这是我的插件:

<?php

class Dagho_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract {

    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        $module = $request->getModuleName();
        $controller = $request->getControllerName();
        $action = $request->getActionName();
        $doctrineAuth = new Dagho_Auth_Doctrine();
        $logged = $doctrineAuth->checklogin();
        $identity = $doctrineAuth->getIdentity();
        Zend_Registry::set("identity", $identity);
        if ($logged && $identity["role"] !== "anonymous") {
            /// user had an identity  let's check the ACL
            $acl = new Dagho_Acl_Main();
            $isAllowed = $acl->isAllowed($identity["role"], $module);
            if (!$isAllowed) {
                return $request->setModuleName("acl")->setControllerName("index")
                        ->setActionName("denied")->setDispatched(true);
            } else {
                /// user has identity and he is allowed to access it
                return;
            }
        } elseif ($logged === false || ($logged && $identity["role"] === "anonymous" )) {
            //// user not logged on > login.php or its his first visit
            $identity = $doctrineAuth->getStorage()->write(array('name' => 'anonymous', 'role' => "anonymous",));
            Zend_Registry::set("identity", $identity);
            return $request->setModuleName("acl")->setControllerName("index")
                    ->setActionName("login")->setDispatched(true);
        } else {
            return $request->setModuleName("acl")->setControllerName("index")
                    ->setActionName("denied")->setDispatched(true);
        }
        parent::preDispatch($request);
    }

}

I have a simple example that might fits your needs

class Dagho_Acl_Main extends Zend_Acl {
    public function   __construct() {
        $anonymous = new Zend_Acl_Role("anonymous");
        $customer = new Zend_Acl_Role("customer");
        $admin = new Zend_Acl_Role("admin");
        $anonymousResource  = new Zend_Acl_Resource("acl");
        $defaultResource = new Zend_Acl_Resource("default");
        $customerResource  = new Zend_Acl_Resource("user");
        $adminResource  = new Zend_Acl_Resource("manage");


        $this->addRole($anonymous)
             ->addRole($customer)
             ->addRole($admin);
        $this->addResource($anonymousResource)
             ->addResource($defaultResource)
             ->addResource($customerResource)
             ->addResource($adminResource);


        $this->allow($anonymous, $anonymousResource);
        $this->allow($anonymous, $defaultResource);
        $this->deny($anonymous, $customerResource);
        $this->deny($anonymous, $adminResource);

        $this->allow($customer, $anonymousResource);
        $this->allow($customer, $defaultResource);
        $this->allow($customer, $customerResource);
        $this->deny($customer, $adminResource);

        $this->allow($admin, $defaultResource);
        $this->allow($admin, $anonymousResource);
        $this->allow($admin, $adminResource);
        $this->deny($admin, $customerResource);
       return $this ;
    }
}

and here is my plugin :

<?php

class Dagho_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract {

    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        $module = $request->getModuleName();
        $controller = $request->getControllerName();
        $action = $request->getActionName();
        $doctrineAuth = new Dagho_Auth_Doctrine();
        $logged = $doctrineAuth->checklogin();
        $identity = $doctrineAuth->getIdentity();
        Zend_Registry::set("identity", $identity);
        if ($logged && $identity["role"] !== "anonymous") {
            /// user had an identity  let's check the ACL
            $acl = new Dagho_Acl_Main();
            $isAllowed = $acl->isAllowed($identity["role"], $module);
            if (!$isAllowed) {
                return $request->setModuleName("acl")->setControllerName("index")
                        ->setActionName("denied")->setDispatched(true);
            } else {
                /// user has identity and he is allowed to access it
                return;
            }
        } elseif ($logged === false || ($logged && $identity["role"] === "anonymous" )) {
            //// user not logged on > login.php or its his first visit
            $identity = $doctrineAuth->getStorage()->write(array('name' => 'anonymous', 'role' => "anonymous",));
            Zend_Registry::set("identity", $identity);
            return $request->setModuleName("acl")->setControllerName("index")
                    ->setActionName("login")->setDispatched(true);
        } else {
            return $request->setModuleName("acl")->setControllerName("index")
                    ->setActionName("denied")->setDispatched(true);
        }
        parent::preDispatch($request);
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文