Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

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.



347
edited 21d ago

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.



347

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.



347
edited 21d ago

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



347

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 21d ago

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.



347

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.



125.4k
Accepted
answer
edited 21d ago

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.



347

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.