问题
In my Symfony2 project I managed to setup FOSUserBundle + SonataUserBundle + SonataAdminBundle following official docs. Now comes the time to setup the ACL (Access control list).
What I did :
Created an AdminClass called AdminReport
app/console sonata:admin:setup-acl
install ACL for sonata.admin.report update role: ROLE_SONATA_ADMIN_REPORT_GUEST, permissions: ["LIST"] update role: ROLE_SONATA_ADMIN_REPORT_STAFF, permissions: ["LIST","CREATE"] update role: ROLE_SONATA_ADMIN_REPORT_EDITOR, permissions: ["OPERATOR","EXPORT"]
- created a new user, granted him with ROLE_SONATA_ADMIN_REPORT_STAFF
- app/console sonata:admin:generate-object-acl
- Logged in with this user and accessed the default /admin/dashboard
The block containing the AdminReport should appear but it's not... I am missing something ?
Here's my config.yml
sonata_admin: security: handler: sonata.admin.security.handler.acl information: GUEST: [VIEW, LIST] STAFF: [EDIT, LIST, CREATE] EDITOR: [OPERATOR, EXPORT] ADMIN: [MASTER] admin_permissions: [CREATE, LIST, DELETE, UNDELETE, EXPORT, OPERATOR, MASTER] object_permissions: [VIEW, EDIT, DELETE, UNDELETE, OPERATOR, MASTER, OWNER]
EDIT I tried to access directly app_dev.php/admin/app/report/list with this user, and Symfony throws an Access Denied error. Log says
DEBUG - Access denied, the user is neither anonymous, nor remember-me. And if I access app_dev.php/admin/app/report/list it works !
So I tried to change the handler from
sonata.admin.security.handler.aclto
sonata.admin.security.handler.roles
It works because I can see the block in admin dashboard. I also tried to change
access_decision_manager: strategy: unanimousto
affirmativebut it doesn't work...
I am definitely missing something but where ?
回答1:
Well, after some tweaking I achieved to make it working.
First, in my 'sonata.yml' in app/config/ I have changed the perms like the following :
app/config/sonata.yml :
sonata_admin:
security:
handler: sonata.admin.security.handler.acl
# acl security information
information:
# GUEST: [VIEW, LIST]
# STAFF: [EDIT, LIST, CREATE]
# EDITOR: [OPERATOR, EXPORT]
# ADMIN: [MASTER]
EDIT: EDIT
LIST: LIST
CREATE: CREATE
VIEW: VIEW
DELETE: DELETE
EXPORT: EXPORT
MASTER: MASTER
To avoid this...
DEBUG - Access denied, the user is neither anonymous, nor remember-me
... i've commented out the following, because i think the firewall voter block the access to my user. Maybe not the wiser solution, but runs good for now :)
app/config/security.yml :
# set access_strategy to unanimous, else you may have unexpected behaviors
# access_decision_manager:
# strategy: unanimous
Notice that my app is built only around the admin dahboard, so each user needs to have the dashboard access when they're created. In that way, I've modified my User constructor like this :
src/Application/Sonata/UserBundle/Entity/User.php :
class User extends BaseUser
{
/**
* @var integer $id
*/
protected $id;
public function __construct() {
parent::__construct();
// your own logic
$this->roles = array('ROLE_USER', 'ROLE_SONATA_ADMIN', 'ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT');
}
/**
* Get id
*
* @return integer $id
*/
public function getId()
{
return $this->id;
}
}
EDIT : It seems that, without knowing it, I replied to another of your questions ^^" (How can I assign default role to user in Symfony2)
Now each user can access the dashboard but like your issue, they cannot see anything.
I needed to use ACL, but like roles my users belong to groups who have their own ACL.
Once my user belong to one or many groups, he got the groups permissions in addition of his own permissions.
By managing one group's permissions, each user belonging to this group have his permissions modified. And by editing a user's permissions, I can make it access some pages that a group won't allow.
For example :
┌─────────────┐
│ GROUP_1 │ ┌───────────────┐
├─────────────┤ │ USER_1 │
│ CAT2_VIEW │ │ applied perms │
│ CAT2_LIST │ ├───────────────┤
│ CAT2_EDIT │ │ CAT1_VIEW │
│ CAT2_DELETE │ │ CAT1_LIST │
├─────────────┤ ├───────────────┤
│ CAT3_VIEW │ ├────┐ │ CAT2_VIEW │
┌─────────────┐ │ CAT3_LIST │ │ │ CAT2_LIST │
│ USER_A │ │ CAT3_EDIT │ │ │ CAT2_EDIT │
├─────────────┤<────────┤ CAT3_DELETE │ │ │ CAT2_DELETE │
│ CAT1_VIEW │ └─────────────┘ │ ├───────────────┤
│ CAT1_LIST │ ├────> │ CAT3_VIEW │
│ │ ┌─────────────┐ │ │ CAT3_LIST │
│ │<────────┤ GROUP_2 │ │ │ CAT3_EDIT │
└─────────────┘ ├─────────────┤ │ │ CAT3_DELETE │
│ CAT4_VIEW │ │ ├───────────────┤
│ CAT4_LIST │ │ │ CAT4_VIEW │
│ CAT4_EDIT │ ├────┘ │ CAT4_LIST │
│ CAT4_DELETE │ │ CAT4_EDIT │
│ CAT4_EXPORT │ │ CAT4_DELETE │
└─────────────┘ │ CAT4_EXPORT │
└───────────────┘
I managed to make it work this way, like I wanted, but I don't know if this is the best solution for your issue. I hope this will help you :)
PS : If anyone see any mistake or any illogical thing, don't hesitate to tell me in comment, i'm still learning to use it, and it'll be helpful :)
回答2:
The PermissionMap of SonataAdminBundle extends Symfony's BasicPermissionMap. Only if you change this default configuration, the AclVoter supports the attributes 'LIST' and 'EXPORT' and can possibly vote to grant the wanted permissions.
parameters:
security.acl.permission.map.class: Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap
See my answer to AclVoter denies access to 'LIST'
来源:https://stackoverflow.com/questions/32380688/acl-sonataadminbundle-sonatauserbundle