The talented Evan Coury created a module that allows you to specify alte
Secondary menu
Zend Framework 2 Acl using a module and plugin
You are here
Home / Zend Framework 2 Acl u ...This is my first attempt at using ZF2's new module system to use Zend's access control list (ACL) implementation for priviledges management. More information on ""Zend\Permissions\Acl" can be found on Zend's website here.
This tutorial is based on the ZendFramework 2 Skeleton App from here. I'm sure there are other ways of accomplishing this but this is how I learned how to do it.
The module I created "MyAcl" sets up roles, resources and permissions to grant or deny access to requested pages. You should already have the "Application" and "Album" modules set up in order to test out the "MyAcl" module.
For this example, my apps root is "ZendSkeletonApplication". From the skeleton app you should already have 2 modules there called "Album" and "Application".
Now were going to add a new module called "MyAcl". So create a new folder in "ZendSkeletonApplication/module" called "MyAcl". The directory structure will be "ZendSkeletonApplication/module/MyAcl".
In the "MyAcl" folder create a "Module.php" file.
Module.php
namespace MyAcl;
use Zend\ModuleManager\ModuleManager; // added for module specific layouts. ericp
// added for Acl ###################################
use Zend\Mvc\MvcEvent,
Zend\ModuleManager\Feature\AutoloaderProviderInterface,
Zend\ModuleManager\Feature\ConfigProviderInterface;
// end: added for Acl ###################################
//class Module
class Module
{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
// added for Acl ###################################
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach('route', array($this, 'loadConfiguration'), 2);
//you can attach other function need here...
}
public function loadConfiguration(MvcEvent $e)
{
$application = $e->getApplication();
$sm = $application->getServiceManager();
$sharedManager = $application->getEventManager()->getSharedManager();
$router = $sm->get('router');
$request = $sm->get('request');
$matchedRoute = $router->match($request);
if (null !== $matchedRoute) {
$sharedManager->attach('Zend\Mvc\Controller\AbstractActionController','dispatch',
function($e) use ($sm) {
$sm->get('ControllerPluginManager')->get('MyAclPlugin')
->doAuthorization($e); //pass to the plugin...
},2
);
}
}
// end: added for Acl ###################################
/*
* // added init() func for module specific layouts. ericp
* <a href="http://blog.evan.pro/module-specific-layouts-in-zend-framework-2
">http://blog.evan.pro/module-specific-layouts-in-zend-framework-2
</a> */
public function init(ModuleManager $moduleManager)
{
$sharedEvents = $moduleManager->getEventManager()->getSharedManager();
$sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
// This event will only be fired when an ActionController under the MyModule namespace is dispatched.
$controller = $e->getTarget();
//$controller->layout('layout/zfcommons'); // points to module/Album/view/layout/album.phtml
}, 100);
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
module.config.php (In "module/MyAcl/config")
MyAclPlugin.php (In "module/MyAcl/src/MyAcl/Controller/Plugin")
namespace MyAcl\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin,
Zend\Session\Container as SessionContainer,
Zend\Permissions\Acl\Acl,
Zend\Permissions\Acl\Role\GenericRole as Role,
Zend\Permissions\Acl\Resource\GenericResource as Resource;
class MyAclPlugin extends AbstractPlugin
{
protected $sesscontainer ;
private function getSessContainer()
{
if (!$this->sesscontainer) {
$this->sesscontainer = new SessionContainer('zftutorial');
}
return $this->sesscontainer;
}
public function doAuthorization($e)
{
// set ACL
$acl = new Acl();
$acl->deny(); // on by default
//$acl->allow(); // this will allow every route by default so then you have to explicitly deny all routes that you want to protect.
# ROLES ############################################
$acl->addRole(new Role('anonymous'));
$acl->addRole(new Role('user'), 'anonymous');
$acl->addRole(new Role('admin'), 'user');
# end ROLES ########################################
# RESOURCES ########################################
$acl->addResource('application'); // Application module
$acl->addResource('album'); // Album module
# end RESOURCES ########################################
################ PERMISSIONS #######################
// $acl->allow('role', 'resource', 'controller:action');
// Application -------------------------->
$acl->allow('anonymous', 'application', 'index:index');
$acl->allow('anonymous', 'application', 'profile:index');
// Album -------------------------->
$acl->allow('anonymous', 'album', 'album:index');
$acl->allow('anonymous', 'album', 'album:add');
$acl->deny('anonymous', 'album', 'album:hello');
$acl->allow('anonymous', 'album', 'album:view');
$acl->allow('anonymous', 'album', 'album:edit'); // also allows route: zf2-tutorial.com/album/edit/1
//$acl->deny('anonymous', 'Album', 'Album:song');
################ end PERMISSIONS #####################
$controller = $e->getTarget();
$controllerClass = get_class($controller);
$moduleName = strtolower(substr($controllerClass, 0, strpos($controllerClass, '\\')));
$role = (! $this->getSessContainer()->role ) ? 'anonymous' : $this->getSessContainer()->role;
$routeMatch = $e->getRouteMatch();
$actionName = strtolower($routeMatch->getParam('action', 'not-found')); // get the action name
$controllerName = $routeMatch->getParam('controller', 'not-found'); // get the controller name
$controllerName = strtolower(array_pop(explode('\\', $controllerName)));
/*
print '<br>$moduleName: '.$moduleName.'<br>';
print '<br>$controllerClass: '.$controllerClass.'<br>';
print '$controllerName: '.$controllerName.'<br>';
print '$action: '.$actionName.'<br>'; */
#################### Check Access ########################
if ( ! $acl->isAllowed($role, $moduleName, $controllerName.':'.$actionName)){
$router = $e->getRouter();
// $url = $router->assemble(array(), array('name' => 'Login/auth')); // assemble a login route
$url = $router->assemble(array(), array('name' => 'application'));
$response = $e->getResponse();
$response->setStatusCode(302);
// redirect to login page or other page.
$response->getHeaders()->addHeaderLine('Location', $url);
$e->stopPropagation();
}
}
}
In the example above, we set two permissions to deny anonymous users access to two routes: "zf2-tutorial.com/album/hello" & "zf2-tutorial.com/album/song". They will be redirected to "zf2-tutorial.com/application"
application.config.php (In "ZendSkeletonApplication/config")
return array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'Application',
'Album',
'MyAcl',
),
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => array(
// This should be an array of paths in which modules reside.
// If a string key is provided, the listener will consider that a module
// namespace, the value of that key the specific path to that module's
// Module class.
'module_paths' => array(
'./module',
'./vendor',
),
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively overide configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
),
);
Fork this entire application at my Github repo here.
Recent Posts
Here is a little bash script I wrote to do a daily backup of my database
This is my first attempt at using ZF2's new module system to use Zend's
Need Help?
Recent comments
- erroe 12 years 5 days ago
- BUG 12 years 1 week ago
- cool stuff 12 years 2 months ago
Comments
BUG
Thanks for your nice tutorial. But I can not run it. It says -
Fatal error: Class 'MyAcl\Controller\Plugin\MyAclPlugin' not found in D:\xampp\htdocs\ZendSkeletonApplication-Acl-Module-Plugin\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170
Would you please help me to figure out this problem?
erroe
sesscontainer) { $this->sesscontainer = new SessionContainer('zf2tutorial'); } return $this->sesscontainer; } public function doAuthorization($e) { // set ACL $acl = new Acl(); $acl->deny(); // on by default //$acl->allow(); // this will allow every route by default so then you have to explicitly deny all routes that you want to protect. # ROLES ############################################ $acl->addRole(new Role('anonymous')); $acl->addRole(new Role('user'), 'anonymous'); $acl->addRole(new Role('admin'), 'user'); # end ROLES ######################################## # RESOURCES ######################################## $acl->addResource('application'); // Application module $acl->addResource('album'); // Album module # end RESOURCES ######################################## ################ PERMISSIONS ####################### // $acl->allow('role', 'resource', 'controller:action'); // Application --------------------------> $acl->allow('anonymous', 'application', 'index:index'); $acl->allow('anonymous', 'application', 'profile:index'); // Album --------------------------> $acl->allow('anonymous', 'album', 'album:index'); $acl->allow('anonymous', 'album', 'album:add'); $acl->deny('anonymous', 'album', 'album:hello'); // denies access to route: /album/hello $acl->allow('anonymous', 'album', 'album:view'); $acl->allow('anonymous', 'album', 'album:edit'); // also allows: http://zf2-tutorial.com/album/edit/1 //$acl->deny('anonymous', 'Album', 'Album:song'); ################ end PERMISSIONS ##################### $controller = $e->getTarget(); $controllerClass = get_class($controller); $moduleName = strtolower(substr($controllerClass, 0, strpos($controllerClass, '\\'))); $role = (! $this->getSessContainer()->role ) ? 'anonymous' : $this->getSessContainer()->role; $routeMatch = $e->getRouteMatch(); $actionName = strtolower($routeMatch->getParam('action', 'not-found')); // get the action name $controllerName = $routeMatch->getParam('controller', 'not-found'); // get the controller name $controllerName = strtolower(array_pop(explode('\\', $controllerName))); /* print '
$moduleName: '.$moduleName.'
'; print '
$controllerClass: '.$controllerClass.'
'; print '$controllerName: '.$controllerName.'
'; print '$action: '.$actionName.'
'; */ #################### Check Access ######################## if ( ! $acl->isAllowed($role, $moduleName, $controllerName.':'.$actionName)){ $router = $e->getRouter(); // $url = $router->assemble(array(), array('name' => 'Login/auth')); // assemble a login route $url = $router->assemble(array(), array('name' => 'application')); $response = $e->getResponse(); $response->setStatusCode(302); // redirect to login page or other page. $response->getHeaders()->addHeaderLine('Location', $url); $e->stopPropagation(); } } }
Fatal error: Class 'MyAcl\Controller\Plugin\MyAclPlugin' not found in C:\xampp\htdocs\ZendSkeletonApplication-Acl-Module-Plugin-master\vendor\ZF2\library\Zend\ServiceManager\AbstractPluginManager.php on line 170
Add new comment