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

Securing Controller-Action for certain parameters using ACL

Hello everybody,

this is my first post and I am still very new to the Phalcon-Framework, but I already love it. Now I am facing a problem and I couldn't find a way how to solve it yet. The following is only one example, in fact, I have this problem frequently in my application.

In my application, I have two roles, "users" and "admins". The profiles-controller has an action called "show" in order to show the profile of a user. The parameter of the show-action is the user-id. Now what I want is that regular users (role: user) are only allowed to use the "show"-action with the parameter of their own user-id stored in the session. Admins should be allowed to use any parameter wich allows them to view all profiles of all users. Is this realizable with the Acl-List and a Security-Plugin or is my whole approach wrong or too complicated?

Thank you and all the best, MSP



1.9k
edited Sep '16

You don't need ACL for that. Simple code in controller action, for example like: if ($user->id !== $session['id']) { return false; } would be enought

edited Sep '16

Well in 3.1.0 i will add Phalcon\Firewall which can be used to securing actions in controllers using acl or annotations. You will get here some options, thanks for idea for adding dispatcher params to it too.

Basically you need to use beforeExecuteRoute and acl. In phalcon 3.0.0 you can implements custom logic in acl, so for example:

// Define allow like this
$acl->allow('ROLE_XYZ', 'SomeController', 'someAction', function ($dispatcherParameters) {
    $userSession = Di::getDefault()->get('session')->get('user');
    return $dispatcherParameters['id'] == $userSession;
});
// In controller or beforeExecuteRoute or wherever you want:
$acl->isAllowed('ROLE_XYZ', 'SomeController', 'someAction', ['dispatcherParameters' => $this->dispatcher->getParams()]

I just recommend add this isAllowed method call in security plugin and that's it.

Check the docs about ACL and new things in 3.0.0:

https://docs.phalcon.io/pl/latest/reference/acl.html#function-based-access https://docs.phalcon.io/pl/latest/reference/acl.html#objects-as-role-name-and-resource-name

Thank you very much, both of you.

@ntesic: I could it implement your way, but I also have to check which role is currently trying to access the controller. I guess the whole point of the Acl and Security-Management is to outsource these kinds of verfications.

@wojciech: Perfect, I was aware of the Acl-functions, but I had no clue how to use it for this problem. Thanks a lot.

edited Sep '16

Hi again, I tried to implement the function based access, but I get the same error every time I try to use it. Even this little piece of code, will case the error "Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'"


$acl->allow($role, $resource, $action, function($param) {
    return $param;
});

$allowed = $acl->isAllowed($role, $controller, $action, array("param" => true));

Basically, the error always appears when I try to set a function as fourth parameter of the "allow"-function. Any ideas?

edited Sep '16

You can't cache(serialize) acl object when it has closure obviously by default. Just don't use cache for stroing acl. If you still need this functionality then extend acl class and and implement Serializable interface and serialize closure with https://github.com/jeremeamia/super_closure for example

Aaaaah :):) That's it, thank you! I wasn't aware that I was caching the ACL-List, but now it works. I don't the cache-functionality, but thanks for the link anyway.