最新消息:

Phalcon之ACL安全插件

ZmmFly 4888浏览 0评论

参考Phalcon文档中的INVO实例,以及ACL、Dispatcher、EventsManager说明。
目录结构以Phalcon生成的Simple项目为准,需要在loader.php中加入pluginsDir。

 #File:path/app/plugins/Security.php
<?php

use Phalcon\Events\Event,
    Phalcon\Mvc\User\Plugin,
    Phalcon\Mvc\Dispatcher,
    Phalcon\Acl;

/**
 * @name 权限安全插件
 * @required 需要 ACL|Event|Dispatcher|Session|Flash (视情况修改)
 * @author Xiyan <shenqhy#qq.com>
 */
class Security extends Plugin
{

    public function __construct($dependencyInjector)
    {
        $this->_dependencyInjector = $dependencyInjector;
    }

    private function getAcl()
    {
        if (!isset($this->persistent->acl))
        {
            //实例化ACL
            $acl = new Phalcon\Acl\Adapter\Memory();
            //设置默认权限(禁止)
            $acl->setDefaultAction(Phalcon\Acl::DENY);


            //添加角色
            $roles = array(
                'Guests' => new Phalcon\Acl\Role('Guests'),
                'Users'  => new Phalcon\Acl\Role('Users'),
                'Admins' => new Phalcon\Acl\Role('Admins'),
            );
            foreach ($roles as $role) {
                $acl->addRole($role);
            }

            $AllResources = array(
                'GuestsResources' => array(
                    'index'  => array('index','about'),
                    'signup' => array('index','register'),
                    'signin' => array('index','login','forgotpwd'),
                    'api'    => array('index','check_invitation_code','check_username_repeat'),
                    'file'   => array('index','download','report'),
                ),
                'UsersResources'  => array(
                    'index'  => array('index','about'),
                    'file'   => array('index','download','report'),
                    'uc'     => array('index','upload','fileedit','profile','pedit','files'),
                ),
                'AdminsResources' => array(
                    'index'  => array('index','about'),
                    'file'   => array('index','download','report'),
                    'xadmin' => array('index','users','allfiles','allreport','banfile'),
                ),
            );

            //添加资源并授权对应权限给角色
            foreach ($roles as $role) {
                foreach ($AllResources[$role->getName().'Resources'] as $resource => $actions) {
                    $acl->addResource(new Phalcon\Acl\Resource($resource), $actions);
                    foreach ($actions as $action) {
                        $acl->allow($role->getName(),$resource,$action);
                    }
                }
            }

            $this->persistent->acl = $acl;


        }
        return $this->persistent->acl;
    }


    public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
    {
        //xdebug_print_function_stack('join beforeDispatch');
        $auth = $this->session->get('auth');
        if (!$auth){
            $role = 'Guests';
        } else {
            $role = $auth['role'];
        }

        //获取控制器和动作
        $controller = $dispatcher->getControllerName();
        $action     = $dispatcher->getActionName();

        $acl        = $this->getAcl();

        $allowed = $acl->isAllowed($role, $controller, $action);
        if ($allowed != Acl::ALLOW) {
            $this->flash->error('无权限访问!');
            //在View中勿用{{ flash.output() }}输出,否则会抛出异常,在转发的对应View中使用{{ content() }}可正常输出
            $dispatcher->forward(array('controller'=>'index','action'=>'index'));
            return false;
        }
    }
}
/**
 * 注意,getAcl中修改角色大小写后
 * 需要在beforeExecuteRoute中同步修改以免抛出异常
 */
 #File:path/app/config/services.php
/*
 * 权限安全插件
 */
$di->set('dispatcher', function() use ($di) {
    $eventsManager = $di->getShared('eventsManager');

    $security = new Security($di);

    /**
     * We listen for events in the dispatcher using the Security plugin
     */
    $eventsManager->attach('dispatch', $security);

    $dispatcher = new Phalcon\Mvc\Dispatcher();
    $dispatcher->setEventsManager($eventsManager);

    return $dispatcher;
});

转载请注明:神奇海域 » Phalcon之ACL安全插件

发表我的评论
取消评论

Protected by WP Anti Spam

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址