The next thing we will do is modifying the access filter inside the AuthManager
service
we wrote for the User Demo sample. Particularly, we want to modify the filterAccess()
method. We want the filterAccess()
method to use our RbacManager
class.
But first we will modify the format of the access_filter
key in the configuration. We want the key to allow
to permit access to:
*
);@
);identity
email address if we specify (@identity
)permission
if we specify the plus sign followed by the
permission name (+permission
).For example, here how the access_filter
key would look like for the User module:
<?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']
],
]
],
//...
];
Below you can find the source code of the filterAccess()
method of the AuthManager
service:
/**
* 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;
}
As you could see from the code, the method returns one of three constants:
ACCESS_GRANTED
if user is allowed to see the given page;AUTH_REQUIRED
if user needs to authenticate first;ACCESS_DENIED
if user is denied to see the page.