2
votes

My website is containing 3 types of users, that may have different ROLES.

ROLE_TRAINEE

ROLE_COMPANY_SUPER_ADMIN, ROLE_COMPANY_ADMIN, ROLE_COMPANY_TUTOR, ROLE_COMPANY_GUEST

ROLE_UNIVERSITY_SUPER_ADMIN, ROLE_UNIVERSITY_ADMIN, ROLE_UNIVERSITY_COORDINATOR, ROLE_UNIVERSITY_GUEST

Depending on ROLE I know what page they are allowed to enter and what not using security.yml access_control block.

access_control:
        - { path: ^/$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/trainee, roles: ROLE_TRAINEE }
        - { path: ^/company, roles: ROLE_COMPANY_GUEST }
        - { path: ^/university, roles: ROLE_UNIVERSITY_GUEST }

Now I came to the point that I have to separate the action that each user can execute: EDIT, DELETE and so on.

I checked ACL documentation and I got totally messed. I saw that I can do everything just using ROLES, just by calling isGranted(). Anyway, I wanted to hear what you guys think about ACL? Is it necessary in my case? What is the main advantage of using ACL?

1

1 Answers

1
votes

It depends on type of application.

I tested ACL's but personally never used in my apps, instead of I used Voters. ACL is ready to use mechanism and if you understand how it work, it can be powerfull tool (very advanced).


ROLES

To check some basic permissions you will use ROLES - for example ->isGranted('ROLE_ADMIN')

As you said this is enough if you don't have any sub-resources. This way is good if you create simple system. Rank: GUEST, EDITOR, MODERATOR, ADMIN etc. It is easy to read, understand and manage it.

As you said it's possible to use ROLES to check resource permissions, but for me (personally) using ROLES to save this type of information, like "He can read and edit product" is dirty. I think storing "army" of ROLES is not the best idea. This is example:

Because you don't need to declare ROLES, it's possible to create something like:

$resource_type = "PRODUCT";
$id = 3;
$role = "ROLE_".$resource_type."_".$id."_EDIT";
->isGranted($role);

In this example you check that user has role ROLE_PRODUCT_3_EDIT. When user create new product, he gain roles to manage his resource and you can check it later. For example he can gain this set of roles:

ROLE_PRODUCT_3_EDIT,ROLE_PRODUCT_3_READ,ROLE_PRODUCT_3_DELETE or ROLE_PRODUCT_3_OWNER

This is only example, you can do it in different ways but it shows problem with ROLES. If your User create many resources, he gain many, many, many roles... In addition this method has few flaws - for example you can't change resource type (PRODUCT) or ID - if you do it, your whole permission system will be broken.

ACL

Before use it you have to understand how it works :) I think this rule should be used everywhere but for ACL this is very very important.

Symfony ACL documentation is quite clear.

In complex applications, you will often face the problem that access decisions cannot only be based on the person (Token) who is requesting access, but also involve a domain object that access is being requested for. This is where the ACL system comes in.

That's all. ACL is built in, ready to use security system, it's very powerfull but as author said:

Using ACL's isn't trivial, and for simpler use cases, it may be overkill. If your permission logic could be described by just writing some code (e.g. to check if a Blog is owned by the current User), then consider using voters. A voter is passed the object being voted on, which you can use to make complex decisions and effectively implement your own ACL. Enforcing authorization (e.g. the isGranted part) will look similar to what you see in this entry, but your voter class will handle the logic behind the scenes, instead of the ACL system.

If you understand how to use ACL is very easy to use, you don't need even create any special DB tables or classes.

VOTERS

If you read ACL code you can see that ACL is built on Voters. You can do very complicated permission system with Voters. Voter is good idea to deal with advanced permissions to resources - for example your User can EDIT comment if he is OWNER or site ADMIN.

In short - all cases where your permissions depends on many conditions. Using Voters you can easly create permission system based on Ranks.

  • (entity)User has (entity)Rank.
  • (entity)Rank has set of (string)ROLES.
  • ROLE give you set of (string)PERMISSIONS.

You can manage Users Rank and change Rank permissions changing its ROLES. In result all Users with this Rank get new permissions.


In short - If you have entity resources (document system), Voter or ACL is good idea. Remeber that you can use ROLES and Voters in the same time. ACL is nice for entity resources. Voter can be used for more complicated situatuons, where user need permissions based on some special cases (and normal too).