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

Posted

技术标签:

【中文标题】如何在 Symfony 中检索完整的角色层次结构【英文标题】:How to retrieve full role hierarchy in Symfony 【发布时间】:2012-01-19 14:50:53 【问题描述】:

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

role_hierarchy:
ROLE_USER: [ROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT]

使用getRoles() 只返回ROLE_USER,我怎么能在我的代码中知道ROLE_USER 是用ROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT 创建的?

感谢您的帮助。

【问题讨论】:

你需要它做什么? 我的“用户”(ROLE_USER)有一组默认的角色,我想允许管理员只给他特定的角色,例如只有 ROLE_ACCESS_DATA。我想通过一个显示所有现有角色的界面来做到这一点。 【参考方案1】:

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

$container->getParameter('security.role_hierarchy.roles')

【讨论】:

【参考方案2】:

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

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

public function __construct(RoleHierarchyInterface $roleHierarchy)

    $this->roleHierarchy = $roleHierarchy;

注意:这也允许您在 RoleHierarchy 对象上调用 getReachableRoles(),这在您的情况下可能很有用:

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

$this->roleHierarchy->getReachableRoles([new Role('ROLE_USER')])

从 Symfony4 开始,您必须在 config/services.yml 中添加 security.role_hierarchy 的别名,方法是添加以下行:

services:
    # creating alias for RoleHierarchyInterface
    Symfony\Component\Security\Core\Role\RoleHierarchyInterface: '@security.role_hierarchy'

【讨论】:

使用 Symfony 3.4 - 我也必须使用别名。 别名是在 Symfony 4.1 中添加的,不再需要手动添加:github.com/symfony/symfony/pull/26639 symfony 5 怎么样?【参考方案3】:

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;
    

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

【讨论】:

$roles = $roleHierarchy->getReachableRoleNames($user->getRoles()); 未在 usersIndex() 方法中使用 - 是被遗忘的语句吗? @long 谢谢,不知道为什么会出现在这里。固定:) 如何在控制器中不提及而用扩展逻辑覆盖RoleHierarchy接口?【参考方案4】:

为了正确表示您的角色,您需要递归。角色可以扩展其他角色。

这里是一个例子:https://***.com/a/36900807/3635680

【讨论】:

请在您的回答中引用相关文字。不建议发布仅链接的答案(即使链接导致 Stack Overflow)。【参考方案5】:

security.role_hierarchy.roles 是security.yml中定义的所有安全角色

如果您想包含 Sonata 管理员角色,您可以检查 SonataUserBundle\Form\Type\SecurityRolesType 中的代码

foreach ($this->pool->getAdminServiceIds() as $id) 
            try 
                $admin = $this->pool->getInstance($id);
             catch (\Exception $e) 
                continue;
            

            $securityHandler = $admin->getSecurityHandler();

            foreach ($securityHandler->buildSecurityInformation($admin) as $role => $acls) 
                $roles[$role] = $role;
            
        

【讨论】:

以上是关于如何在 Symfony 中检索完整的角色层次结构的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 的角色层次结构

如何在 Symfony2 中创建和注册新角色

如何在 Symfony4 结构的参数文件中检索我的环境变量?

Symfony2\Doctrine - 检索用户角色

如何在雪花中获取用户角色层次结构?

如何在 Strapi 中配置角色层次结构(权限继承)?