Zend Framework 2 入门-ACL(访问控制列表)

本文未对原文逐字翻译,只是将其方法做了简要的说明。详情见原文(Zend Framework 2 Acl using a module and plugin)。

本文将使用一个模块和插件来介绍Zend Framework 2 Acl的用法。

首先我们参照手册中的“Application”和“Album”模块建立一个名字为“MyAcl”的模块。

setp 1: 在“MyAcl”模块中建立一个名为“Module.php”的文件。

Module.php:

<?php
namespace MyAcl;

use Zend\ModuleManager\ModuleManager;
use Zend\Mvc\MvcEvent,
    Zend\ModuleManager\Feature\AutoloaderProviderInterface,
    Zend\ModuleManager\Feature\ConfigProviderInterface;

//class Module
class Module
{

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    // 添加Acl
    public function onBootstrap(MvcEvent $e)
    {
        $eventManager = $e->getApplication()->getEventManager();
        $eventManager->attach('route', array($this, 'loadConfiguration'), 2);
        // 你可以按照需要添加其他函数
    }

    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
            );
        }
    }

    /*
     *  添加当前模块的初始化函数
     *  详见:http://blog.evan.pro/module-specific-layouts-in-zend-framework-2     
     */
    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__,
                ),
            ),
        );
    }
}

Step 2: 配置module.config.php

(path: “module/MyAcl/config”)

<?php
return array(
    'controller_plugins' => array(
        'invokables' => array(
            'MyAclPlugin' => 'MyAcl\Controller\Plugin\MyAclPlugin',
        )
    ),
);

Step 3: 配置MyAclPlugin.php

(path: “module/MyAcl/src/MyAcl/Controller/Plugin”)

<?php
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)
    {
        // 设置 ACL
        $acl = new Acl();
        $acl->deny(); // 设置默认状态为禁止访问
        //$acl->allow(); // 或者设置默认为访问状态

        # 添加角色,角色之间可以继承,例如“user”拥有“anonymous”的所有权限。
        $acl->addRole(new Role('anonymous'));
        $acl->addRole(new Role('user'),  'anonymous');
        $acl->addRole(new Role('admin'), 'user');

        # 添加资源
        $acl->addResource('application'); // Application 模块
        $acl->addResource('album'); // Album 模块

        ################ 设置权限 #######################
        // $acl->allow('角色', '资源', '控制器:方法');

        // 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'); // 同样允许路由为 “zf2-tutorial.com/album/edit/1” 的访问
        //$acl->deny('anonymous', 'Album', 'Album:song');

        $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')); // 获取方法名
        $controllerName = $routeMatch->getParam('controller', 'not-found');     // 获取控制器名
        $controllerName = strtolower(array_pop(explode('\\', $controllerName)));

        /*
          print '<br>$moduleName: '.$moduleName.'<br>';
          print '<br>$controllerClass: '.$controllerClass.'<br>';
          print '$controllerName: '.$controllerName.'<br>';
          print '$action: '.$actionName.'<br>'; */

        #################### 检查权限 ########################
        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();
        }

    }
}

在上面的示例中,我们对anonymous用户设置了两个禁止访问的路由:”zf2-tutorial.com/album/hello”和”zf2-tutorial.com/album/song”。当其访问这两个路由时将会被重定向到”zf2-tutorial.com/application”。

Step 4: 在application.config.php中添加当前模块

<?php
return array(
    'modules' => array(
        'Application',
        'Album',
        'MyAcl',
    ), 

....(其他参数未显示)

);

转自http://mushroot.com/zf2-zend-framework-2-rumen-acl-fangwenkongzhiliebiao
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值