Symfony2 实体用户提供者覆盖自定义身份验证提供者

Posted

技术标签:

【中文标题】Symfony2 实体用户提供者覆盖自定义身份验证提供者【英文标题】:Symfony2 entity user provider overrides custom auth provider 【发布时间】:2013-02-09 09:12:15 【问题描述】:

我的 Symfony2 自定义身份验证提供程序现在 appears to be working。

用户提供者

我几乎使用了 FOSUserBundle,但我什至没有我的用户的电子邮件地址,我不需要添加的功能或复杂性。

所以我只是使用entity provider。

我将我的编码器设置为纯文本,因为 API 客户端库会为我处理,但可惜,还有另一个问题:似乎现在正在根据这些用户记录对用户进行身份验证

在我实现实体用户提供程序之前,我的登录表单给了我有效的响应:正确的凭据不会产生错误,错误的凭据会导致我的自定义“不正确的用户/密码错误”。

现在,即使我提供了我认为正确的凭据,我得到的只是错误消息“凭据错误”as if I'm implementing the UserAuthenticationProvider,但据我所知,我不是。我的自定义提供者directly implements the AuthenticationProviderInterface。

所以目前我假设我错误地实现了实体用户提供程序,以至于它以某种方式覆盖了我的自定义身份验证提供程序。同时配置实体用户提供者和自定义身份验证提供者的正确方法是什么?

文件

/app/config/security.yml /src/WordRot/PlayBundle/Security/Authentication/Provider/WordnikProvider.php

security.yml

的相关部分
encoders:
    WordRot\PlayBundle\Entity\User: plaintext

providers:
    wordnik_users:
        entity:  class: WordRotPlayBundle:User, property: username 

firewalls:
    wordnik_secured:
        pattern: ^/play
        logout: ~
        anonymous: ~
        # The next line specifies the custom authentication provider:
        wordnik: true 
        form_login:
            provider: wordnik_users
            login_path:  /login
            check_path:  /play_check
            # on success
            always_use_default_target_path: true
            default_target_path: /play

编辑

This might prove useful。这是 master 分支上的差异...

自定义身份验证提供程序 (WordnikProvider) 仍被执行时 (a473d354) 主分支 (ddcfeae2) 上的最新提交,其中不再执行身份验证提供程序。

编辑 2

我发现了更多断点:

    在登录表单 POST 中,WordnikProvider#supports 使用 UsernamePasswordToken 调用,因此返回 false。 在登录表单 POST 上,构造了 WordnikListener,但它的其他方法(attemptAuthenticationrequiresAuthentication)从未被调用。然而,WordnikFactory#createListener 也从未被调用过!构造监听器真是一个奇迹。 但是在login_check GET,WordnikListener#requiresAuthentication 被调用。

【问题讨论】:

form_login 服务几乎假定您需要密码。所以让自己成为一个编码器,它说没有密码是好的。这应该会让你更进一步。 Cerad,实际上问题似乎来自 UserAuthenticationProvider,因为“凭据错误”。错误提示。尽管对我来说为什么要加载该提供程序是一个完全的谜!我认为编码器不是问题。 AuthProvider 通过用户提供者加载用户,然后通过使用编码器检查密码来验证用户。如果您根本不使用 form_login 服务,请将其取出。但它确实似乎 /play_check 正在由默认身份验证处理程序处理。 啊,这就是问题所在!我希望 play_check 由自定义身份验证提供程序处理!我认为 form_login 只是声明登录块的通用方式,它使用了一个表单,我没有意识到它有影响。如果不是“form_login”,有什么用? return $this->httpUtils->checkRequestPath($request, '/play');在您的身份验证侦听器中将 play 更改为 play_check。这应该会为您开启。 【参考方案1】:

所以我们对此进行了长时间的讨论。基本问题是 form_login 服务干扰了 wodnik 服务。删除了 form_login,事情开始变得更好了。

https://chat.***.com/rooms/25251/discussion-between-montgomery-jean-and-cerad

【讨论】:

这里是完整的成绩单,不长:chat.***.com/transcript/25251

以上是关于Symfony2 实体用户提供者覆盖自定义身份验证提供者的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 不会加载自定义身份验证提供程序,加载 DaoAuthenticationProvider

Symfony2 自定义身份验证:用户登录但未通过身份验证

Symfony2:如何使用非默认实体管理器对用户进行身份验证?

将旧用户迁移到 symfony2

在 Symfony2 中使用自定义身份验证提供程序

我需要在 symfony2 中使用哪个类进行自定义身份验证