我有一个Symfony应用程序,由几个保护身份验证器保护。其中两个与此问题相关:一个验证用户检查用户的x509证书,如果失败则显示传统的登录表单。
我也在使用Sonata / FOS用户捆绑包。该bundle检查用户是否具有credentials_expire_at
属性,并在credentials_expire_at <= now()
时抛出CredentialsExpiredException。
问题在于它检查所有身份验证器,但证书有自己的到期时间,与用户的credentials_expire_at
属性无关。
因此我们遇到以下情况:用户访问该站点并提供有效证书。用户的帐户过去设置了credentials_expire_at
,这会导致抛出CredentialsExpiredException。
当发生这种情况时,会调用防护的onAuthenticationFailure()
方法,这使我可以访问异常和用户。所以在这一点上我知道用户并且我知道为什么认证(错误地)失败了。
我的问题是:我如何从这种情况中恢复过来? 无论抛出什么异常,我都希望symfony对用户进行身份验证。
答案 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,但事实证明没有必要。