We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

problem with security plugins

my application works well when I loggin then go to a controller page but as soon as I try to go back/refresh or click menu link to another controller, the app trigger "$this->session->destroy();" and apache log report " the Trying to destroy uninitialized session in .." a lot of time.

my app was working properly before I implement layouts in volt...

some ideas?

Can you post your Security Plugin code?



11.6k
<?php
use Phalcon\Acl;
use Phalcon\Acl\Role;
use Phalcon\Acl\Resource;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Acl\Adapter\Memory as AclList;
/**
 * SecurityPlugin
 *
 * This is the security plugin which controls that users only have access to the modules they're assigned to
 */
class SecurityPlugin extends Plugin
{
    /**
     * Returns an existing or new access control list
     *
     * @returns AclList
     */
    public function getAcl()
    {
        if (!isset($this->persistent->acl)) {
            $acl = new AclList();
            $acl->setDefaultAction(Acl::DENY);
            // Register roles
            $roles = [
                'salarie'  => new Role(
                    'salarie',
                    'accès limité.'
                ),
                'guests' => new Role(
                    'Guests',
                    'accès limité.'
                ),
                'admin' => new Role(
                    'admin',
                    'accès à l\'ensemble de l\'application.'
                ),
                'comptable' => new Role(
                    'comptable',
                    'accès au fonctions comptables de l\'application.'
                )
            ];
            foreach ($roles as $role) {
                $acl->addRole($role);
            }
            //Admin area resources
            $privateResources = array(
                'index'    => array('index', 'search', 'new', 'edit', 'save', 'create', 'delete'),
                'dashboard'   => array('index', 'search', 'new', 'edit', 'save', 'create', 'delete'),
                'clients' => array('index', 'search', 'nouveau', 'edit', 'save', 'creation', 'delete'),
                'articles' => array('index', 'search', 'new', 'edit', 'save', 'create', 'delete'),
                'parametres' => array('index', 'search', 'new', 'edit', 'save', 'create', 'delete'),
                'session'    => array('index', 'register', 'start', 'end'),

            );
            foreach ($privateResources as $resource => $actions) {
                $acl->addResource(new Resource($resource), $actions);
            }
            //Public area resources
            $publicResources = array(
                'index'      => array('index'),
                'about'      => array('index'),
                'errors'     => array('show401', 'show404', 'show500'),
                'session'    => array('index', 'register', 'start', 'end'),
                'contact'    => array('index', 'send')
            );
            foreach ($publicResources as $resource => $actions) {
                $acl->addResource(new Resource($resource), $actions);
            }
            //Grant access to public areas
            foreach ($roles as $role) {
                foreach ($publicResources as $resource => $actions) {
                    foreach ($actions as $action){
                        $acl->allow($role->getName(), $resource, $action);
                    }
                }
            }
            //Grant access to private area to role Users
            foreach ($privateResources as $resource => $actions) {
                foreach ($actions as $action){
                    $acl->allow('admin', $resource, $action);
                }
            }
            //The acl is stored in session, APC would be useful here too
            $this->persistent->acl = $acl;
        }
        return $this->persistent->acl;
    }
    /**
     * This action is executed before execute any action in the application
     *
     * @param Event $event
     * @param Dispatcher $dispatcher
     * @return bool
     */
    public function beforeDispatch(Event $event, Dispatcher $dispatcher)
    {
        $auth = $this->session->get('auth');
        if (!$auth){
            $role = 'Guests';
        } else {
            $role = $auth['role'];
        }
        $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 != Acl::ALLOW) {
            $dispatcher->forward(array(
                'controller' => 'errors',
                'action'     => 'show401'
            ));
            $this->session->destroy();
            return false;
        }
    }
}

I've now commented the '$this->session->destroy();' line and now it's works and ACL seems to are still working (i.e. protected pages are still not accessible as guest...)

Everytime an user has not priviledges you want to clear your persistent storage? This way evertime user access page without privs, he will be logged out. Is it really what you want?



11.6k

after a reboot of the staging server, I can uncomment the line and it re-work as expected...I can't say what happened, sorry..

Maybe some cache :)