我需要获取具有特定角色的所有用户的列表,有什么方法可以轻松完成吗?我现在想出的解决方案是检索所有用户,然后在每个使用被授予的函数(这是硬核)上应用过滤器
PS:我不喜欢使用浏览数据的db请求,如果用户角色等于想要的角色,则返回它,否则不会。这意味着我们不会考虑具有超级角色的用户。
答案 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;
}
}
注意:为了简化起见,我将所有内容都放在了控制器中,但是我当然建议将角色管理代码移到单独的服务中。