Passing object to custom voter?

2019-05-29 01:24发布

问题:

I've been reading up about creating custom voters in Symfony 2. According to this page, it is possible to pass an object to the isGranted method of the securitycontext, which I have done in my own controller:

$page = new Page();

if ( ! $securityContext->isGranted('CONTENT_CREATE', $page)) {
    throw new AccessDeniedException('Fail');
}

It looks like the vote method should be accepting it, however, when I call get_class on the $object parameter, instead of getting my Page entity, I get:

Symfony\Component\HttpFoundation\Request

public function vote(TokenInterface $token, $object, array $attributes)
{   
    print_r(get_class($object)); die();
    return VoterInterface::ACCESS_ABSTAIN;
}

My voter is defined as a service in my services.yml file:

content_security.access.my_voter:
        class:      My\Bundle\Security\Authorization\Voter\MyVoter
        arguments:  ["@service_container"]
        public:     false
        tags:
            - { name: security.voter }

Where am I going wrong?

Any advice appreciated.

Thanks

回答1:

Every registered Voters is called when something calls isGranted.

The fact is that the framework itself (or a bundle f.e) calls isGranted on the request.

You have to use supportsClass, supportsAttribute, ... in order to check if the object is the one you're waiting for, and if not return a VoterInterface::ABSTAIN value.

Take a look at existing implementations (in the framework itself (like RoleVoter) or here: https://github.com/KnpLabs/KnpRadBundle/blob/develop/Security/Voter/IsOwnerVoter.php#L35-L45