ACL + SonataAdminBundle + SonataUserBundle

无人久伴 提交于 2019-12-07 18:59:34

问题


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.acl
to
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: unanimous
to
affirmative
but 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!