7

我正在使用安全选民作为 symfony 的 acl 系统的替代方案。

选民示例:

我的选民看起来很像下面的一个。

    class FoobarVoter implements VoterInterface
    {
        public function supportsClass($class)
        {
            return in_array($class, array(
                'Example\FoobarBundle\Entity\Foobar',
            ));
        }

        public function supportsAttribute($attribute)
        {
            return in_array(strtolower($attribute), array('foo', 'bar'));
        }

        public function vote(TokenInterface $token, $object, array $attributes)
        {
            $result = VoterInterface::ACCESS_ABSTAIN

            if (!$this->supportsClass(get_class($object))) {
                return VoterInterface::ACCESS_ABSTAIN;
            }

            foreach ($attributes as $attribute) {
                $attribute = strtolower($attribute);

                // skip not supported attributes
                if (!$this->supportsAttribute($attribute)) {
                    continue;
                }

                [... some logic ...]
            }

            return $result;
        }
    }

问题:

减少对 Voter::vote() 的调用

我的选民被包括在内,并在每次页面加载时被调用。即使他们不支持给定班级的决定。 FoobarVoter::vote()总是被调用。即使FoobarVoter::supportsClass()FoobarVoter::supportsAttribute返回false。因此我需要检查里面的类和属性FoobarVoter::vote()。这是行为标准吗?我怎样才能防止这个不必要的电话。

将选民限制为捆绑

一些选民只需要在特定的捆绑包中。有些只需要决定特定的类。因此,我的申请的所有部分都不需要一些选民。是否可以动态地包括每个捆绑/实体的选民?例如,仅在访问/使用特定捆绑包或特定实体时才将选民纳入决策管理器链?

4

1 回答 1

8

查看 Symfony 的源代码,似乎是因为它AccessDecisionManager使用这些方法(supportsClass 和 seupportsAttribute)来汇总对自身的支持。

这允许您的选民做的是延长申请经理的案件。因此,您不是在详细说明选民的能力,而是在说明整个投票过程。不管那是不是你想要的,都是另一回事……

至于减少不必要的调用,在一般情况下并不是不必要的。该系统是使用以下三种方法之一设计的:

  1. 允许基于( decideAffirmative)。这使用“基于允许”的投票。这意味着如果一个插件说“允许”,那么你就被允许了。

  2. 基于共识( decideConsensus)。这使用基于共识的许可,如果更多的选民同意允许而不是拒绝你被允许......

  3. 基于拒绝( decideUnanimous)。这使用“基于拒绝”的投票。这意味着如果一个插件说“拒绝”,那么你就会被拒绝。否则,您至少需要一笔补助金。

因此,考虑到它们都依赖于明确的拒绝与允许,为每个请求运行所有插件实际上是有意义的。因为即使您不专门支持某个类,您也可能希望允许或拒绝该请求。

简而言之,通过支持属性限制选民并没有什么好处。

于 2013-06-24T15:24:28.663 回答