A free and open-source book on Zend Framework for beginners


17.12. Modifying the AuthManager Service

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:

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:


Top