2011-03-06 6 views
16

¿Puede alguien guiarme para el típico ejemplo de implementación de ACL? Como 'admin' puede acceder al módulo 'admin', 'usuario' puede acceder a 'módulo de usuario' y el invitado puede acceder a páginas 'abiertas'.Zend Framework: necesita un ejemplo típico de ACL

+0

Véase la respuesta más común a esta pregunta anterior para un excelente ejemplo de implementación: http://stackoverflow.com/questions/2046608/practical-zend-acl-zend-auth-implementation-and-best-practices –

+0

La referencia de ZF tampoco es mala e xample: http://framework.zend.com/manual/en/zend.acl.refining.html – Laimoncijus

+0

THX, Will Prescott :) – SMka

Respuesta

4

Tengo un ejemplo sencillo que el poder se adapte a sus necesidades

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 ; 
    } 
} 

y aquí está mi 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); 
    } 

} 
27

te puedo pegar mi ACL. Consta de tres elementos: acl.ini, el complemento del controlador ACL (My_Controller_Plugin_Acl) y la clase My_Acl, y la tabla USER. Sin embargo, no se trata de módulos, sino de controladores y acciones. Sin embargo, puede darle una idea general acerca de ACL. Mi uso de ACL se basa en el de un libro llamado "Zend Framework in Action".

tabla de usuario (campo de privilegio se utiliza para 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 (tengo cuatro privilegios, que hereda básicos de huéspedes, forman hereda prima básica y administrador de la prima):

; 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 

clase My_Acl (crea roles y recursos basados ​​en el archivo 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; 
    } 

} 

Finalmente una parte de Bootstrap.php donde todo se inicializa:

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); 
} 
+0

Marcin, siempre propones una idea nueva, y la idea de hoy es guardar acl en un archivo ini, buen trabajo mi amigo – tawfekov

+0

@tawfekov. Gracias :-) Pero esto no es completamente mi idea ya que tomé del libro mencionado en mi respuesta. – Marcin

+0

Hola, podemos administrar controladores y acciones con este código. ¿Cómo puedo gestionar el acceso de los módulos con este código? – afsane