I am building system and trying to decide between Voters and ACL. What I need to achieve is there should be users with different roles to access object properties, for example: A regular authenticated user could see Post and it contents but not it's "Position" attribute, and User with editor role could also see the Post and it's contents, and have permision to see "Position" attribute and edit it.
Can I achieve this functionality by using voters alone, or I need to use ACL?
EDIT:
I'm sorry for confusing question, I'm new to symfony and don't quite yet understand those concepts. What I wan't to achieve is permissions in object field level.
Regular user can access "TITLE" and "CONTENT" properties, and modify "CONTENT" property", moderator can view and edit, both of previous properties, and admin should have access to all object properties, and do whatever with them.
The docs only explain how to check access on objects rather than properties.
I'll explain the decisions I make when choosing between voters or ACL. Next I'll explain how you can use (Hierachy) voters to achieve your goal.
When users simply have or don't have access to a object based on a role, access can be performed using the firewall and is the simplest solution.
However when access depends on a per object basis under certain rules a Voter should be used. An example, Users can only edit a post when they created it. But moderators should always be ably to edit a post.
The most difficult of access control is when a user can be granted access by an other user. For example, an admin can assign users to a post and grant them edit permissions. This is a solution where access can't be decided based purely on the role of the user. The access/permissions need to be stored per user for an object. This is what ACL does. It stores permissions on objects in the database per user.
As for your problem.
Mostly these kind of uses are handled in the code itself. I've seen a lot of different forms for an entity. UserPostFormType, ModeratorPostFormType and AdminPostFormType. This isn't very dry as you can see. And checking the type of user in the code
Consider defining roles and manage them using hierarchy.
Define separate roles per property per action.
Thus define the following roles.
ROLE_ID_VIEW
ROLE_ID_EDIT
ROLE_TITLE_VIEW
ROLE_TITLE_EDIT
...
You can then assign these roles to the correct user role.
security:
role_hierarchy:
ROLE_USER: [ROLE_TITLE_VIEW, ROLE_CONTENT_VIEW, ROLE_CONTENT_EDIT]
ROLE_MODERATOR: [ROLE_USER, ROLE_TITLE_EDIT]
ROLE_ADMIN: [ROLE_MODERATOR, ROLE_ID_EDIT, ROLE_ID_VIEW]
You can now use the Hierarchy Voter to check if a user can modify or view a certain property.
The cleanest solution would be to create a Listener on you form which adds fields on your forms based the permissions the current user has.
Voters have nothing to do with ACL. Voters concern is route access whereas ACL concern is object read/write access.So it's not one or the other because they dont have anything to do with each other.
Related
I am using FOSUserBundle in my Symfony2 project.
My goal is to make the teams consist with multiple users. Users are invites by administrator (owner) by e-mail confirmation.
If a user belongs to one team, can't set up new accounts using the same address. Of course, each user should have the opportunity to unsubscribe from the team.
Are there any ready-made solutions? I looked for Groups With FOSUserBundle.
Or do you have any good advice?
You were right, groups can be a good ready-to-use solution to make your logic.
The association is already setup and it's also easy to extend.
The documentation (now part of Symfony's doc) contains a great guide to use groups.
Of course, you can make your own entity, take example from the FOSUB User->Group logic (association) .
You should see the Security and Roles part of the documentation to manage authorisations of your different kind of users.
You can assign roles to your different groups, and make your users directly inherit the roles of their group for manage access permissions.
For the confirmation email, see the corresponding documentation too .
And for the unsubscribing, just remove the association between the user you want remove from a Group and the Group (or Team).
This is also part of the association, see the doctrine documentation.
Good use.
I'd like to make a system with granular permissions so
Is there a way to make groups of claims and assign them to a role so when a user gets a role it gets all the claims?
Is it possible to create groups of claims or am I misunderstanding something?
I'm failling to find the purpose of claims.
This could be done using groups with various roles and the roles are gonna be the permissions, right? This is the way I should do it? Since roles per se are claims.
Following steps can solve your problem
Create granular level of roles...typically for each action
Group them up into GroupRoles...so that admin can easily manage it
Add individual level claims to user for specific permission
Some good examples of the same are below
http://www.3pillarglobal.com/insights/granular-level-user-and-role-management-using-asp-net-identity
http://bitoftech.net/2015/03/11/asp-net-identity-2-1-roles-based-authorization-authentication-asp-net-web-api/
Hope this solves your problem
I am trying to understand access control based on RBAC model. I referred to the following link.
NIST RBAC Data Model
I haven't understood this part clearly as mentioned in the excerpt -
*"Each session is a mapping of one user to possibly many roles, i.e., a user establishes a session during which the user activates some subset of roles that he or she is assigned. Each session is associated with a single user and each user is associated with one or more sessions. The function session_roles gives us the roles activated by the session and the function user_sessions gives us the set of sessions that are associated with a user. The permissions available to the user are the permissions assigned to the roles that are activated across all the user.s sessions."*
Question - How can session be used to activate roles ? The relationship between the user / group and roles are inserted as admin data. So, how does session activate subset of roles for a user ?
P.S -> I asked this question earlier here but without an answer. May be this question is too basic to ask but I am keen to understand it. Any use case or a link will definitely be helpful.
Thanks for your time.
In RBAC, administrators give permissions by assigning them to roles, and in addition by assigning roles to users. As you know, for a user to be able to use a particular permission, he will have to have been assigned at least one role that provides said solution.
So each user has a set of roles assigned to him. During a session, he can choose to activate (or deactivate) any of these roles, but no other. The activated roles determine which permissions are available to the user at a given time during the session. This is useful, for example, for dynamic separation of duty constraints, where two roles A and B can be assigned to the same user U, but can't be used together. Therefore, if U wants to use A, he will have to deactivate B before activating A.
From my experience in implementing RBAC, I pretty much avoided using dynamic management of multi-sessions.
At first it sounded like a pretty neat and flexible idea, but as you questioned on who activates/deactivates roles (and when), I realized the complexity and security risks wasn't worth the effort (my personal opinion).
The important thing to understand here and for which #Imontriux (above) mentioned:
"This is useful, for example, for dynamic separation of duty
constraints, where two roles A and B can be assigned to the same user
U, but can't be used together. Therefore, if U wants to use A, he will
have to deactivate B before activating A."
Most of the time, there are separation of duty constraints that must apply and in order to honour this, I simply chose to only have/manage one valid session per user at a time. If a user wants to authenticate under different set of roles, he/she is responsible in logging out and logging back in.
It pretty much simplified a lot of my code. It was a compromise I chose and could easily live with.
I need to automatically apply a role, Role X, to all Drupal users that have been granted a separate role, Role Y. In other words, I wish for Role X to be a subset of Role Y. How can I do this?
You could implement hook_user() in a custom module. On the 'insert' and/or 'update' action, you'd check for role Y in the $account->roles array. If present, add role X if not already there. This would ensure that your rule gets applied every time a user account gets created and/or changed.
For a bootstrapping/one time operation, take a look at user_multiple_role_edit(). It lets you add or remove roles for an array of user ids. Alternatively, you could do it directly in the database:
INSERT INTO users_roles (uid, rid)
SELECT uid, [roleX_ID] AS rid FROM users_roles
WHERE uid IN
(SELECT uid FROM users_roles WHERE rid = [roleY_ID])
AND uid NOT IN
(SELECT uid FROM users_roles WHERE rid = [roleX_ID])
;
I agree with Henrik Opel on using hook_user in a custom module would be a good solution to maintain the users and make sure they are up to date all the time.
Normally I wouldn't mind writing SQL or something alike, but in this case, since it's on a production site, I would prefer a different route, since if something can easily go wrong when writing raw SQL, a little typo can cause big troubles. Another good point is that you can run into problems as drupal wont be aware of what raw SQL you run on your database and might get out of sync with some processes, hooks and other processes that's normally run when you do things through the Drupal API.
Instead you can use the drupal user admin interface. I actually think that in this case, it is the easiest way to do what you want. Simply filter all users that are students. Click all the users and give them the member role. This is done with a few clicks in no time, and is very secure since Drupal will handle all the SQL for you.
Updated
With that many users, I'm surprised that you don't have a custom user and content managing page setup using views_bulk_operations. Using a few minutes, you can setup a admin page which you can use to preform bulk operations like changing user status, roles, or perform similar tasks for nodes. You can create your own filters using exposed views filters. So with a few clicks you can select all the users with role of student and that isn't member, select them all and add the member roll to them. The advantage doing this is not only that it's quick and safe, but you can create some nice managing pages for your site administrators, content creators etc. You should consider looking into this module.
The LDAP module allows you to dynamically assign roles based on DN. I actually had to write my own module that is tailored specifically to our system, otherwise I would be more than happy to share it.
link text
I wish to ensure a user has access to an aspx page by 'Zone'. For example, "Financials" is a Security Zone which some users should not have access to.
The result should not involve patterns such as MVP, MVC, MVVM, etc. I'm looking for something that's light and quick to do.
To make things easier I have a base class which each aspx page derives from. What is the easiest/best way to have each page to be checked versus a security zone given the userID?
Thanks.
I've used this, whether it's the best way is seriously questionable. I have a class I derive from Page, called SecurePage. In that I usually have a cross table in a database that lists objects, such as the page, and groups/users that have access to that page. Running a stored procedure using the UserID and the Object name (Page name in this case, but can be a field, or whatever) it returns whether that user or a group that the user belongs in has access. You can check this during the page init, and if it doesn't match up, then response.redirect them or whatever you want to do.
You basically need to create a little ACL implementation. (Access Control List).
Create a acl_roles table, with all your roles (Admin, Accountant, whatever, guest) and stuff. Then link the id of it with your user table, so each user has a role_id.
Then define a acl_resources table, where you add the "zones" in your app and the minimum role they have to be to access it.
Then at the start of each script simply do check if the current user has enough privileges to be in that zone.
There are more details into this, but that is the basic idea.
Yeah, use forms or Windows authentication. You can easily lock down different parts of your site based on the authenticated user's role. Look into using locations.
Why not just use the security features such as forms authentication built into .NET? It's very easy.