dez201001
John Marques
5
Controle de Acesso com Zend_Acl
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
5 Comentários to “Controle de Acesso com Zend_Acl”
Responda







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!
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
Boa Noite, John Marques, muito bom seu tutorial.
para permitir tudo para o administrador basta:
$this->acl->allow(‘admin’);
somente isto, simples assim…
Bom post, mas onde fica o diretório pra salvar o plugin ?
Eu uso na seguinte pasta “application/plugins/”
John