Search code examples
securitysymfonyauthorizationacl

Use ACL isGranted inside a voter isGranted


Edit: See my answer below.

For my needs, I decided to use both ACL and voters for my app (maybe it is not the best way, please, tell me if I'm wrong with this).

My entities represent a factory where there are : Lines owning Workshops owning Equipments owning Spare Parts.

I want to give either a manager or a viewer access to a line level. For this purpose, I use an ACL on the line.

Because there are more than 5000 spare parts per line, I don't want to write 5000 ace to tell symfony that this user, which is allowed to manage this line, can manage the spare parts of the line.

To solve this problem, I decided to add a voter before the acl check.

I do a isGranted('edit',$sparepart) which is handled by a voter, and inside my own voter, I want to perform a isGranted('OPERATOR',$line).

Actually, I have many more things to check (is the user plant manager ? for example) and I like to combine the voter and the ACL.

Unfortunately, I'm a bit lost and I don't manage to call the right "isGranted" from my voter, I get an infinite loop error.

Voter isGranted

$authChecker = $this->get('security.authorization_checker');
$authChecker->isGranted('', $post);

ACL isGranted

$securityContext = $this->get('security.context');
$securityContext->isGranted('EDIT', $comment);

I understand this might be a bit confusing, and maybe I'm not doing it the right way :s

Thanks for your help !


So I finally did this in another way. I use one voter and I created new entities to manage my access. I have a LineAccess entity with: ManyToOne: Line ManyToOne: User Sp_access: smallint Cart_access: smallint Line_access: smallint

So I check everything by myself and I also manage the links with my LineAccess entity and CustomerAccess entity. Finally, it is the best way I think. Good luck


Here is the full problem for the curious : The permissions selection table

For each user, I want to be able to select his permissions with this table. If, for example, I check Boeing (the customer) manage. I will create an ACL/ACE with OPERATOR for this $customer. That's it. Later, I want to check if this user is able to manage a line by first looking at a 'OPERATOR' on $line but if it doesn't exist, I will check 'OPERATOR' on $plant, and then 'OPERATOR' on $customer.

If I select Manage Dreamliner plant, I get this : enter image description here You can see that I'm still able to chose the kind of access to spare parts and cart. I can set this user, which is a plant manager, another permission : Spare parts manage. For that kind of permission, I can use the mask builder feature which allows me to store with a single integer "SP_MANAGER, CART_VALIDATE, LINE MANAGE', for example.

You can see that it gets a little complex here and this is why I think that ACL are my best friends, but I wanted to add a level of control in which I can manually select which isGranted() method, and on which entity.

I tried to be precise but it is not that easy :s

Thanks a lot for your help !


Solution

  • Voters and ACL are both standalone architecture approach to authorization. I'd recommend using Voters only, since they're easier to understand, use and extend.

    For more details on this comparison, check these explanatory slides.

    Where exactly you can't use Voters instead of ACL?

    Also, why you need to nest Voters/ACL?