Menú
Crea una regla de lista de control de acceso (ACL)
Crear archivo acl
Crear un rol por código
Restringir el acceso a usuarios
Restringir Controladores
Restringiendo contenido
Zend Acl
Crea una regla de lista de control de acceso
las listas de control de acceso en Magento 2 es utilizan para definir los permisos para usuarios especificos en el area de administración de magento.
Se puede usar el ACL, para controlar qué acciones puede realizar un usuario, tal como ver menús, acceder a controladores, endponds (api) y layout blocks condicionales.
Crear archivo acl
Se debe definir los recursos por medio del archivo etc/acl.xml
del modulo. En caso de que no exista este archivo en la carpeta etc de su modulo, se debera de crear.
La etiqueta resorce debera contener los siguientes atributos
Atributo | Descripcion |
---|---|
id | String unico que debe tener el siguiente formato: {Vendor}_{Module}::{resource_id} |
title | Título que se muestra en la barra de menú |
sortOrder | Posición en la que se muestra el menú |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="{Vendor}_{Module}::{resource_id}" title="{Resource Title}" sortOrder="100">
<resource id="{Vendor}_{Module}::{sub_resource_id}" title="{Sub Resource Title}" sortOrder="10"/>
</resource>
</resource>
</resources>
</acl>
</config>
Recuerde que después de esto, se debe limpiar la cache bin/magento cache:clear
o haciendo clic en Sistema > Administración de caché > Vaciar caché de Magento
Crear un rol por código
Este paso se ejemplifica el como crear un rol por medio de código por medio de un upgradeData. Recordemos que para este paso se debe
subir la versón del modulo y correr bin\magento setup:upgrade
<?php
namespace {Vendor}\{Module}\Setup;
use Magento\Authorization\Model\Acl\Role\Group
use Magento\Authorization\Model\RoleFactory;
use Magento\Authorization\Model\RulesFactory;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Authorization\Model\UserContextInterface;
class UpgradeData implements UpgradeDataInterface
{
/**
* @var RoleFactory
*/
private RoleFactory $roleFactory;
private RuleFactory $ruleFactory;
/**
* @param RoleFactory $roleFactory
*/
public function __construct(
RoleFactory $roleFactory,
RuleFactory $ruleFactory
) {
$this->roleFactory = $roleFactory;
}
/**
* En este ejemplo, usamos la instancia de Role en el cual se usan los siguientes metodos para crear el rol
* setName: Es el nombre del rol que se va a crear.
* setRoleType: Aquí se define el grupo al que va a pertenecer el rol
* setUserType: Aquí se define el tipo de usuario al que va a pertenecer el rol
*
* El array de resouces son los modulos o recursos a los que el rol podra tener acceso.
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
/** @var Magento\Authorization\Model\Role $role */
$role = $this->roleFactory->create();
$role->setName('{Role Name}')
->setRoleType(Group::ROLE_TYPE)
->setUserType(UserContextInterface::USER_TYPE_ADMIN)
->setPid(0);
$resources = [
'{Vendor}_{Module}::{resource_id}',
'{Vendor}_{Module}::{sub_resource_id}',
];
$role->save();
$rule = $this->ruleFactory->create();
$rule->setRoleId(
$role->getId()
)->setResources($resources)->saveRel();
$setup->endSetup();
}
}
El siguiente código ejemplifica como podemos agregar mas Recursos a un rol existente que ya tenga Recursos asignados previamente.
<?php
namespace {Vendor}\{Module}\Setup;
use Magento\Authorization\Model\RoleFactory;
use Magento\Authorization\Model\RulesFactory;
use Magento\Authorization\Model\Acl\AclRetriever;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
class UpgradeData implements UpgradeDataInterface
{
/**
* @var RoleFactory
*/
private RoleFactory $roleFactory;
private RulesFactory $ruleFactory;
private AclRetriever $aclRetriever;
/**
* @param RoleFactory $roleFactory
*/
public function __construct(
RoleFactory $roleFactory,
RulesFactory $ruleFactory,
AclRetriever $aclRetriever
) {
$this->roleFactory = $roleFactory;
$this->ruleFactory = $ruleFactory;
$this->aclRetriever = $aclRetriever;
}
/**
* En este ejemplo, se le agregan los recursos al rol "Desarrollador" para que pueda acceder a los modulos
*
* El array de resouces son los modulos o recursos a los que el rol podra tener acceso.
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
if (version_compare($context->getVersion(), '1.0.1', '<')) {
/** @var Magento\Authorization\Model\Role $role */
$role = $this->roleFactory->create()->load('Desarrollador', 'role_name');
$resources = $this->aclRetriever->getAllowedResourcesByRole(
$role->getId()
);
$resources = array_merge($resources, [
'Movil_Regulatorio::regulatorio',
'Movil_Regulatorio::report',
'Movil_Regulatorio::clientes'
]);
$this->ruleFactory->create()->setRoleId(
$role->getId()
)->setResources($resources)->saveRel();
}
$setup->endSetup();
}
}
Restringir el acceso a usuarios
En le modulo, cree el siguiente archivo etc/adminhtml/menu.xml
, este archivo creara un menú que estará oculto para los usuarios no autorizados. Los atributos en los nodos determinan a que recursos pueden acceder
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="{Vendor}_{Module}::menu" title="Custom Menu" module="{Vendor}_{Module}" sortOrder="10" resource="{Vendor}_{Module}::menu"/>
<add id="{Vendor}_{Module}::create" title="Create" module="{Vendor}_{Module}" sortOrder="10" parent="{Vendor}_{Module}::menu" action="custommenu/create/index" resource="{Vendor}_{Module}::create"/>
<add id="{Vendor}_{Module}::delete" title="Delete" module="{Vendor}_{Module}" sortOrder="20" parent="{Vendor}_{Module}::menu" action="custommenu/delete/index" resource="{Vendor}_{Module}::delete"/>
<add id="{Vendor}_{Module}::view" title="View" module="{Vendor}_{Module}" sortOrder="30" parent="{Vendor}_{Module}::menu" action="custommenu/view/index" resource="{Vendor}_{Module}::view"/>
</menu>
</config>
Atributo | Descripcion |
---|---|
id | String unico que debe tener el siguiente formato: {Vendor}_{Module}::{resource_id} |
title | Título que se muestra en la barra de menú |
module | Módulo que contiene el menú actual |
sortOrder | Posición en la que se muestra el menú |
Parent | El menú que padre del actual |
action | la URL de la pagina que debe mostrarce después de hacer click en el menú. Debe tener el siguiente formato: {front_name}/{controller_path}/{action} |
resource | Regla ACL para restringir el acceso {Vendor}_{Module}::{subresource_id} |
Restringir Controladores
Para poder aplicar el acceso a un controlador, se puede hacer de dos formas, una de ellas es sobre escribiendo la funcion _isAllowed y la otra es sobre escribiendo la constante ADMIN_RESOURCE. Esta segunda opción funciona dado a que la funcion _isAllowed esta escrita de la siguiente forma:
/**
* Determines whether current user is allowed to access Action
*
* @return bool
*/
protected function _isAllowed()
{
return $this->_authorization->isAllowed(static::ADMIN_RESOURCE);
}
<?php
namespace {Vendor}\{Module}\Controller\Adminhtml;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\View\Result\PageFactory;
class Crud extends Action
{
/** Por medio de sobre escribir la constante */
const ADMIN_RESORUCE = '{Vendor}_{Module}::{subresource_id}';
}
Y al sabre escribir la funcion, seria de la siguiente forma:
<?php
namespace {Vendor}\{Module}\Controller\Adminhtml;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\View\Result\PageFactory;
class Crud extends Action
{
/**
* @override to allow access to this controller
* @return bool
*/
protected function _isAllowed()
{
return $this->_authorization->isAllowed('{Vendor}_{Module}::{subresource_id}');
}
}
Restringiendo contenido
Con los ACL también es posible restringir el render de blockes dinamicos en una pagina, ya que basta con establecer el valor del subresorce en el tag aclResource
<block class="{Vendor}\{Module}\Block\Adminhtml\Type" name="block.example" aclResource="{Vendor}_{Module}::{subresource_id}">
<!-- ... -->
</block>
Zend Acl
Si bien, es bieno saber como implementar el acl en magento, también es interesante entender como funciona, ya que la clase Magento\Framework\Acl extiende de Zend_Acl de Zend Framework version 1.2, gracias a ello, Magento es capaz de proporcionar una implementación liviana y flexible para la administración de privilegios. En general, una aplicación puede utilizar tales ACL para controlar el acceso a ciertos objetos protegidos por parte de otros objetos solicitantes.
Para poner un poco de contexto, definamos lo siguiente:
- un Rol es un objeto que puede solicitar acceso a un recurso.
- un Recurso es un objeto al que se le controla el acceso.
Bajo este contexto, los roles solicitan acceso a los recursos,
codigo 1
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework;
/**
* ACL. Can be queried for relations between roles and resources.
*
* @api
* @since 100.0.2
*/
class Acl extends \Zend_Acl
{
Para poner un ejemplo, podríamos suponer que para un archivo Foo, que en este caso, sería el recurso, el usuario A tiene todos los privilegios. El usuario B tiene acceso de solo lectura, mientras que el usuario C no tiene acceso al archivo.
En este ejemplo, la ACL define las políticas de control de acceso para el archivo y determina a qué usuarios se les concede o deniega el acceso al archivo y qué acciones pueden realizar (como leer, escribir o ejecutar el archivo).
En zend, podríamos ejemplificar este ejemplo de la siguiente forma:
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('A'));
$acl->addRole(new Zend_Acl_Role('B'));
$acl->addRole(new Zend_Acl_Role('C'));
$acl->addResource(new Zend_Acl_Resource('Foo'));
$acl->allow('A', 'Foo', ['read', 'write', 'delete']);
$acl->allow('B', 'Foo', ['read']);
$acl->deny('C', 'Foo');
$acl->isAllowed('A', 'Foo', 'read'); // true
$acl->isAllowed('A', 'Foo', 'write'); // true
$acl->isAllowed('A', 'Foo', 'delete'); // true
$acl->isAllowed('B', 'Foo', 'read'); // true
$acl->isAllowed('B', 'Foo', 'write'); // false
$acl->isAllowed('B', 'Foo', 'delete'); // false
$acl->isAllowed('C', 'Foo', 'read'); // false
$acl->isAllowed('C', 'Foo', 'write'); // false
$acl->isAllowed('C', 'Foo', 'delete'); // false
Top comments (0)