Irei mostrar como fazer o controle de acesso através do esquema de plugin do zend framework e utilizando as classes zend_auth e zend_acl. No nosso exemplo teremos três tipos de usuários: guest, normal e admin.

Resposta:

index.php:

PHP:

<?php
error_reporting(E_ALL|E_STRICT);

setlocale(LC_ALL, 'BRA');
date_default_timezone_set('America/Sao_Paulo');

header('Content-type: text/html; charset=iso-8859-1');

set_include_path(
        '.'.PATH_SEPARATOR.'./lib'
           .PATH_SEPARATOR.'./application/models/'
           .PATH_SEPARATOR.'./application/autenticacao/'
           .PATH_SEPARATOR.get_include_path());

include "Zend/Loader.php";

Zend_Loader::loadClass('Zend_Controller_Front');
Zend_Loader::loadClass('Zend_Config_Xml');
Zend_Loader::loadClass('Zend_Config_Ini');
Zend_Loader::loadClass('Zend_Registry');
Zend_Loader::loadClass('Zend_Db');
Zend_Loader::loadClass('Zend_Db_Table');
Zend_Loader::loadClass('Zend_Controller_Plugin_ErrorHandler');
Zend_Loader::loadClass('Zend_Log');
Zend_Loader::loadClass('Zend_Log_Writer_Stream');
Zend_Loader::loadClass('Zend_Log_Formatter_Simple');
Zend_Loader::loadClass('Zend_Log_Formatter_Xml');
Zend_Loader::loadClass('Zend_Log_Filter_Priority');
Zend_Loader::loadClass('Zend_Date');
// Dando load nas classes responsavel pelo login e controle de acesso
Zend_Loader::loadClass('MyPluginAuth');
Zend_Loader::loadClass('MyAcl');
Zend_Loader::loadClass('Zend_Auth');

// pega as configuracoes
$config = new Zend_Config_Xml('./application/config.xml', 'staging');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);

// setup database
$db = Zend_Db::factory($config->database->type, $config->database->toArray());
Zend_Db_Table::setDefaultAdapter($db);

$controlador = Zend_Controller_Front::getInstance();
$controlador->throwExceptions(true);

// Setando o nivel de controladores do administradores
$controlador->setControllerDirectory( array(
                'default' => './application/controllers',
                'admin'   => './application/admin/controllers'
));

// Pega a instancia do Zend_Auth, acl e o plugin
$auth = Zend_Auth::getInstance();
$acl = new MyAcl($auth);
$plugin = new MyPluginAuth($auth, $acl);

// Registrando o plugin no Zend_Front
$controlador->registerPlugin( $plugin );
$controlador->setParam('auth', $auth);
$controlador->dispatch();

myPluginAuth:

PHP:

<?php
class MyPluginAuth extends Zend_Controller_Plugin_Abstract
{
        private $_auth;
        private $_acl;

             // Setando o modulo quando nao tem usuario logado
        private $_noauth = array('module' => 'default',
        'controller' => 'login',
        'action' => 'paginalogin');
            // Setando o modulo quando nao tem permissao de acesso
        private $_noacl = array('module' => 'default',
        'controller' => 'erro',
        'action' => 'semautorizacao');

        public function __construct($auth, $acl)
        {
                $this->_auth = $auth;
                $this->_acl = $acl;
        }

        public function preDispatch(Zend_Controller_Request_Abstract $request)
        {

                $bOk = false;
                // Verifica se tem usuario logado
                if ($this->_auth->hasIdentity()) {
                        // Caso tenha, pega dados do usuario
                        $identity = $this->_auth->getIdentity();
                                      // pega o perfil do usuario logado
                        $role = $identity['perfil'];

                } else {
                         // Caso contrario, associa o perfil de visitante
                        $role = 'guest';
                }

                $controller = strtolower($request->controller);
                $action = strtolower($request->action);
                $module = strtolower($request->module);
                $resource = $controller;

                if (!$this->_acl->has(strtolower($resource))) {
                        //$this->log->debug("Resource $resource nao encontrada.");
                        $resource = null;
                }

                if (!$this->_acl->isAllowed($role, $resource, $action)) {
                          // Usuario nao tem permissao ao resource
                         // Verifica o motivo dele nao ter permissao
                         // Verifica se está logado
                        if (!$this->_auth->hasIdentity()) {
                                //Nao está logado, logo nao tem permissao
                                $module = $this->_noauth['module'];
                                $controller = $this->_noauth['controller'];
                                $action = $this->_noauth['action'];

                        } else {
                                // Está logado e nao tem permissao
                                $module = $this->_noacl['module'];
                                $controller = $this->_noacl['controller'];
                                $action = $this->_noacl['action'];
                        }
                        $bOk = true;
                }
                          // Nao tem permissao, redireciona para o modulo de sem permissao ou sem usuario logado
                if( $bOk )
                {
                        // seta a action
                        $request->setModuleName($module);
                        $request->setControllerName($controller);
                        $request->setActionName($action);
                        }
        }
}
?>


myAcl:

PHP:

<?php
require_once 'Zend/Acl.php';
require_once 'Zend/Acl/Role.php';
require_once 'Zend/Acl/Resource.php';

class MyAcl extends Zend_Acl
{
    public function __construct(Zend_Auth $auth)
    {

                // Resources
                $this->add(new Zend_Acl_Resource('index'));
                $this->add(new Zend_Acl_Resource('adminindex'));
                $this->add(new Zend_Acl_Resource('login'));

                // Roles
        $this->addRole(new Zend_Acl_Role('guest'));
        $this->addRole(new Zend_Acl_Role('normal'), 'guest');
        $this->addRole(new Zend_Acl_Role('admin'), 'normal');

        //Recursos do Guest
        $this->allow('guest', 'login');

        //Recursos do normal
        $this->allow('normal','index');

        //Recursos do Admin
        $this->allow('admin','adminindex');        

    }
}

?>

Abstract Login Controller :

PHP:

<?php
        require_once("AbstractController.php");

        class AbstractLoginController extends AbstractController
        {
                function realizaLogin($login, $senha)
                {
                Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable');
                     $authAdapter = new Zend_Auth_Adapter_DbTable(           Zend_Db_Table::getDefaultAdapter() );

                //setando as colunas e as tabelas aonde vai conferir os dados
                $authAdapter->setIdentityColumn('s_username');
                     $authAdapter->setCredentialColumn('s_senha');
                $authAdapter->setTableName('usuario');

              //setando os dados
               $authAdapter->setIdentity($login);
                   $authAdapter->setCredential($senha);

                  Zend_Loader::loadClass('Zend_Auth');

                 $auth = Zend_Auth::getInstance();
                 $result = $auth->authenticate($authAdapter);

            // Verifica se a senha confere
            if ($result->isValid()) {
                //Senha confere

                $data = $authAdapter->getResultRowObject(null, 's_senha');

                                // pegando dados do usuario e setando no objeto
                $usuario['id']     = $data->id_usuario;
                                $usuario['nome']   = $data->s_username;
                                $usuario['perfil'] = $data->s_tipo;

                $auth->getStorage()->write($usuario);
                $this->_redirect('/');
                        }
                        else {
                                // Senha nao confere
                                $this->_request->setModuleName("default");
                                $this->_request->setControllerName("login");
                                // Volta pra pagina de login
                                $this->_request->setActionName("paginalogin");
                                $this->_forward("paginalogin","login","default");                      

                        }
                }
        }

Pra quem já é conhecedor do zend, o restante não tem muito segredo, pra quem ainda nao conhece mais uma vez recomendo o post do felipe tonello, que está alguns posts atrás ensinando como se configura o zend framework. O código fonte completo sem o lib (zend) está disponivel para download.



O exemplo foi feito em plataforma windows, ou seja, não está se preocupando com detalhes como case das actions/controllers, ele NÃO irá funcionar em ambiente UNIX. Assim que tiver tempo irei verificar esses detalhes e até irei implementar uma página de teste para quem quiser ver como funciona.

Endereço de trackback para este post

Trackback URL (clique direito e copie atalho/localização do link)

Sem feedback para esse post ainda

Deixe seu comentário


Seu endereço de e-mail não será revelado nesse site.

Sua URL será exibida.
(Quebras de linha se tornam <br />)
(Nome, e-mail & website)
(Permitir que usuários o contatem através de um formulário eletrônico (seu e-mail não será exibido.))