如何在Symfony中检索完整的角色层次结构

lin*_*bou 17 symfony

我正在使用symfony2角色层次结构,它运行良好,但为了执行一些更改,我必须检索role_hierarchy我的设置security.yml.

role_hierarchy:
ROLE_USER: [ROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT]
Run Code Online (Sandbox Code Playgroud)

使用getRoles()刚刚返回ROLE_USER,我怎么能知道我的代码ROLE_USER与制作ROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT

谢谢你的帮助.

Kri*_*ith 39

您可以从容器中获取层次结构:

$container->getParameter('security.role_hierarchy.roles')
Run Code Online (Sandbox Code Playgroud)


twi*_*337 12

启用自动布线后,您还可以直接注入RoleHierarchy填充了全局角色层次结构的对象.只需RoleHierarchyInterface使用依赖注入注入您的控制器或服务:

use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;

public function __construct(RoleHierarchyInterface $roleHierarchy)
{
    $this->roleHierarchy = $roleHierarchy;
}
Run Code Online (Sandbox Code Playgroud)

注意:这也可以让你调用getReachableRoles()RoleHierarchy的对象,这可能是你的情况非常有用:

use Symfony\Component\Security\Core\Role\Role;

$this->roleHierarchy->getReachableRoles([new Role('ROLE_USER')])
Run Code Online (Sandbox Code Playgroud)

作为Symfony4你要添加一个别名,security.role_hierarchy在你config/services.yml加入下面的一行:

services:
    # creating alias for RoleHierarchyInterface
    Symfony\Component\Security\Core\Role\RoleHierarchyInterface: '@security.role_hierarchy'
Run Code Online (Sandbox Code Playgroud)


Erd*_* G. 8

Symfony 5答案

namespace App\Controller;

...
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
use Symfony\Component\Security\Core\Role\RoleHierarchy;

class UserController extends AbstractController
{
    private $roleHierarchy;

    /**
     * @Route("/users", name="users")
     */
    public function usersIndex(RoleHierarchyInterface $roleHierarchy)
    {
        $this->roleHierarchy = $roleHierarchy;

        // your user service or your Doctrine code here
        $users = ...

        foreach ($users as $user) {
            if ($this->isGranted($user, 'ROLE_SUPER_ADMIN')) {
                ...
            }
        }
        ...
    }

    private function isGranted(User $user, string $role): bool 
    {
        $reachableRoles = $this->roleHierarchy->getReachableRoleNames($user->getRoles());

        foreach ($reachableRoles as $reachableRole) {
            if ($reachableRole === $role) {
                return true;
            }
        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:为了简单起见,我将所有内容都放在控制器中,但当然我建议将角色管理代码移动到您自己的专用角色服务中。