dez201001

5

Controle de Acesso com Zend_Acl

Lomadee, uma nova espécie na web. A maior plataforma de afiliados da América Latina.

Olá pessoal,

Hoje iremos falar sobre como criar o controle de acesso para os usuários no sistema, ou seja as permissões que o usuário possui baseado em seu perfil dentro do sistema.

A ACL é composta de três funções básicas, são elas:

Perfil (Role)
Eu entendo como nível, como se fosse em um hierarquia, é de acordo com o perfil do usuário, que ele terá acesso as funcionalidades do sistema.
Ex.: Administrador, Técnico, e etc..

Funcionalidades (Resource)
São as funções que você disponíbiliza, ou seja, adicionar, editar, excluir, listar entre outros.

Permissões (Permissions)
Rs, esse acho que nem preciso falar, mas é a ligação entre o perfil e funcionalidade, é onde determino qual funcionalidade o perfil terá ou não acesso.

Então vamos começar o código! (Até que enfim! \0/)

No meu caso eu criei um plugin, mas acredito que possa ser adaptado a ACL e colocada dentro do Bootstrap.

Iremos  por parte, primeiramente vamos criar a classe e instânciar o Zend_Acl.

<?php
class Application_Plugin_ACL extends Zend_Controller_Plugin_Abstract
{
    private $acl;

    public function __construct()
    {
        // Instânciamos a ACL
        $this->acl = new Zend_Acl();
    }

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
    }
}
?>

Agora vamos criar dois perfis para os usuários.

  • admin = administrador do sistema
  • operador = Usuário comum do sistema

na prática

<?php
class Application_Plugin_ACL extends Zend_Controller_Plugin_Abstract
{
    private $acl;

    public function __construct()
    {
        // Instânciamos a ACL
        $this->acl = new Zend_Acl();

        // Criando os perfis
        $this->acl->addRole(new Zend_Acl_Role('operador')) //Operador
                  ->addRole(new Zend_Acl_Role('admin')); // Administrador</pre>
}

 public function preDispatch(Zend_Controller_Request_Abstract $request)
 {
 }
}
?>

Agora que criamos os perfis, vamos determinar as funcionalidades do sistema.

<?php
class Application_Plugin_ACL extends Zend_Controller_Plugin_Abstract
{
    private $acl;

    public function __construct()
    {
        // Instânciamos a ACL
        $this->acl = new Zend_Acl();

        // Criando os perfis
        $this->acl->addRole(new Zend_Acl_Role('operador')) //Operador
                  ->addRole(new Zend_Acl_Role('admin')); // Administrador

        // Funcionalidades
        // Definicao modulo:controller, action
        $this->acl->add(new Zend_Acl_Resource('default:auth', 'logout')) // Para sair do sistema
                  ->add(new Zend_Acl_Resource('default:users')) // Cadastro de usuarios
                  ->add(new Zend_Acl_Resource('default:noticias')); // Cadastro de notícias</pre>
 }

 public function preDispatch(Zend_Controller_Request_Abstract $request)
 {

 }
}
?>

Agora já está quase pronto, vamos pra o próximo passo, definir as permissões dentro da ACL.

<?php
class Application_Plugin_ACL extends Zend_Controller_Plugin_Abstract
{
    private $acl;

    public function __construct()
    {
        // Instânciamos a ACL
        $this->acl = new Zend_Acl();

        // Criando os perfis
        $this->acl->addRole(new Zend_Acl_Role('operador')) //Operador
                  ->addRole(new Zend_Acl_Role('admin')); // Administrador

        // Funcionalidades
        // Definicao modulo:controller, action
        $this->acl->add(new Zend_Acl_Resource('default:auth', 'logout')) // Para sair do sistema
                  ->add(new Zend_Acl_Resource('default:users')) // Cadastro de usuarios
                  ->add(new Zend_Acl_Resource('default:noticias')); // Cadastro de notícias

        // Definir as permissões
        // perfil, modulo:controller, action
        // Metódo allow é de permissão
        // Metódo deny é de negação

        // Perfil: Operador
        $this->acl->allow('operador', 'default:auth', 'logout') // Tem que permitir que cara saia não é mesmo, ah não ser que o perfil seja prisioneiro ai não ehaueshuase =D
                  ->allow('operador', 'default:noticias', array('index', 'edit')) // Definer por ações, vamos dizer que o cara so possa listar e editar
                  ->deny('operador', 'default:noticias', 'delete') // e não permitir ele excluir a notícia
                  ->deny('default:users') //não vamos permitir que o operador administre os usuários

        // Perfil: Admin
        // E para o admin tudo =D
                  ->allow('admin', 'default:auth', 'logout')
                  ->allow('admin', 'default:noticias')
                  ->allow('admin', 'default:users');

}

 public function preDispatch(Zend_Controller_Request_Abstract $request)
 {

 }
}
?>

Agora que já foram definidos os perfis, funcionalidades e permissões, falta apenas fazer a verificação e pronto! =D

<?php
class Application_Plugin_ACL extends Zend_Controller_Plugin_Abstract
{
    private $acl;

    public function __construct()
    {
        // Instânciamos a ACL
        $this->acl = new Zend_Acl();

        // Criando os perfis
        $this->acl->addRole(new Zend_Acl_Role('operador')) //Operador
                  ->addRole(new Zend_Acl_Role('admin')); // Administrador

        // Funcionalidades
        // Definicao modulo:controller, action
        $this->acl->add(new Zend_Acl_Resource('default:auth', 'logout')) // Para sair do sistema
                  ->add(new Zend_Acl_Resource('default:users')) // Cadastro de usuarios
                  ->add(new Zend_Acl_Resource('default:noticias')); // Cadastro de notícias

        // Definir as permissões
        // perfil, modulo:controller, action
        // Metódo allow é de permissão
        // Metódo deny é de negação

        // Perfil: Operador
        $this->acl->allow('operador', 'default:auth', 'logout') // Tem que permitir que cara saia não é mesmo, ah não ser que o perfil seja prisioneiro ai não ehaueshuase =D
                  ->allow('operador', 'default:noticias', array('index', 'edit')) // Definer por ações, vamos dizer que o cara so possa listar e editar
                  ->deny('operador', 'default:noticias', 'delete') // e não permitir ele excluir a notícia
                  ->deny('default:users') //não vamos permitir que o operador administre os usuários

        // Perfil: Admin
        // E para o admin tudo =D
                  ->allow('admin', 'default:auth', 'logout')
                  ->allow('admin', 'default:noticias')
                  ->allow('admin', 'default:users');
  }

 public function preDispatch(Zend_Controller_Request_Abstract $request)
 {
 // Primeiro vamos instânciar o Zend_Auth
 $auth = Zend_Auth::getInstance();
 // Agora vamos descobri qual o modulo, controller e action que o usuário está acessando
 $module = $request->getModuleName();
 $controller = $request->getControllerName();
 $action = $request->getActionName();

 /* Agora que já capturamos a ação do usuário, vamos verificar se o usuário está logado, caso esteja vamos verificar se ele tem acesso a funcionalidade */
 if($auth->hasIdentity()) {
 // Beleza o cabra ta logado, agora vamos ver se ele tem permissão
 $identity = $auth->getIdentity();

 if(!$this->acl->isAllowed($identity->perfil, $module.':'.$controller, $action)) {
 /* Agora é so direcionar para outra página ou gerar o erro, eu faço o seguinte seto o controller de error e ação forbidden que é o erro 403, ficando assim.*/
 $request->setControllerName('error')->setActionName('forbidden');
 }
 }
 }
}
?>

É isso ai pessoal, espero que tenham gostado o próximos artigos serão sobre Zend_Navigation para criar menus e depois a integração do Zend_Navigation com o Zend_Acl para que o usuário visualize somente o menu que tem direito.

Então abraço a todos,

John Marques


Lomadee, uma nova espécie na web. A maior plataforma de afiliados da América Latina.

5 Comentários to “Controle de Acesso com Zend_Acl”

  1. Diogo 19 fevereiro 2011 at 15:26 #

    Fala John,

    Parabéns pelo tutorial, porém estou com algumas dúvidas:

    - Depois de feito o plugin é necessário instanciar no Bootstrap ou o metodo preDispatch ja faz isso automaticamente?
    - Tenho o modulo admin, porém só tenho 1 Bootstrap na minha aplicação, como ficaria?
    - Tem alguma opção pro admin ficar allow tudo sem precisar ficar colocando na mão as permissões 1 por 1?

    Fico no aguardo, valeu!

  2. John Marques 21 fevereiro 2011 at 9:49 #

    Fala Diogo,

    Obrigado primeiramente, e vamos lá =D

    Depois de feito o plugin é necessário instanciar no Bootstrap ou o metodo preDispatch ja faz isso automaticamente?

    - Sim é necessário inicializar no bootstrap. Eu faço assim oh,

    public function _initPlugins()
    {
    $frontController = Zend_Controller_Front::getInstance();
    $frontController->registerPlugin(new Application_Plugin_ACL());
    }

    - Tenho o modulo admin, porém só tenho 1 Bootstrap na minha aplicação, como ficaria?

    Também só utilizo um Bootstrap, não tem problema.

    - Tem alguma opção pro admin ficar allow tudo sem precisar ficar colocando na mão as permissões 1 por 1?

    Tem um método da classe do ACL que é getResources(), ela retorna um vertor com todas a funcionalidades adicionadas, assim basta, você pegar e fazer um loop e add pro admin.
    Ex:

    $func = $this->acl->getResources();
    $nfunc = count($func);

    for($i=0; $i< $nfunc; $i++) {
    $this->acl->allow(‘admin’, $func[$i]);
    }

    e pronto ! =D

    Espero que te sirva,

    John Marques

  3. Jean Michael 31 maio 2011 at 22:01 #

    Boa Noite, John Marques, muito bom seu tutorial.

    para permitir tudo para o administrador basta:

    $this->acl->allow(‘admin’);

    somente isto, simples assim…

  4. Albert Guedes 6 junho 2011 at 11:42 #

    Bom post, mas onde fica o diretório pra salvar o plugin ?

  5. John Marques 6 junho 2011 at 14:28 #

    Eu uso na seguinte pasta “application/plugins/”

    John


Responda