How to implement ACL in Zend Framework 2 application

The Zend\Permissions\Acl component provides a lightweight and flexible access control list (ACL) implementation for privileges management. So lets start.

1. Create a new module called ManageAcl.
So inside module folder create a new folder called “ManageAcl”. Create Module.php and code should be


namespace ManageAcl;

class Module
{
    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }
}

Done, you register a new module of your Zend Framework 2 application.

Now I discuss about hard code acl list that you create a inside file.

So ManageAcl/config folder create a new file called module.roles.php

return array(
    'super_admin'=> array(
        'all'
    ),
    'admin'=> array(
        'user',
        'dashboard',
        'home',
        'admin'
    ),
);

So now open your Module.php file, we will check ACL on bootstap. So code are looks like

namespace ManageAcl;

use Zend\Mvc\MvcEvent;
use Zend\Permissions\Acl\Acl;
use Zend\Permissions\Acl\Role\GenericRole;
use Zend\Permissions\Acl\Resource\GenericResource;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        // initialize ACL
        $this->initAcl($e);
        // Check ACL
        $e->getApplication()->getEventManager()->attach('route', array($this, 'checkAcl'));
    }

    public function initAcl(MvcEvent $e) {

        $acl = new Acl();
        $roles = include __DIR__ . '/config/module.roles.php';
        $allResources = array();
        foreach ($roles as $role => $resources) {
            // Add groups to the Role registry using Zend\Permissions\Acl\Role\GenericRole
            $role = new GenericRole($role);
            $acl->addRole($role);
            $allResources = array_merge($resources, $allResources);
            foreach ($resources as $resource) {
                if(!$acl->hasResource($resource))
                    $acl->addResource(new GenericResource($resource));
            }
            //adding restrictions
            foreach ($allResources as $resource) {
                $acl->allow($role, $resource);
            }
        }
        $e->getViewModel()->acl = $acl;
    }

    public function checkAcl(MvcEvent $e) {
        $route = $e->getRouteMatch()->getMatchedRouteName();
        
        // set user role
        $userRole = 'admin'; // $userRole = 'super_admin';

        if($userRole != 'super_admin') {
            if (!$e->getViewModel()->acl->isAllowed($userRole, $route)) {
                $response = $e->getResponse();
                $response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseUrl() . '/404');
                $response->setStatusCode(404);

            }
        }

    }

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }
}

That’s it!

One thought on “How to implement ACL in Zend Framework 2 application

  1. If you wanted to have multiple roles in the config file wouldn’t you add “$acl->allow($role, $resource);” to the “foreach ($resources as $resource)” loop otherwise all roles are going to have access to any defined route in the config file.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s