无法使用acl和自定义调度程序访问我的页面

时间:2018-05-08 12:25:08

标签: php phalcon

我目前正在使用Phalcon 3.3 / PHP 7.2(Ubuntu 18.04 LTS / Windows 10)

我创建了一个自定义SecurityPlugin文件来验证用户访问路由的权限。我已经使用Phalcon的ACL定义了我的角色,资源和权限。

这是我的SecurityPlugin类

    <?php

use Phalcon\Acl;
use Phalcon\Acl\Resource;
use Phalcon\Acl\Role;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Acl\Adapter\Memory as AclList;

/**
 * Class SecurityPlugin
 *
 * This is the security plugin that makes sure users access the modules they are assigned to
 *
 */
class SecurityPlugin extends Plugin
{
    private function _getAcl()
    {
        if(!isset($this -> persistent -> acl))
        {
            $acl = new AclList();

            $acl -> setDefaultAction(Acl::DENY);

            //Add Roles
            $roles = [
                'base_acc' => new Role(
                    'BaseAcc',
                    'This role represents the standard users that are allowed on the platform'
                ),
                'guest'     => new Role(
                    'Guest',
                    'This is the default role assigned to users that are not logged in'
                )
            ];

            //Register Roles
            foreach ($roles as $role) {
                $acl -> addRole($role);
            }

            //Add Standard User Resources
            $standardResources = [
                'store'     => ['index']
            ];

            //Add Public Resources
            $publicResources = [
                'index'     => ['index'],
                'auth'      => ['index', 'login', 'logout', 'register', 'confirmEmail', 'continueReg', 'finishReg', 'verifyPasswordToken', 'forgotPassword', 'updatePassword'],
                'errors'    => ['show404', 'show503', 'errorConfirm']
            ];

            //Register Standard User Resources
            foreach ($standardResources as $resource => $actions)
            {
                $acl -> addResource(new Resource($resource), $actions);
            }

            //Register Public Resources
            foreach ($publicResources as $resource => $actions)
            {
                $acl -> addResource(new Resource($resource), $actions);
            }

            //Register Public Resources to all roles
            foreach ($roles as $role) {
                foreach ($publicResources as $resource => $actions){
                    foreach($actions as $action){
                        $acl -> allow($role -> getName(), $resource, $action);
                    }
                }
            }

            //Register Standard Resources to standard User Role
            foreach ($standardResources as $resource => $actions){
                foreach($actions as $action){
                    $acl -> allow('BaseAcc', $resource, $action);
                }
            }

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

        return $this -> persistent -> acl;
    }

    public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
    {
        $auth = $this->session->get('auth');
        if (!$auth){
            $role = 'Guests';
        } else {
            $role = 'BaseAcc';
        }

        $controller = $dispatcher->getControllerName();
        $action = $dispatcher->getActionName();

        $acl = $this->_getAcl();

        if (!$acl->isResource($controller)) {
            $dispatcher->forward([
                'controller' => 'errors',
                'action'     => 'show404'
            ]);

            return false;
        }

        $allowed = $acl->isAllowed($role, $controller, $action);
        if (!$allowed) {
            $dispatcher->forward([
                'controller' => 'errors',
                'action'     => 'show401'
            ]);
            //$this->session->destroy();
            return false;
        }
        //Checks thr current user role
        //$roles = [];
        /*$auth = $this -> session -> get('auth');
        if(!$auth)
        {
            $role = 'Guest';
        }
        else
        {
            $role = 'BaseAcc';
        }

        $acl = $this -> _getAcl();

        $controller = $dispatcher -> getControllerName();
        $action     = $dispatcher -> getActionName();
        $lastController = $dispatcher ->getLastController();

        if(!$acl -> isResource($controller))
        {
            $dispatcher -> forward([
                'controller'    => 'errors',
                'action'        => 'show404'
            ]);
            return false;
        }

        if(!$acl -> isAllowed($role, $controller, $action))
        {
            $dispatcher -> forward([
                'controller'    => 'errors',
                'action'        => 'show503'
            ]);
            return false;
        }*/

    }

}

我的应用程序引导程序的一部分:

    <?php

define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');

error_reporting(E_ALL);

use Phalcon\Mvc\View as ViewEngine;
use Phalcon\Mvc\Model\MetaData\Files as MetaDataAdapter;
use Phalcon\Mvc\Application as AppEngine;
use Phalcon\Flash\Session as FlashService;
use Phalcon\Flash\Direct as FlashDirect;
use Phalcon\Session\Adapter\Files as SessionHandler;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
//use Phalcon\Logger\Adapter\File as LogService;
use Phalcon\Logger\Factory as LogFactory;

try{

    //Try our Debugger
    // = new Phalcon\Debug();
    //$debug -> listen(true, true);

    //Application Loader
    $loader = new Phalcon\Loader();

    //Register Working Directories
    $loader -> registerDirs([
        APP_PATH . '/controllers',
        APP_PATH . '/config',
        APP_PATH . '/models',
        APP_PATH . '/cache',
        APP_PATH . '/plugins',
        BASE_PATH . '/vendor',
    ]);

    //Register Namespaces
    $loader -> registerNamespaces([
        //'AgroTech\Models'   => APP_PATH . '/models',
        'AgroTech\Plugins'  => APP_PATH . '/plugins'
    ]);

    //Register Loader
    $loader -> register();

    // Use composer autoloader to load vendor classes
    require_once BASE_PATH . '/vendor/autoload.php';

    $di = new Phalcon\Di\FactoryDefault();

    ...

    $di -> set('dispatcher', function() use ($di){
        $eventsManager = $di->getShared('eventsManager');

        //Bind our Custom Event Handlers
        $eventsManager -> attach('dispatch:beforeExecuteRoute', new SecurityPlugin());
        $eventsManager -> attach('dispatch:beforeException', new NotFoundPlugin());
        //xdebug_print_function_stack();

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

...

    $app = new AppEngine($di);

    $response = $app -> handle();

    $response -> send();

} catch(Phalcon\Exception $e){
    echo "Exception: " . $e -> getMessage();
    echo '<pre>' . $e -> getTraceAsString() . '</pre>';
}

但是,将事件'dispatch:beforeExecuteRoute'与我的SecurityPlugin绑定会给出503错误。禁用它会使我的所有页面都可访问。而且,禁用我的NotFoundPlugin(处理无效路由),我得到一个Dispatcher循环路由错误

我有什么问题吗?

注意:我将我的SecurityPlugin实现基于https://github.com/phalcon/invo

1 个答案:

答案 0 :(得分:0)

我能说什么?只需用xdebug甚至var_dumps调试它就可以了吗?检查$auth方法中的beforeExecuteRoute,控制器,操作等内容,并检查isAllowed返回的内容以及创建它后acl对象的外观,您会发现错误很容易。< / p>