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

时间:2012-01-19 14:50:53

标签: symfony

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

role_hierarchy:
ROLE_USER: [ROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT]

使用getRoles()只返回ROLE_USER,我如何在代码中知道ROLE_USERROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT的?{/ p>

感谢您的帮助。

5 个答案:

答案 0 :(得分:38)

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

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

答案 1 :(得分:10)

启用自动布线后,您还可以直接注入填充了全局角色层次结构的RoleHierarchy对象。 只需使用依赖注入

在控制器或服务中注入RoleHierarchyInterface
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;

public function __construct(RoleHierarchyInterface $roleHierarchy)
{
    $this->roleHierarchy = $roleHierarchy;
}

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

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

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

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

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

答案 2 :(得分: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;
    }
}

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

答案 3 :(得分:0)

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

以下是一个示例:https://stackoverflow.com/a/36900807/3635680

答案 4 :(得分:0)

security.role_hierarchy.roles是security.yml

中定义的所有安全角色

如果要包含Sonata Admin角色,可以在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;
            }
        }