security.yml access_control匹配查询参数

时间:2014-03-19 20:51:00

标签: symfony symfony-2.4

我希望保护所有应用了?preview=true查询字符串的网址。 遗憾的是,以下情况不起作用。我想请求匹配器只查看pathInfo。

# app/config/security.yml
access_control:
    - { path: (?|&)preview=true, role: ROLE_ADMIN }

任何提示都非常感谢。

2 个答案:

答案 0 :(得分:0)

我很确定访问控制只查看分层部分而不是查询字符串。这是因为查询参数不是为了确定内容,而是为了对内容进行过滤。您可能需要重新设计URL结构以匹配这些。

答案 1 :(得分:0)

自己解决了。正如@Chausser所说,在security.yml中无法通过查询参数进行访问控制,所以我为此创建了一个选民。

// src/Your/Bundle/Security/Voter/PreviewAccessVoter.php
namespace Your\Bundle\Security\Voter;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;


/**
 * voter that denies access if user has not the required role
 * to access urls with preview query param set true
 */
class PreviewAccessVoter implements VoterInterface
{

    protected $requestStack;
    protected $requiredRole;


    public function __construct(RequestStack $requestStack, $requiredRole)
    {
        $this->requestStack  = $requestStack;
        $this->requiredRole = $requiredRole;
    }


    public function supportsAttribute($attribute)
    {
        return true;
    }


    public function supportsClass($class)
    {
        return true;
    }


    public function vote(TokenInterface $token, $object, array $attributes)
    {
        if(filter_var($this->requestStack->getCurrentRequest()->query->get('preview'), FILTER_VALIDATE_BOOLEAN))
        {
            foreach($token->getRoles() as $role) {
                if($this->requiredRole === $role->getRole()) {
                    return VoterInterface::ACCESS_GRANTED;
                }
            }
            return VoterInterface::ACCESS_DENIED;
        }

        return VoterInterface::ACCESS_ABSTAIN;
    }
}

将选民添加为(隐藏)服务

# src/Your/Bundle/Resources/config/services.yml
# preview voter that denies access for users without the required role
security.access.preview.voter:
    class:      Your\BundleBundle\Security\Voter\PreviewAccessVoter
    arguments:  [ @request_stack , ROLE_ADMIN ]
    tags:       [ { name: security.voter } ]
    public:     false

更改访问决策策略

# app/config/security.yml
access_decision_manager:
    strategy: unanimous # can be: affirmative, unanimous or consensus


见:http://symfony.com/doc/current/cookbook/security/voters.html作为参考
https://github.com/symfony/Security/blob/master/Core/Authorization/Voter/RoleVoter.php也可能有帮助