php - Necesita orientación para comenzar con Zend ACL
zend-framework authentication (3)
Actualmente estoy trabajando en un sitio que requiere ACL y como estoy usando Zend, tiene sentido para mí hacer uso de su clase de ACL, pero tengo poca o ninguna idea de cómo hacerlo. He leído los documentos, pero me confundieron más ... básicamente, todo lo que quiero hacer es configurar dos grupos de usuarios, por ejemplo, "normal" y "administrador", los usuarios normales pueden acceder a todas las páginas que tienen un controlador que no es administrador, mientras el administrador puede acceder obviamente a las páginas del controlador de administración.
Tengo muchas preguntas:
- ¿Cómo configuro esto?
- ¿Debo ejecutarlo a través de un DB o el config.ini?
- ¿Dónde coloco mi ACL.php?
- ¿Cómo escribo tal script?
- ¿Cómo llamo, se hace esto en el índice?
Le agradecería mucho si me guía a un sitio web o un buen tutorial.
Esta solución puede 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;
}
}
Implementé algo similar no hace tanto tiempo. El concepto básico sigue en un código de ejemplo.
Creé mi propio archivo configAcl.php que se carga en el archivo bootstrap, en mi caso es index.php. Así es como sería de acuerdo con 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 "enumere" la 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 se solicite 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());
Entonces este es el concepto básico. No probé el código anterior (copie y pegue y vuelva a escribir solo para el propósito del escaparate), por lo que no es a prueba de balas. Solo para dar una idea.
EDITAR
Por la claridad El código anterior en AuthPlugin supone que el objeto $ identity está lleno de datos de usuario (columna "rol" en la base de datos). Esto podría hacerse dentro del proceso de inicio de sesión de esta 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);
[...]
Juega con esta estructura. obtenga rol y recurso de la base de datos y guárdelo en sesión para cualquier almacenamiento en caché.