La siguiente cosa que haremos es modificar el filtro de acceso que está dentro
del servicio AuthManager
que escribimos para el ejemplo User Demo. Exactamente,
vamos a modificar el método filterAccess()
. Queremos que el método filterAccess()
use la clase RbacManager
.
Pero primero modificaremos la llave access_filter
en la configuración. Queremos
que la llave permite el acceso a:
*
).@
).identity
en forma de dirección de
correo electrónico (@identity
).+permission
).Por ejemplo, abajo mostramos como se ve la llave access_filter
para el módulo
User:
<?php
return [
//...
// The 'access_filter' key is used by the User module to restrict or permit
// access to certain controller actions for unauthorized visitors.
'access_filter' => [
'controllers' => [
Controller\UserController::class => [
// Give access to "resetPassword", "message" and "setPassword" actions
// to anyone.
['actions' => ['resetPassword', 'message', 'setPassword'], 'allow' => '*'],
// Give access to "index", "add", "edit", "view", "changePassword" actions
// to users having the "user.manage" permission.
['actions' => ['index', 'add', 'edit', 'view', 'changePassword'],
'allow' => '+user.manage']
],
Controller\RoleController::class => [
// Allow access to authenticated users having the "role.manage" permission.
['actions' => '*', 'allow' => '+role.manage']
],
Controller\PermissionController::class => [
// Allow access to authenticated users having "permission.manage" permission.
['actions' => '*', 'allow' => '+permission.manage']
],
]
],
//...
];
Abajo podemos encontrar el código fuente del método filterAccess()
del servicio
AuthManager
:
/**
* This is a simple access control filter. It is able to restrict unauthorized
* users to visit certain pages.
*
* This method uses the 'access_filter' key in the config file and determines
* whenther the current visitor is allowed to access the given controller action
* or not. It returns true if allowed; otherwise false.
*/
public function filterAccess($controllerName, $actionName)
{
// Determine mode - 'restrictive' (default) or 'permissive'. In restrictive
// mode all controller actions must be explicitly listed under the 'access_filter'
// config key, and access is denied to any not listed action for unauthorized users.
// In permissive mode, if an action is not listed under the 'access_filter' key,
// access to it is permitted to anyone (even for not logged in users.
// Restrictive mode is more secure and recommended to use.
$mode = isset($this->config['options']['mode'])?$this->config['options']['mode']:'restrictive';
if ($mode!='restrictive' && $mode!='permissive')
throw new \Exception('Invalid access filter mode (expected either restrictive or permissive mode');
if (isset($this->config['controllers'][$controllerName])) {
$items = $this->config['controllers'][$controllerName];
foreach ($items as $item) {
$actionList = $item['actions'];
$allow = $item['allow'];
if (is_array($actionList) && in_array($actionName, $actionList) ||
$actionList=='*') {
if ($allow=='*')
// Anyone is allowed to see the page.
return self::ACCESS_GRANTED;
else if (!$this->authService->hasIdentity()) {
// Only authenticated user is allowed to see the page.
return self::AUTH_REQUIRED;
}
if ($allow=='@') {
// Any authenticated user is allowed to see the page.
return self::ACCESS_GRANTED;
} else if (substr($allow, 0, 1)=='@') {
// Only the user with specific identity is allowed to see the page.
$identity = substr($allow, 1);
if ($this->authService->getIdentity()==$identity)
return self::ACCESS_GRANTED;
else
return self::ACCESS_DENIED;
} else if (substr($allow, 0, 1)=='+') {
// Only the user with this permission is allowed to see the page.
$permission = substr($allow, 1);
if ($this->rbacManager->isGranted(null, $permission))
return self::ACCESS_GRANTED;
else
return self::ACCESS_DENIED;
} else {
throw new \Exception('Unexpected value for "allow" - expected ' .
'either "?", "@", "@identity" or "+permission"');
}
}
}
}
// In restrictive mode, we require authentication for any action not
// listed under 'access_filter' key and deny access to authorized users
// (for security reasons).
if ($mode=='restrictive') {
if(!$this->authService->hasIdentity())
return self::AUTH_REQUIRED;
else
return self::ACCESS_DENIED;
}
// Permit access to this page.
return self::ACCESS_GRANTED;
}
Como podemos ver, en el código de arriba el método regresa una de tres constantes posibles:
ACCESS_GRANTED
si el usuario puede ver la página dada.AUTH_REQUIRED
si el usuario necesita autenticarse primero.ACCESS_DENIED
si el usuario no puede ver la página.