如何使用Symfony2中的AccessDecisionManager来授权任意用户?

2022-08-31 00:55:59

我希望能够验证属性(角色)是否被授予在Symfony2中实现的任何任意对象。这可能吗?UserInterface

UserInterface->getRoles()不适合我的需求,因为它没有考虑角色层次结构,而且我宁愿不要在该部门重新发明轮子,这就是为什么我想在可能的情况下使用访问决策管理器。

谢谢。

为了回应Olivier在下面的解决方案,这是我的经验:

可以将 security.context 服务与 isGranted 方法一起使用。您可以传递第二个参数,该参数是您的对象。

$user = new Core\Model\User();
var_dump($user->getRoles(), $this->get('security.context')->isGranted('ROLE_ADMIN', $user));

输出:

array (size=1)
  0 => string 'ROLE_USER' (length=9)

boolean true

我的角色层次结构:

role_hierarchy:
    ROLE_USER:          ~
    ROLE_VERIFIED_USER: [ROLE_USER]
    ROLE_ADMIN:         [ROLE_VERIFIED_USER]
    ROLE_SUPERADMIN:    [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
    ROLE_ALLOWED_TO_SWITCH: ~

我的方法:UserInterface->getRoles()

public function getRoles()
{
    $roles = [$this->isVerified() ? 'ROLE_VERIFIED_USER' : 'ROLE_USER'];

    /**
     * @var UserSecurityRole $userSecurityRole
     */
    foreach ($this->getUserSecurityRoles() as $userSecurityRole) {
        $roles[] = $userSecurityRole->getRole();
    }

    return $roles;
}

ROLE_ADMIN必须显式分配,但即使用户刚刚创建并且未分配除默认角色之外的任何角色,只要当前登录的用户被授予ROLE_ADMIN,也会返回。这使我相信第二个参数被忽略了,并且使用了 由 提供给 的参数。isGranted('ROLE_ADMIN', $user)TRUEROLE_USERisGranted()TokenAccessDecisionManager->decide()SecurityContext

如果这是一个错误,我会提交一份报告,但也许我仍然做错了什么?


答案 1

您只需要这样做,不需要安全上下文,因为您不需要身份验证。AccessDecisionManager

$user = new Core\Model\User();

$token = new UsernamePasswordToken($user, 'none', 'none', $user->getRoles());
$isGranted = $this->get('security.access.decision_manager')
    ->decide($token, array('ROLE_ADMIN'));

这将正确地考虑角色层次结构,因为默认情况下已注册RoleHierarchyVoter

更新

正如@redalaanait所指出的,security.access.decision_manager是一项私人服务,因此直接访问它不是一件好事。最好使用服务别名,它允许您访问私有服务。


答案 2

security.context自 2.6 起已弃用。

用:AuthorizationChecker

$token = new UsernamePasswordToken(
     $user,
     null,
     'secured_area',
     $user->getRoles()
);
$tokenStorage = $this->container->get('security.token_storage');
$tokenStorage->setToken($token);
$authorizationChecker = new AuthorizationChecker(
     $tokenStorage,
     $this->container->get('security.authentication.manager'),
     $this->container->get('security.access.decision_manager')
);
if (!$authorizationChecker->isGranted('ROLE_ADMIN')) {
    throw new AccessDeniedException();
}

推荐