Just check: abstain from voting in Symfony AbstractVoter isGranted

I am working on a Symfony2 application in which we want to introduce Security Advocates . The DX initiative (jay!) Brought us a simpler version of this mechanism, so I would like to use this. The only thing that bothers me a bit about using \Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter is the fact that I can no longer abstain from voting just by using the isGranted abstract method. I would like to change this for our application, but would really appreciate your opinion on this issue from a security point of view.

To be clear, in our application we will use the unanimous access manager solution unanimous - in short: you need at least one ACCESS_GRANTED and no ACCESS_DENIED - because later we will want to enter voters to ban IP addresses or other frauds.

As shown in the corresponding code snippet below, once the AbstractVoter implementation supports the attribute, the default vote will be Denied .

 public function vote(TokenInterface $token, $object, array $attributes) { if (!$object || !$this->supportsClass(get_class($object))) { return self::ACCESS_ABSTAIN; } // abstain vote by default in case none of the attributes are supported $vote = self::ACCESS_ABSTAIN; foreach ($attributes as $attribute) { if (!$this->supportsAttribute($attribute)) { continue; } // as soon as at least one attribute is supported, default is to deny access $vote = self::ACCESS_DENIED; if ($this->isGranted($attribute, $object, $token->getUser())) { // grant access as soon as at least one voter returns a positive response return self::ACCESS_GRANTED; } } return $vote; } 

What I would like to do is override this with the code below

 public function vote(TokenInterface $token, $object, array $attributes) { if (!$object || !$this->supportsClass(get_class($object))) { return self::ACCESS_ABSTAIN; } $vote = self::ACCESS_ABSTAIN; foreach ($attributes as $attribute) { if (!$this->supportsAttribute($attribute)) { continue; } // This is where we differ from SymfonyAbstractVoter. Only if there is an outspoken yes or no, a vote is cast // When returning null, it will still abstain $grant = $this->isGranted($attribute, $object, $token->getUser()); if ($grant === true) { return self::ACCESS_GRANTED; } if($grant === false) { return self::ACCESS_DENIED; } } return $vote; } 

What do you think? Is it safe to return ACCESS_ABSTAIN when null returns the isGranted form, and only cast ACCESS_GRANTED or ACCESS_DENIED if the voter returns true or false?


Why do I even want to do this? Still use AbstractVoter (because, yes, I'm a lazy developer), but share my concerns.

Let's say I make one voter per post, PostVoter , which allows me to edit my own posts. Then it will produce a ACCESS_GRANTED . But as long as I don't own this message, this voter really doesn't care: he should just draw ACCESS_ABSTAIN . Later it can work in AdminVoter , which will still distinguish ACCESS_GRANTED . However, when using the unanimous access decision manager strategy, if this PostVoter has already selected ACCESS_DENIED , it will never get into any other voters.

Now I can’t do this ACCESS_ABSTAIN in AbstractVoter without overriding the vote method, and the whole point of simpler voters in my mind was, in simple terms, to make it easier :)

+6
source share
1 answer

The AbstractVoter class is a simple boot implementation for most use cases, and it emulates how internal voters behave , so as soon as you feel your solution is different from the base, you should feel free to override it with your own methods.

+1
source

Source: https://habr.com/ru/post/981753/


All Articles