我正在使用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身份验证器,这样如果第一个成功,则跳过第二个?
答案 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方法中的任何内容。