Authorization is the process of specifying access to resources to different users based on defined roles. Zend Framework provides Zend_Acl to define and enforce an Access Control List (ACL).

Resources

In Zend Framework context resources are usually actions you want to control access to. Zend provides the Zend_Acl_Resource class to create resources. Each resource should have a unique ID to identify it.

1
new Zend_Acl_Resource('resourceId');

Then you can add the resource to Zend_Acl using Zend_Acl::add:

1
Zend_Acl::add(new Zend_Acl_Resource('resourceId'));

Roles

In your application, roles are the different kind of users your application serves. Zend framework provides Zend_Acl_Role to create roles, and they work very similar to Resources:

1
Zend_Acl::addRole(new Zend_Acl_Role('roleId'));

Since it is very usual to have roles in a hierarchical structure you can have roles that inherit from other roles. You only need to specify the role you want to inherit from as the second argument of Zend_Acl_Role constructor:

1
new Zend_Acl_Role('roleId', 'parentRole');

Rules

Rules are when we specify if a role has or not access to an specific resource. Zend_Acl uses a white list approach by default, so you need to explicitly define each rule for your system. For giving permissions to a specif role to a resource you can use Zend_Acl::allow:

1
Zend_Acl::allow('guestId', 'resourceId');

Putting it all together

To put this all together I like to have a model that controls all the rules:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
/**
 * ACL model
 */
class Application_Model_Acl extends Zend_Acl
{
    /**
     * Initialize authorization
     */
    public function __construct()
    {
        $this->createRoles();
        $this->createResources();
        $this->createRules();
    }

    /**
     * Create roles
     */
    protected function createRoles()
    {
        $this->addRole(new Zend_Acl_Role('guest'));
        $this->addRole(new Zend_Acl_Role('admin'), 'guest');
    }

    /**
     * Create resources
     */
    protected function createResources()
    {
        // Some Controller::Action keys
        $this->add(new Zend_Acl_Resource('error::error'));
        $this->add(new Zend_Acl_Resource('auth::login'));
        $this->add(new Zend_Acl_Resource('index::index'));
        $this->add(new Zend_Acl_Resource('auth::logout'));
        $this->add(new Zend_Acl_Resource('admin::index'));
    }

    /**
     * Create access rules
     */
    protected function createRules()
    {
        // Guest permissions
        $this->allow('guest', 'error::error');
        $this->allow('guest', 'auth::login');
        $this->allow('guest', 'index::index');

        // Admin permissions
        $this->allow('admin', 'auth::logout');
        $this->allow('admin', 'admin::index');
    }
}

Now we have a model that we can easily instantiate it to initialize our ACL. You can see that for the resource keys I used a combination of controller::key.

Because we want to activate our ACL with every request the best bet is to make a plugin to run it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
/**
 * ACL Plugin
 */
class Application_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
    /**
     * Index of the role in the authentication storage
     * @const string
     */
    const ROLE_INDEX = 'role';

    /**
     * Default role for not logged users
     * @const string
     */
    const DEFAULT_ROLE = 'guest';

    /**
     * Verify if the logged user has access to the requested resource. If the
     * user does not have access they will be redirected to an authorization
     * page
     *
     * @param Zend_Controller_Request_Abstract $request
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        // We get the current role from the Authentication object
        $auth = Zend_Auth::getInstance();
        $user = $auth->getIdentity();

        if (isset($user->{self::ROLE_INDEX})) {
            $role = $user->{self::ROLE_INDEX};
        } else {
            $role = self::DEFAULT_ROLE;
        }

        $acl = new Application_Model_Acl();
        if (
            !$acl->isAllowed(
                $role,
                $request->getControllerName() . '::' . $request->getActionName()
            )
        ) {
            // Redirect to login page
        }
    }
}

That’s it, we have our authorization system ready.

[ design_patterns  php  programming  ]
Dependency injection (Inversion of Control) in Spring framework
Flyway - Version control for Databases in Java
Immutables and Java
Introduction to JDBI
Introduction to JDBC