Symfony guard从身份验证失败中恢复

时间:2017-11-02 12:46:27

标签: symfony security

我有一个Symfony应用程序,由几个保护身份验证器保护。其中两个与此问题相关:一个验证用户检查用户的x509证书,如果失败则显示传统的登录表单。

我也在使用Sonata / FOS用户捆绑包。该bundle检查用户是否具有credentials_expire_at属性,并在credentials_expire_at <= now()时抛出CredentialsExpiredException。

问题在于它检查所有身份验证器,但证书有自己的到期时间,与用户的credentials_expire_at属性无关。

因此我们遇到以下情况:用户访问该站点并提供有效证书。用户的帐户过去设置了credentials_expire_at,这会导致抛出CredentialsExpiredException。

当发生这种情况时,会调用防护的onAuthenticationFailure()方法,这使我可以访问异常和用户。所以在这一点上我知道用户并且我知道为什么认证(错误地)失败了。

我的问题是:我如何从这种情况中恢复过来? 无论抛出什么异常,我都希望symfony对用户进行身份验证。

1 个答案:

答案 0 :(得分:0)

事实证明这很简单。

UserChecker服务(security.user_checker.main)抛出异常。

我基本上扩展了Symfony提供的UserChecker并覆盖了checkPostAuth方法:

public function checkPostAuth(UserInterface $user)
{
    try {
        parent::checkPostAuth($user);
    } catch (CredentialsExpiredException $exception) {
        if (!$user->isCertificateLogin()) {
            throw $exception;
        }
    }
}

因此,这会捕获CredentialsExpiredException,并在用户未通过证书身份验证器登录时重新抛出它。

最后一步是在我的services.yml注册服务:

security.user_checker.main:
    class: AppBundle\Security\UserChecker

我预计必须为它添加一个CompilerPass,但事实证明没有必要。