Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
336 views
in Technique[技术] by (71.8m points)

php - How to use the AccessDecisionManager in Symfony2 for authorization of arbitrary users?

I'd like to be able to verify whether or not attributes (roles) are granted to any arbitrary object implementing UserInterface in Symfony2. Is this possible?

UserInterface->getRoles() is not suitable for my needs because it does not take the role hierarchy into account, and I'd rather not reinvent the wheel in that department, which is why I'd like to use the Access Decision Manager if possible.

Thanks.

In response to Olivier's solution below, here is my experience:

You can use the security.context service with the isGranted method. You can pass a second argument which is your object.

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

Output:

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

boolean true

My role hierarchy:

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: ~

My UserInterface->getRoles() method:

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 must be explicitly assigned, yet isGranted('ROLE_ADMIN', $user) returns TRUE even if the user was just created and has not been assigned any roles other than the default ROLE_USER, as long as the currently logged in user is granted ROLE_ADMIN. This leads me to believe the 2nd argument to isGranted() is just ignored and that the Token provided to AccessDecisionManager->decide() by the SecurityContext is used instead.

If this is a bug I'll submit a report, but maybe I'm still doing something wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need only AccessDecisionManager for this, no need for security context since you don't need authentication.

$user = new CoreModelUser();

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

This will correctly take role hierarchy into account, since RoleHierarchyVoter is registered by default

Update

As noted by @redalaanait, security.access.decision_manager is a private service, so accessing it directly is not a good thing to do. It's better to use service aliasing, which allows you to access private services.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...