在没有SonataUserBundle的Sonata中删除每个用户角色的特定路由

Men*_*s93 8 php symfony sonata-admin sonata-user-bundle

我在Symfony 3中使用了SonataAdminBundle.因为我使用Symfony 3,我仍然无法使用SonataUserBundle.所以我只使用带有FOSUserBundle的SonataAdminBundle.

现在我试图实现的是隐藏每个角色的特定路线.例如,我只有三个角色;

  • 超级管理员
  • 管理员
  • 另一个角色

超级管理员拥有管理员拥有的所有角色,管理员拥有所有第三个角色,第三个显然拥有ROLE_USER.超级管理员应该能够创建新用户并为他分配角色.超级管理员还应该能够更改用户的密码.用户应该能够更改自己帐户的密码.最后,超级管理员应该更改自己的角色和创建新用户的其他角色.

如何在不使用SonataUserBundle的情况下实现此目的.为了删除路线部分我试过这样的事情:

protected function configureRoutes(RouteCollection $collection)
{
    $securityContext = $this->getConfigurationPool()->getContainer()->get('security.authorization_checker');

    if (!$securityContext->isGranted('ROLE_SUPER_ADMIN')) {
        $collection->remove('create');
        $collection->remove('edit');
    }
}
Run Code Online (Sandbox Code Playgroud)

但我想有更好的解决方案.我完全了解有关安全性官方文档,但我对此感到困惑,这是否意味着我必须对我security.yml文件中所有不同管理员的每个角色进行硬编码?没有SonataUserBundle,这甚至可以工作吗?我不想为ACL添加额外的数据库表.

有人可以帮助和/或提供一个很好的例子吗?我会非常感激的.

yce*_*uto 3

如何在没有 的情况下管理 Sonata 中的用户和角色SonataUserBundle

答:我们需要做同样的事情SonataUserBundle(但让我们简单一点)

ROLE_基于Symfony flat 的安全性类比:

  • 房子:有门和钥匙(系统)的建筑物。
  • 门:房屋内限制出入的地方 - isGranted()

    // the door is here, we need the key to open it.
    if ($this->isGranted('ROLE_FOO')) {
        // restricted access to do something
    } 
    
    Run Code Online (Sandbox Code Playgroud)
  • 钥匙:授予进入受限门的权限 - ROLE_*

    class User extends FOSUser
    { 
        public function getRoles()
        {
            // the keys comes from DB or manually.
            // e.g: 
            return ['ROLE_FOO'];
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 万能钥匙:一把可以打开几扇门的钥匙:

    # app/config/security.yml
    
    security:
        role_hierarchy:
            # other than opening the door "isGranted('ROLE_BAR')"
            # we can also opening the door "isGranted('ROLE_FOO')" with this single key.
            ROLE_BAR: ROLE_FOO
    
    Run Code Online (Sandbox Code Playgroud)

按照这个类比,已经创建了限制对跨受管理实体的每个默认操作(例如操作SonataAdminBundle)的访问的门。list

因此,我们的工作是“仅”将钥匙分配给用户(除非您需要创建自己的门)。有很多方法可以实现这一目标(这取决于您的需要)。

注意:如果您没有角色层次结构,则只有单个密钥(即没有主密钥),这使得角色(密钥)的分配不太灵活。

现在,SonataAdminBundle使用一种特殊的方法来检查管理类上下文中的键,只需执行以下操作:$admin->isGranted('list'),这是因为他有自己的isGranted()函数('list'操作名称在哪里),但实际上它所做的是构建角色名称(通过使用当前的管理代码)在检查之前,所以他最终验证了这一点:isGranted('ROLE_APP_BUNDLE_ADMIN_FOO_ADMIN_LIST')-这个密钥是我们需要“提供”给用户的密钥-。

如何从Sonata管理系统获取角色列表?

在控制器上下文中:

public function getSonataRoles()
{
    $roles = [];

    // the sonata admin container
    $pool = $this->get('sonata.admin.pool');

    foreach ($pool->getAdminServiceIds() as $id) {
        // gets the registered admin instance from id service name
        $admin = $pool->getInstance($id);

        // the role security handler instance (must be configured)
        $securityHandler = $admin->getSecurityHandler();

        // gets the base role name from admin code 
        // e.g. 'ROLE_APP_BUNDLE_ADMIN_FOO_ADMIN_%s'
        $baseRole = $securityHandler->getBaseRole($admin);

        // gets the access actions (e.g. LIST, CREATE, EDIT, etc.)
        foreach (array_keys($admin->getSecurityInformation()) as $action) {
            // add the final role name
            // e.g. 'ROLE_APP_BUNDLE_ADMIN_FOO_ADMIN_LIST'
            $roles[] = sprintf($baseRole, $action);
        }
    }

    return $roles;
}
Run Code Online (Sandbox Code Playgroud)

接下来,您可以用它做任何事情(例如创建自定义表单类型来管理用户角色属性)。您可以对这些角色进行排序、分组,以尽可能简单的方式向用户显示此列表。

在这里,我们可以分配角色并工作,甚至无需使用role_hierarchy.

更多详细信息http://symfony.com/doc/current/bundles/SonataAdminBundle/reference/security.html