gpt4 book ai didi

Symfony2 : Call Voter from another Voter

转载 作者:行者123 更新时间:2023-12-04 08:50:37 28 4
gpt4 key购买 nike

我正在使用 Voters 来限制对 REST API 中实体的访问。

第1步

考虑这个限制用户访问博客文章的选民:

class BlogPostVoter extends Voter
{
public function __construct(AccessDecisionManagerInterface $decisionManager)
{
$this->decisionManager = $decisionManager;
}

/**
* Determines if the attribute and subject are supported by this voter.
*
* @param string $attribute An attribute
* @param int $subject The subject to secure, e.g. an object the user wants to access or any other PHP type
*
* @return bool True if the attribute and subject are supported, false otherwise
*/
protected function supports($attribute, $subject)
{
if (!in_array($attribute, $this->allowedAttributes)) {
return false;
}
if (!$subject instanceof BlogPost) {
return false;
}

return true;
}

/**
* Perform a single access check operation on a given attribute, subject and token.
*
* @param string $attribute
* @param mixed $subject
* @param TokenInterface $token
* @return bool
* @throws \Exception
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
return $this->canUserAccess($attribute, $subject, $token);
}

public function canUserAccess($attribute, $subject, TokenInterface $token) {
if ($this->decisionManager->decide($token, array('ROLE_SUPPORT', 'ROLE_ADMIN'))) {
return true;
}

//other logic here omitted ...

return false;
}
}

可以看到有一个公共(public)函数 canUserAccess确定是否允许用户查看 BlogPost。这一切都很好。

第2步

现在我有另一个选民检查其他内容,但也需要检查博客帖子的相同逻辑。我的想法是:
  • 添加新选民
  • 执行一些其他检查
  • 但随后也执行此 BlogPost 检查

  • 所以我想我会像这样将 BlogPostVoter 注入(inject)我的其他选民:
    class SomeOtherVoter extends Voter
    {
    public function __construct(BlogPostVoter $blogPostVoter)
    {
    $this->decisionManager = $decisionManager;
    }

    ...

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
    {
    //other logic

    if ($this->blogPostVoter->canUserAccess($attribute, $subject, $token)) {
    return true;
    }

    return false;
    }
    }

    问题

    当我这样做时,我得到以下错误,同时使用 setter 和构造函数注入(inject):

    检测到服务“security.access.decision_manager”的循环引用,路径:“security.access.decision_manager”

    我看不到 security.access.decision_manager 在哪里应该取决于 Voter 的实现。所以我没有看到循环引用在哪里。

    还有其他方法可以从 VoterB 调用 VoterA 吗?

    最佳答案

    引用 VoterOne来自 VoterTwo您可以注入(inject) AuthorizationCheckerInterface进入 VoterTwo然后调用->isGranted('ONE') .其中 ONE 是 VoterOne 的受支持属性.

    像:

    class VoterTwo extends Voter
    {
    private $authorizationChecker;

    public function __construct(AuthorizationCheckerInterface $authorizationChecker)
    {
    $this->authorizationChecker = $authorizationChecker;
    }

    protected function supports($attribute, $subject)
    {
    return in_array($attribute, ['TWO']);
    }

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
    {
    return $this->authorizationChecker->isGranted('ONE', $subject);
    }
    }

    在此示例中 VoterTwo只是将请求重定向到 VoterOne (或支持属性 ONE 的选民)。然后可以通过附加条件来扩展。

    关于Symfony2 : Call Voter from another Voter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40046998/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com