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

Does not work Acl on Micro

My SecurityMiddleware :

class SecurityMiddleware {

    public function __construct($app) {
        $acl = $this->getAcl();
        //get the handler
        $arrHandler = $app->getActiveHandler();
        //get the controller for this handler (strip off the Controller namespace if required)
        $controller = str_replace('Controllers\\','',get_class($arrHandler[0]));
        //is an Admin user allowed to view the current controller/method?
        $allowed = $acl->isAllowed('Admin', $controller, $arrHandler[1]);

        return $allowed;
    }

    private function getAcl() {
        $acl = new AclList();

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

        $roles = [
            'worker'    => new Role('Worker'),
            'admin'     => new Role('Admin'),
            'victim'    => new Role('Victim')
        ];

        foreach($roles as $role) $acl->addRole($role);
        $acl->addInherit('Admin', 'Worker');

        $adminResource = ['Admin' => ['Accounts', 'Workers', 'Payments', 'Notifications', 'MakePayment']];

        foreach($adminResource as $controller => $methods)
            $acl->addResource(new Resource($controller), $methods);

        // Allows
        foreach($acl->getRoles() as $role) {
            if($role->getName() == 'Admin') 
                foreach($adminResource as $resource => $method)
                    $acl->allow($role->getName(), $resource, $method);
        }

        return $acl;
    }
}

and in index.php

    $app->before(new SecurityMiddleware($app));

On the output I get only a blank page

Most likely because you have some kind of error. Just check your logs.



2.5k
edited May '18

I did Middleware: class CheckAuthMiddleware implements MiddlewareInterface{

        public function beforeExecuteRoute(Event $event, Micro $app) {
            $acl = $this->getAcl();
            //get the handler
            $arrHandler = $app->getActiveHandler();
            //get the controller for this handler (strip off the Controller namespace if required)
            $controller = str_replace('Controllers\\','',get_class($arrHandler[0]));
            //is an Admin user allowed to view the current controller/method?
            $allowed = $acl->isAllowed('Admin', $controller, $arrHandler[1]);

            return false;
        }

        public function call(Micro $app)
        {
            return true;
        }

        private function getAcl() {
            $acl = new AclList();

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

            $roles = [
                'worker'    => new Role('Worker'),
                'admin'     => new Role('Admin')
            ];

            foreach($roles as $role) $acl->addRole($role);
            $acl->addInherit('Admin', 'Worker');

            $adminResource = ['Admin' => ['Accounts', 'Workers', 'Payments', 'Notifications', 'MakePayment']];

            foreach($adminResource as $controller => $methods)
                $acl->addResource(new Resource($controller), $methods);

            // Allows
            foreach($acl->getRoles() as $role) {
                if($role->getName() == 'Admin') 
                    foreach($adminResource as $resource => $method)
                        $acl->allow($role->getName(), $resource, $method);
            }

            return $acl;
        }
    }

After Routes i write: // Middlewares $app->before(new CheckAuthMiddleware());

And for the test I return false, but the method still works: public function Accounts() {

          //$accounts = $this->modelsManager->executeQuery('SELECT * FROM App\Models\Accounts AS a LEFT JOIN App\Models\Workers AS w ON (a.worker_id = w.id)');
          $accounts = $this->modelsManager->createBuilder()
                                      ->from(['account' => Accounts::class])
                                      ->leftJoin(Workers::class, 'worker.id = account.worker_id', 'worker')
                                      ->columns('account.*,worker.*')
                                      ->getQuery()
                                      ->execute();

          $this->response->setJsonContent(['accounts' => $accounts])->send();
      }

And outputs all records

Most likely because you have some kind of error. Just check your logs.

Well in micro you need to do $app->stop() to stop execution of handler/action.



2.5k

And for what then, return false; I think he stoped handle

Well in micro you need to do $app->stop() to stop execution of handler/action.



2.5k
edited May '18

And it does not work at all. As if middleware is not there.

I just use vuejs more:

          // Middlewares
      $app->before(function() use ($app) {
          if($app->request->isGet())echo $app->view->render('index.html');
      });

  $app->before(new CheckAuthMiddleware());

Well in micro you need to do $app->stop() to stop execution of handler/action.

Don't understand you, i mean in middleware you need to do $app->stop(); https://github.com/phalcon/cphalcon/blob/master/phalcon/mvc/micro.zep#L667



2.5k

Dont worked:

public function beforeExecuteRoute(Event $event, Micro $app) {
        $acl = $this->getAcl();
        //get the handler
        $arrHandler = $app->getActiveHandler();
        //get the controller for this handler (strip off the Controller namespace if required)
        $controller = str_replace('Controllers\\','',get_class($arrHandler[0]));
        //is an Admin user allowed to view the current controller/method?
        $allowed = $acl->isAllowed('Admin', $controller, $arrHandler[1]);

        $app->stop();
        return false;
    }

Don't understand you, i mean in middleware you need to do $app->stop(); https://github.com/phalcon/cphalcon/blob/master/phalcon/mvc/micro.zep#L667

edited May '18

What you mean didn't work? What is happening atm? You are not providing enough information.

Is middleware even executed first? Just try to debug it first yourself using xdebug or even var_dump.



2.5k

Look. I use a Falcon in conjunction with vue.js. I use the Falcon as Api, that is, for all GET requests, Phalcon returns the html page to which my js is connected. In the first middleware, I have a test to ensure that all GET requests return this html. And to check POST requests, I use a second middleware. It is described above. The problem is that this second middleware does not want to work. I always return false for the test in beforeExecuteRoute or $ app-> stop (); but even so the Controller and Method corresponding to the POST route is executed. I do not understand why.

What you mean didn't work? What is happening atm? You are not providing enough information.

Is middleware even executed first? Just try to debug it first yourself using xdebug or even var_dump.



145.0k
Accepted
answer
edited May '18

But is it even executed? You didn't answer my question anyway.

You are returning true in call method of Middleware. So what you expect? Middleware isn't called on micro events, it's not an handler for events of micro app so you need to move your code to call method, when micro calls middlewares it only executes code in call method.



2.5k

Thank you, you helped a lot!

But is it even executed? You didn't answer my question anyway.

You are returning true in call method of Middleware. So what you expect? Middleware isn't called on micro events, it's not an handler for events of micro app so you need to move your code to call method, when micro calls middlewares it only executes code in call method.