在Symfony2中,为什么经过完全身份验证的用户也会匿名进行身份验证?

时间:2014-04-12 13:07:04

标签: php symfony authentication

我正在编写自定义身份验证提供程序,目前正在使用API​​密钥。我现在大部分时间都在工作,但有一件事令我困惑。我已经跟踪了创建此行为的Symfony部分:

供应商/ symfony的/ symfony的/ SRC / Symfony的/分量/安全/核心/授权/选民/ AuthenticatedVoter.php:

/**
 * {@inheritdoc}
 */
public function vote(TokenInterface $token, $object, array $attributes)
{
    $result = VoterInterface::ACCESS_ABSTAIN;
    foreach ($attributes as $attribute) {
        if (!$this->supportsAttribute($attribute)) {
            continue;
        }

        $result = VoterInterface::ACCESS_DENIED;

        if (self::IS_AUTHENTICATED_FULLY === $attribute
            && $this->authenticationTrustResolver->isFullFledged($token)) {
            return VoterInterface::ACCESS_GRANTED;
        }

        if (self::IS_AUTHENTICATED_REMEMBERED === $attribute
            && ($this->authenticationTrustResolver->isRememberMe($token)
                || $this->authenticationTrustResolver->isFullFledged($token))) {
            return VoterInterface::ACCESS_GRANTED;
        }

        if (self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute
            && ($this->authenticationTrustResolver->isAnonymous($token)
                || $this->authenticationTrustResolver->isRememberMe($token)
                || $this->authenticationTrustResolver->isFullFledged($token))) {
            return VoterInterface::ACCESS_GRANTED;
        }
    }

    return $result;
}

为什么在最后一部分是说"如果你完全认证或记住,那么你也是匿名登录的#34;?当然,如果你以匿名方式登录,那么你就没有完全成熟,反之亦然。

我试图解决此问题的原因是因为我有一个防火墙部分API,您可以传递用户名和密码,以便从此创建用于身份验证的令牌。我希望只有在您没有使用API​​密钥进行身份验证的情况下才能访问此区域,即如果用户已退出' (无国籍形式)。

我该如何实现这种行为?

2 个答案:

答案 0 :(得分:0)

我使用此功能告诉有人登录:

public function isAuthenticated()
{
    $securityContext = $this->container->get('security.context');
    return $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED');
}

所以在你的控制器动作中你可以使用

if (isAuthenticated()) {
     throw $this->createNotFoundException('This page does not exist');
}

答案 1 :(得分:0)

最后,我隐约地遵循了这个指南:http://symfony.com/doc/current/cookbook/security/voters.html

我复制了原来的Symfony选民并将其改为:

/**
 * {@inheritdoc}
 */
public function vote(TokenInterface $token, $object, array $attributes)
{
    $result = VoterInterface::ACCESS_ABSTAIN;
    foreach ($attributes as $attribute) {
        if (!$this->supportsAttribute($attribute)) {
            continue;
        }

        $result = VoterInterface::ACCESS_DENIED;

        if (self::IS_AUTHENTICATED_FULLY === $attribute
            && $this->authenticationTrustResolver->isFullFledged($token)) {
            return VoterInterface::ACCESS_GRANTED;
        }

        if (self::IS_AUTHENTICATED_REMEMBERED === $attribute
            && $this->authenticationTrustResolver->isRememberMe($token)) {
            return VoterInterface::ACCESS_GRANTED;
        }

        if (self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute
            && $this->authenticationTrustResolver->isAnonymous($token)) {
            return VoterInterface::ACCESS_GRANTED;
        }
    }

    return $result;
}

然后我添加了服务:

pp_security.apikey_authenticated_voter:
    class: %pp_security.apikey_authenticated_voter.class%
    arguments:
        - "@security.authentication.trust_resolver"
    public:     false
    tags:
        - { name: security.voter }

然后,在我的应用程序security.yml文件中,我添加了以下内容:

security:
    access_decision_manager:
        strategy: unanimous

这意味着,如果单个选民允许访问,而不是Symfony授予访问权限,现在它需要所有选民授予访问权限,然后当然要考虑这个新选民。

现在,用户是三个中的一个,而不再是。