ZF2AuthAcl Module doesnt work out of the box

时间:2017-06-09 12:42:02

标签: mysql zend-framework2

I picked up this ZF2AuthAcl module to make my life easier. For some reason it does not work out of the box. As soon as i activate it in Zend2 Application.config it takes over the whole site. Meaning it goes straight to login on any page i have. There is a "white list" and i tried to add pages to this in an array and it does not seem to work. I will show the Acl page that it has with the "white list" maybe i did not add them correctly or there is a better way. It is data driven also. Has anyone used this with success or know about it?

The author is the one who told me it probably has to do with the white list.

The area that i added to looked like this:

    public function initAcl()
    {
    $this->roles = $this->_getAllRoles();
    $this->resources = $this->_getAllResources();
    $this->rolePermission = $this->_getRolePermissions();
    // we are not putting these resource & permission in table bcz it is
    // common to all user
    $this->commonPermission = array(
        'ZF2AuthAcl\Controller\Index' => array(
            'logout',
            'index'                
        ),
    );
    $this->_addRoles()
        ->_addResources()
        ->_addRoleResources();
}

This is the whole thing with parts i added.

namespace ZF2AuthAcl\Utility;

use Zend\Permissions\Acl\Acl as ZendAcl;
use Zend\Permissions\Acl\Role\GenericRole as Role;
use Zend\Permissions\Acl\Resource\GenericResource as Resource;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class Acl extends ZendAcl implements ServiceLocatorAwareInterface
{

const DEFAULT_ROLE = 'guest';

protected $_roleTableObject;

protected $serviceLocator;

protected $roles;

protected $permissions;

protected $resources;

protected $rolePermission;

protected $commonPermission;

public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
    $this->serviceLocator = $serviceLocator;

    return $this;
}

public function getServiceLocator()
{
    return $this->serviceLocator;
}

public function initAcl()
{
    $this->roles = $this->_getAllRoles();
    $this->resources = $this->_getAllResources();
    $this->rolePermission = $this->_getRolePermissions();
    // we are not putting these resource & permission in table bcz it is
    // common to all user
    $this->commonPermission = array(
        'ZF2AuthAcl\Controller\Index' => array(
            'logout',
            'index'                
        ),
        'Frontend\Controller\Index' => array(
            'index'                
        ),
        'Blog\Controller\Blog' => array(
            'blog',
            'list',
            'view',
            'UsMap',
            'maps'                
        )
    );
    $this->_addRoles()
        ->_addResources()
        ->_addRoleResources();
}

public function isAccessAllowed($role, $resource, $permission)
{
    if (! $this->hasResource($resource)) {
        return false;
    }
    if ($this->isAllowed($role, $resource, $permission)) {
        return true;
    }
    return false;
}

protected function _addRoles()
{
    $this->addRole(new Role(self::DEFAULT_ROLE));

    if (! empty($this->roles)) {
        foreach ($this->roles as $role) {
            $roleName = $role['role_name'];
            if (! $this->hasRole($roleName)) {
                $this->addRole(new Role($roleName), self::DEFAULT_ROLE);
            }
        }
    }
    return $this;
}

protected function _addResources()
{
    if (! empty($this->resources)) {
        foreach ($this->resources as $resource) {
            if (! $this->hasResource($resource['resource_name'])) {
                $this->addResource(new Resource($resource['resource_name']));
            }
        }
    }

    // add common resources
    if (! empty($this->commonPermission)) {
        foreach ($this->commonPermission as $resource => $permissions) {
            if (! $this->hasResource($resource)) {
                $this->addResource(new Resource($resource));
            }
        }
    }

    return $this;
}

protected function _addRoleResources()
{
    // allow common resource/permission to guest user
    if (! empty($this->commonPermission)) {
        foreach ($this->commonPermission as $resource => $permissions) {
            foreach ($permissions as $permission) {
                $this->allow(self::DEFAULT_ROLE, $resource, $permission);
            }
        }
    }

    if (! empty($this->rolePermission)) {
        foreach ($this->rolePermission as $rolePermissions) {
            $this->allow($rolePermissions['role_name'], $rolePermissions['resource_name'], $rolePermissions['permission_name']);
        }
    }

    return $this;
}

protected function _getAllRoles()
{
    $roleTable = $this->getServiceLocator()->get("RoleTable");
    return $roleTable->getUserRoles();
}

protected function _getAllResources()
{
    $resourceTable = $this->getServiceLocator()->get("ResourceTable");
    return $resourceTable->getAllResources();
}

protected function _getRolePermissions()
{
    $rolePermissionTable =   $this->getServiceLocator()->get("RolePermissionTable");
    return $rolePermissionTable->getRolePermissions();
}

private function debugAcl($role, $resource, $permission)
{
    echo 'Role:-' . $role . '==>' . $resource . '\\' . $permission .  '<br/>';
 }
}

06/10/2016 Additional information I have also found that this ACL page is not in any of the pages in the module. The functions are not called out anywhere in any page nor is it "use" on any page. So how is it supposed to work?

Update 06/10/2017 - Area that has been fixed.

I have found where this is used in the module.php there is a whitelist that the pages have to be added too. Below is where you add them.

$whiteList = array(
        'Frontend\Controller\Index-index',
        *Add whatever modules/controller/action you do not want included*
        'ZF2AuthAcl\Controller\Index-index',
        'ZF2AuthAcl\Controller\Index-logout'
    );

2 个答案:

答案 0 :(得分:1)

以上是我的问题的结论。我偶然发现了它。我没有查看module.php文件。这就是答案所在。

答案 1 :(得分:0)

这是Zend ACL的一般实现。我跟着这个。如果你愿意,你也可以遵循这个。

在模块的module.acl.php文件夹中创建名为config/的文件。此文件包含角色和权限的配置。根据需要修改此脚本。

模块名/配置/ module.acl.php

return array(
    'roles' => array(
        'guest',
        'member'
    ),
    'permissions' => array( 
        'guest' => array(
            // Names of routes for guest role
            'users-signup',
            'users-login'
        ),
        'member' => array(
            // Names of routes for member role
            // Add more here if you need
            'users-logout'
        )
    )
);

您需要导入以下三个类,并在Module.php中定义和初始化一些方法。

模块名/ Module.php

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

// Optional; use this for authentication
use Zend\Authentication\AuthenticationService; 

现在让我们创建将部署ACL并检查角色和权限的方法。

模块:: initAcl()

public function initAcl(MvcEvent $e)
{

    // Set the ACL
    if ($e->getViewModel()->acl == null) {
        $acl = new Acl();
    } else {
        $acl = $e->getViewModel()->acl;
    }

    // Get the roles and permissions configuration
    // You may fetch configuration from database instead.
    $aclConfig = include __DIR__ . '/config/module.acl.php';

    // Set roles
    foreach ($aclConfig['roles'] as $role) {
        if (!$acl->hasRole($role)) {
            $role = new GenericRole($role);
            $acl->addRole($role);
        } else {
            $role = $acl->getRole($role);
        }

        // Set resources
        if (array_key_exists($role->getRoleId(), $aclConfig['permissions'])) {
            foreach ($aclConfig['permissions'][$role->getRoleId()] as $resource) {
                if (!$acl->hasResource($resource)) {
                    $acl->addResource(new GenericResource($resource));
                }

                // Add role to a specific resource
                $acl->allow($role, $resource);
            }
        }
    }

    // Assign the fully prepared ACL object    
    $e->getViewModel()->acl = $acl;
}

模块:: checkAcl()

public function checkAcl(MvcEvent $e) {

    // Get the route
    $route = $e->getRouteMatch()->getMatchedRouteName();

    // Use this if you have authentication set
    // Otherwise, take this off 
    $auth = new AuthenticationService();

    // Set role as you need  
    $userRole = 'guest';

    // Use this if you have authentication set
    // Otherwise, take this off  
    if ($auth->hasIdentity()) {
        $userRole = 'member';
        $loggedInUser = $auth->getIdentity();
        $e->getViewModel()->loggedInUser = $loggedInUser;
    }

    // Check if the resource has right permission 
    if (!$e->getViewModel()->acl->isAllowed($userRole, $route)) {
        $response = $e->getResponse();

        // Redirect to specific route
        $response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseUrl() . '/404');
        $response->setStatusCode(404);
        return;
    }
}

现在,在onBootstrap() Module.php方法中调用上述方法。初始化Module::initAcl()并通过向Module::checkAcl()事件添加route来检查资源权限。

模块:: onBootstrap()

public function onBootstrap(MvcEvent $e)
{   
    $this->initAcl($e);
    $e->getApplication()->getEventManager()->attach('route', array($this, 'checkAcl'));
}

让我们知道它对您有帮助!