获得具有特定角色的用户

时间:2014-07-10 11:14:07

标签: symfony doctrine-odm user-roles

我需要获取具有特定角色的所有用户的列表,有什么方法可以轻松完成吗?我现在想出的解决方案是检索所有用户,然后在每个使用被授予的函数(这是硬核)上应用过滤器

PS:我不喜欢使用浏览数据的db请求,如果用户角色等于想要的角色,则返回它,否则不会。这意味着我们不会考虑具有超级角色的用户。

2 个答案:

答案 0 :(得分:2)

由于角色层次结构,我没有看到避免抓取所有用户然后过滤的方法。您可以创建用户角色表并添加所有可能的用户角色,但如果更改了层次结构,则会过时。

但是,一旦您拥有给定用户的所有角色,您就可以测试是否支持特定用户。

有一个角色层次结构对象可以提供帮助。

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

class RoleChecker
{
    protected $roleHeirarchy;

    public function __construct(RoleHierarchy $roleHierarchy)
    {  
        $this->roleHierarchy = $roleHierarchy; // serviceId = security.role_hierarchy
    }
    protected function hasRole($roles,$targetRole)
    {
        $reachableRoles = $this->roleHierarchy->getReachableRoles($roles);
        foreach($reachableRoles as $role)
        {
            if ($role->getRole() == $targetRole) return true;
        }
        return false;
    }
}

# services.yml
# You need to alias the security.role_hierarchy service
cerad_core__role_hierarchy:
    alias: security.role_hierarchy

您需要将一组角色对象传递给hasRole。这基本上与安全上下文对象使用的代码相同。我无法为此找到另一个Symfony服务。

这也是一个名为'%security.role_hierarchy.roles%'的参数值,有时会派上用场。

答案 1 :(得分:0)

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) {
            $roles = $roleHierarchy->getReachableRoleNames($user->getRoles());
            \dump($roles);

            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;
    }
}

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