How to secure admin specific area to specific role using SonataAdmin - symfony

I have a working SonataAdminBundle installation, meanings my admin is well secured and cannot be accessed by simple users.
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
I have created some admin sections in the backoffice.
But, I don't want all of these sections to be available to each admin users. To explain a little bit, my website will allow to build custom websites. So I don't want a website admin to be able to access all websites informations. So I need to restrict some parts of the admin to super admin only.
In order to do that, I tried to limit the access to one of the section to Super admin only
- { path: ^/admin/app/site/, role: [ROLE_SUPER_ADMIN]}
Here is my role hierarchy
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN]
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
SONATA:
- ROLE_SONATA_PAGE_ADMIN_PAGE_EDI
The problem is, if I create a new user with my super admin account and give him the ROLE_ADMIN.
Then this user is still able to access my admin/app/site/* section so obviously it's not working and I can't figure it why.
EDIT: I have the feelings this can't be done without using ACL...but I don't really need ACL that much...

Related

Sonata Admin restrict action if user type XXX

I'm using Sonata Admin for a project and i have a problem.
I'm using FosUserBundle and i have several type of users, ex Admin and Superviser.
I have two entities User and Document.
An account type Admin can manage Document and User, but I want a Superviser can only manage Document.
How can I do that ?
When I connect with a Superviser, I don't want to have the choice to create edit etc... a user
Thanks !
Sonata Admin Docs - Security
Looks like your situation can be handled with Roles:
Incorporate FOSUserBundle into Sonata Admin with SonataUserBundle (you may already have done this)
Set up appropriate roles in security.yml. These are standard Symfony Roles, but following a special Sonata Admin naming convention, e.g. (adapted from docs with your Entities):
app/config/security.yml
security:
...
role_hierarchy:
#collect specific Sonata permissions together for convenience
ROLE_SONATA_USER:
- ROLE_SONATA_ADMIN_DEMO_USER_LIST
- ROLE_SONATA_ADMIN_DEMO_USER_VIEW
- ROLE_SONATA_ADMIN_DEMO_USER_CREATE
- ROLE_SONATA_ADMIN_DEMO_USER_EDIT
- ROLE_SONATA_ADMIN_DEMO_USER_DELETE
ROLE_SONATA_DOCUMENT:
- ROLE_SONATA_ADMIN_DEMO_DOCUMENT_LIST
- ROLE_SONATA_ADMIN_DEMO_DOCUMENT_VIEW
- ROLE_SONATA_ADMIN_DEMO_DOCUMENT_CREATE
- ROLE_SONATA_ADMIN_DEMO_DOCUMENT_EDIT
- ROLE_SONATA_ADMIN_DEMO_DOCUMENT_DELETE
#roles actually assigned to users
ROLE_SUPERVISER: [ROLE_USER, ROLE_SONATA_DOCUMENT]
ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_DOCUMENT, ROLE_SONATA_USER]
Assign ROLE_SUPERVISER and ROLE_ADMIN to users (via FOSUserBundle commands or $user->addRole)
These are then used by Sonata to limit access to functions, and e.g. to show which panels are appropriate on the main dashboard, and you yourself can test them to customised your own views etc

Sonata Admin: Let ROLE_SONATA_ADMIN edit entities of all users (ACL)

In SonataAdmin I have granted user a role: ROLE_SONATA_ADMIN
Also I have granted him: ROLE_SONATA_ADMIN_CITY_ADMIN
Unfortunately this user cannot edit City entities created by other users. Any guess how to fix this?

User with multiple roles, access always denied

Users may have multiple roles, e.g. ROLE_USER, ROLE_SUBSCRIBTION_FOO, ROLE_SUBSCRIBTION_BAR.
Based on their role I define an access control list:
- { path: ^/admin/helpdesk/foo, roles: ROLE_SUBSCRIPTION_FOO }
- { path: ^/admin/helpdesk/index, roles: ROLE_ADMIN }
The role hierarchy
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUBSCRIBTION_FOO: ROLE_ADMIN
ROLE_SUPER_ADMIN: ROLE_ADMIN
The problem now is, when user has the role ROLE_SUBSCRIBTION_FOO and accesses /admin/helpdesk/foo access is denied. The user has both ROLE_ADMIN and ROLE_SUBSCRIBTION_FOO. However when I have
- { path: ^/admin/helpdesk/foo, roles: ROLE_ADMIN }
it works but I need it to be
- { path: ^/admin/helpdesk/foo, roles: ROLE_SUBSCRIPTION_FOO }
which does not work, howeve the user does have the role? This is kinda weired. Any ideas where the problem is?
It looks like a typo to me. You defined ROLE_SUBSCRIBTION_FOO in your hierarchy (with a B) but you're wanting to restrict the path with ROLE_SUBSCRIPTION_FOO (with a P).
Looking at the setup everything seems right.
I want to change user roles dynamically from admin area of my application. So e.g. I give the FOO role to user BOB and expect the changes to take effect immediately.
But this does not work. The currently open session of user BOB is not refreshed. He has to reauthenticate himself. After reauthentication (logout and login again) symfonys security system will compare the role correctly with the given access list.
So I expected the user session to be updated automatically, but this is not possible with the default security system of symfony. I think it needs to be extended with database based session management. This way you could refresh the user session.

Multiple roles required for same url in symfony 2

This is how my security.yml looks like for access control list:
access_control:
- { path: ^/admin, roles: IS_AUTHENTICATED_FULLY }
- { path: ^/admin, roles: ROLE_ADMIN }
What I want to do is that user must have both roles (ROLE_ADMIN and IS_AUTHENTICATED_FULLY) in order to access the path as defined. But with above rules, if the user has any one of the role, the user can access the path as defined which i dont want. I also tried giving rule as follow with no success:
- { path: ^/admin, roles:[ROLE_ADMIN,IS_AUTHENTICATED_FULLY] }
How can I add rule that requires user to have both roles in order to access the path defined ?
IS_AUTHENTICATED_FULLY
returns true when ever a user is actually authenticated.
Anonymous users are technically authenticated, meaning that the
isAuthenticated() method of an anonymous user object will return true.
To check if your user is actually authenticated, check for the
IS_AUTHENTICATED_FULLY role.
So if a user has a role ROLE_ADMIN and is logged in, he is fully authenticated. As a result there is no need to set this requirement:
- { path: ^/admin, roles: IS_AUTHENTICATED_FULLY }
because you have (see below) which includes beeing fully authenticated
- { path: ^/admin, roles: ROLE_ADMIN }
And
- { path: ^/admin, roles: IS_AUTHENTICATED_FULLY }
will allow any user to see the admin section.
Read: http://symfony.com/doc/current/book/security.html
Looking at the problem itself, not at your specific situation.
If you need user to have all specified roles to access some path, this needs more configuration, as default RoleVoter grants access if current security token has at least one of specified roles.
RoleVoter grants access if token has at least one of passed roles, but Security component passes each of specified roles individually to each of the voters. So to change OR behaviour to AND behaviour all you need to do is to change decition manager strategy:
# app/config/security.yml
security:
access_decision_manager:
# strategy can be: affirmative (default one), unanimous or consensus
strategy: unanimous # if any voter returns ACCESS_DENIED, access is denied
If i didn't get you wrong , i think hierarchical roles
is a better approach http://symfony.com/doc/current/book/security.html#hierarchical-roles) .
#Hierarchical Roles
Instead of associating many roles to users, you can define role inheritance rules by creating a role hierarchy:
YAML
app/config/security.yml
security:
...
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_BOTH_ROLE_TOGETHER: [IS_AUTHENTICATED_FULLY,ROLE_ADMIN]
And them oyu can check for the hierarchy.

The Symfony2 application automatically logs out a user which has more than one role defined

I have a Symfony2 application that uses roles to manage authorization. It all works fine when I login with a user that only has one role associated with him, but when I try with one that has more than one role, the application logs him out automatically.
I really don't know what code sample to provide, so any question or suggestion is welcome.
Why don't you define ROLE HIERARCHY ?
so you can have only 1 role, but stacking the permission of role under it.
Something like :
security.yml :
role_hierarchy:
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_ADMIN: ROLE_MANAGER
ROLE_MANAGER: ROLE_USER
The ROLE_SUPER_ADMIN will have all the role under (admin / manager / user).
The documentation for the hierachical role is here : http://symfony.com/doc/current/book/security.html#hierarchical-roles

Resources