了解 Symfony/FOSUserBundle 身份验证 - 如何处理 fos_user_security_check

Understanding Symfony/FOSUserBundle Authentication - How is fos_user_security_check handled

我想了解在使用 FOSUserBundle 时,Symfony 2.8 是如何处理身份验证(用户 + 密码)的。设置没有问题,一切正常,我只是想了解它是如何工作的。

post 用户名 + 密码 fos_user_security_check 路由 (/login_check) 的登录表单 FOSUserBunde\Resources\config\routing\security.xml:

中定义
<route id="fos_user_security_check" path="/login_check" methods="POST">
    <default key="_controller">FOSUserBundle:Security:check</default>
</route>

因此 FOSUserBundle:Security:check 操作负责处理请求。然而,实现看起来像这样:

public function checkAction() {
    throw new \RuntimeException('You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.');
}

所以我查看了/app/config/security.yml中的防火墙配置:

security:
    ...
    firewalls:
        ...
        main:
            ...

            form_login:
                provider: fos_userbundle
                csrf_provider: security.csrf.token_manager
                login_path: fos_user_security_login
                check_path: fos_user_security_check

这里的check_path也指的是fos_user_security_check... 那么,认证到底是在哪里处理的呢?

身份验证不在 FOSUserBundle 内部处理,它只是提供一些基本参数以及如何从数据库中检索用户的提供程序 (fos_userbundle)。

您需要查看 Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener 以了解有关身份验证失败和成功时发生的情况的一些基础知识。您可以查看那里的 Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListenerattemptAuthentication() 方法,然后沿着那里找到调用 authenticate().

的身份验证管理器服务

您最终会到达 Symfony\Component\Security\Core\Encoder\UserPasswordEncoderisPasswordValid() 函数,它会检查您拥有的任何编码器(可能 Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder),最终调用 PHP 的 password_verify函数。

您之所以以这种方式看到控制器操作,是因为您永远不应该直接调用 login_check。因此,如果您到达那里,则表明配置错误,这就是抛出异常的原因。有关详细信息,请参阅 check_path variable in the documentation, and this Whosebug answer