OR关系中的多个Guard身份验证器

时间:2016-01-04 20:35:15

标签: symfony authentication

我正在使用Symfony 2.8的新Guard身份验证系统,我想允许用户使用两种方法中的任何一种进行身份验证。所以我已经为两者实现了Guard身份验证器,并像这样配置它们:

security:
  firewalls:
    my_firewall:
      pattern: ^/some-pattern
      guard:
        authenticators:
          - my_first_auth
          - my_second_auth
        entry_point: my_first_auth

问题是他们运行,所以如果用户在第一次成功但在第二次成功时失败,他会得到一个禁止的响应。在这种情况下,我希望他能够成功。

有没有办法在OR关系中配置多个Guard身份验证器,这样如果第一个成功,则跳过第二个?

3 个答案:

答案 0 :(得分:5)

最后,我自己手动实现了一个解决方案,利用了如果getCredentials()返回null,则跳过身份验证器的事实。两个身份验证器的代码都如下所示:

class MyAuthenticator extends AbstractGuardAuthenticator {
    private $tokenStorage;

    public function __construct(TokenStorageInterface $tokenStorage) {
        $this->tokenStorage = $tokenStorage;
    }

    public function getCredentials(Request $request) {
        if ($this->isAlreadyAuthenticated()) {
            return null; // Skip this authenticator
        }
        // Get the credentials and continue with this authenticator
    }

    protected function isAlreadyAuthenticated() {
        $token = $this->tokenStorage->getToken();
        return $token && $token->isAuthenticated();
    }

答案 1 :(得分:0)

根据您的配置,您无法执行此操作。多个保护身份验证器的行为正是您所描述的行为:它们都运行。

作为替代方案,我建议使用Security Voters,我认为你会以这种方式获得更多运气,虽然我不知道实现的确切程度如何。

答案 2 :(得分:-1)

你的例子很肤浅,你应该描述更好的用例。如果你想要简单的回答,那就没有OR。

但是如果你的getCredentials方法返回null,则跳过see this,所以第二次应该运行(没有测试)。

其他解决方案如何做你想做的事情就是拥有一个Authenticator并解析来自请求或cookie的凭据或getCredentials方法中的任何内容。