我目前正在使用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
答案 0 :(得分:0)
我能说什么?只需用xdebug甚至var_dumps调试它就可以了吗?检查$auth
方法中的beforeExecuteRoute
,控制器,操作等内容,并检查isAllowed
返回的内容以及创建它后acl对象的外观,您会发现错误很容易。< / p>