Necesita orientación para comenzar con Zend ACL


Actualmente estoy trabajando en un sitio que requiere el ACL y como estoy usando Zend, tiene sentido para mí hacer uso de su ACL clase, pero poco tengo cero idea de cómo hacerlo. He leído los documentos, pero me confundió aún más...básicamente todo lo que quiero hacer es configurar dos grupos de usuarios, por ejemplo, "normal" y "admin", los usuarios normales pueden acceder a todas las páginas que tienen un controlador que no es administrador, mientras que el administrador obviamente puede acceder a las páginas del controlador de administrador.

Tengo muchas preguntas:

  1. ¿Cómo puedo configurar esto?
  2. Debería ejecutarlo a través de una base de datos o la configuración.ini?
  3. Dónde pongo mi ACL.php?
  4. ¿Cómo escribo tal guión?
  5. ¿Cómo llamo entonces, se hace esto en el Índice?.

Le agradecería mucho si me guía a un sitio web o un buen tutorial.

Author: assylias, 2009-02-13

3 answers

Implementé algo similar no hace mucho tiempo. El concepto básico sigue en un código de ejemplo.

He creado mi propia configAcl.archivo php que se carga en el archivo bootstrap, en mi caso es index.php. Así es como sería según su caso:

$acl = new Zend_Acl();

$roles  = array('admin', 'normal');

// Controller script names. You have to add all of them if credential check
// is global to your application.
$controllers = array('auth', 'index', 'news', 'admin');

foreach ($roles as $role) {
    $acl->addRole(new Zend_Acl_Role($role));
}
foreach ($controllers as $controller) {
    $acl->add(new Zend_Acl_Resource($controller));
}

// Here comes credential definiton for admin user.
$acl->allow('admin'); // Has access to everything.

// Here comes credential definition for normal user.
$acl->allow('normal'); // Has access to everything...
$acl->deny('normal', 'admin'); // ... except the admin controller.

// Finally I store whole ACL definition to registry for use
// in AuthPlugin plugin.
$registry = Zend_Registry::getInstance();
$registry->set('acl', $acl);

Otro caso es si desea permitir que el usuario normal solo "lista" acción en todos sus controladores. Es bastante simple, agregarías una línea como esta:

$acl->allow('normal', null, 'list'); // Has access to all controller list actions.

A continuación, debe crear un nuevo complemento que se encargue de la verificación de credenciales automáticamente cuando hay una solicitud para alguna acción del controlador. Esta comprobación tiene lugar en el método preDispatch() que se llama antes de cada llamada a la acción del controlador.

Aquí está AuthPlugin.php:

class AuthPlugin extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $loginController = 'auth';
        $loginAction     = 'login';

        $auth = Zend_Auth::getInstance();

        // If user is not logged in and is not requesting login page
        // - redirect to login page.
        if (!$auth->hasIdentity()
                && $request->getControllerName() != $loginController
                && $request->getActionName()     != $loginAction) {

            $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');
            $redirector->gotoSimpleAndExit($loginAction, $loginController);
        }

        // User is logged in or on login page.

        if ($auth->hasIdentity()) {
            // Is logged in
            // Let's check the credential
            $registry = Zend_Registry::getInstance();
            $acl = $registry->get('acl');
            $identity = $auth->getIdentity();
            // role is a column in the user table (database)
            $isAllowed = $acl->isAllowed($identity->role,
                                         $request->getControllerName(),
                                         $request->getActionName());
            if (!$isAllowed) {
                $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector');
                $redirector->gotoUrlAndExit('/');
            }
        }
    }
}

Los pasos finales son cargar su configAcl.php y registrar el AuthPlugin en el archivo bootstrap (probablemente index.php).

require_once '../application/configAcl.php';

$frontController = Zend_Controller_Front::getInstance();
$frontController->registerPlugin(new AuthPlugin());

Así que este es el concepto básico. No probé el código anterior (copiar y pegar y reescribir solo para el propósito de escaparate) por lo que no es a prueba de balas. Sólo para dar una idea.

EDITAR

Para la claridad. El código anterior en AuthPlugin supone que el objeto identity identity está lleno de datos de usuario (columna"role" en la base de datos). Esto se puede hacer dentro del proceso de inicio de sesión de la siguiente manera:

[...]
$authAdapter = new Zend_Auth_Adapter_DbTable($db);
$authAdapter->setTableName('Users');
$authAdapter->setIdentityColumn('username');
$authAdapter->setCredentialColumn('password');
$authAdapter->setIdentity($username);
$authAdapter->setCredential(sha1($password));
$authAdapter->setCredentialTreatment('? AND active = 1');
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
    $data = $authAdapter->getResultRowObject(null, 'password'); // without password
    $auth->getStorage()->write($data);
[...]
 38
Author: Marek Janouch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-13 13:23:48

Esta solución puede resultar ser la implementación más simple de Zend_Acl.

Ejemplo:

class UserController extends Zend_Controller_Action {

    public function preDispatch(){

        $resource = 'user_area';
        $privilege = $this->_request->getActionName();
        if (!$this->_helper->acl($resource, $privilege)) $this->_redirect();

    }

}

Zend/Controller/Action/Helper/Acl.php

class Zend_Controller_Action_Helper_Acl extends Zend_Controller_Action_Helper_Abstract {

    protected $acl;
    protected $role;

    protected function getAcl(){

        if (is_null($this->acl)){

            $acl = new Zend_Acl();

            $acl->addResource(new Zend_Acl_Resource('user_area'));
            $acl->addResource(new Zend_Acl_Resource('customer_area'), 'user_area');
            $acl->addResource(new Zend_Acl_Resource('web_area'));

            $acl->addRole(new Zend_Acl_Role('guest'));      
            $acl->addRole(new Zend_Acl_Role('user'), 'guest');

            $acl->allow('guest', 'web_area');
            $acl->allow('guest', 'user_area', array(
                'forgot-password',
                'login'
            ));
            $acl->allow('user', 'user_area');
            $acl->allow('customer', 'customer_area');

            $this->acl = $acl;

        }

        return $this->acl;

    }

    protected function getRole(){

        if (is_null($this->role)){

            $session = new Zend_Session_Namespace('session');
            $role = (isset($session->userType)) ? $session->userType : 'guest';
            $this->role = $role;

        }

        return $this->role;

    }

    public function direct($resource, $privilege = null){

        $acl = $this->getAcl();
        $role = $this->getRole();
        $allowed = $acl->isAllowed($role, $resource, $privilege);
        return $allowed;

    }

}
 2
Author: axiom82,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-09 14:38:04

Juega con esta estructura . obtenga el rol y el recurso de la base de datos y guárdelos en la sesión o en cualquier almacenamiento en caché . introduzca la descripción de la imagen aquí

 2
Author: Saurabh Chandra Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-25 05:45:13