【问题标题】:How can I configure basic authentication in Symfony to allow an empty password?如何在 Symfony 中配置基本身份验证以允许空密码?
【发布时间】:2019-12-21 19:04:40
【问题描述】:

我正在 PHP / Symfony 4.0 中编写一个 REST API 端点,我想使用基本身份验证,并使用密码为空的内存用户。当我尝试使用这些凭据调用端点时,我收到一个 BadCredentialsException 说“提供的密码不能为空”。

DaoAuthenticationProvider 似乎正在引发异常。

如何在 Symfony 中配置基本身份验证以允许空密码?

上下文:我正在为一个简单的端点设置基本身份验证,该端点将用作集成字段的 Prismic 自定义 API(请参阅https://user-guides.prismic.io/en/articles/1401183-connect-to-a-custom-api)。 Prismic 对此支持基本身份验证,您可以在其中输入将用作用户名的密钥,而密码将留空。

我正在使用 PHP / Symfony 4.0 编写此内容,并且我一直在关注 https://symfony.com/doc/current/security.html 的文档。

我的 config/packages/security.yaml 文件是:

security:
    firewalls:
        secured_area:
            pattern: ^/api/my-endpoint
            http_basic: ~
            security: true
        main:
            security: false

    providers:
        in_memory:
            memory:
                users:
                    test:
                        password: ''

    encoders:
        Symfony\Component\Security\Core\User\User: plaintext

我的日志中的完整错误消息是:

用户的基本身份验证失败。 {"username":"test","exception":"[object] (Symfony\Component\Security\Core\Exception\BadCredentialsException(code: 0): Bad credentials. at my-project\vendor\symfony\security\Core \Authentication\Provider\UserAuthenticationProvider.php:84, Symfony\Component\Security\Core\Exception\BadCredentialsException(code: 0): 提供的密码不能为空。在 my-project\vendor\symfony\security\Core\Authentication\ Provider\DaoAuthenticationProvider.php:54)"} []

【问题讨论】:

  • 只是为了澄清:您使用哪个 Symfony 版本?您是否尝试将其更新到 4.3 的最新版本?
  • Symfony 4.0。我尝试更新到 Symfony 4.3,但我得到了同样的异常。

标签: php symfony symfony4 basic-authentication symfony-security


【解决方案1】:

如果您真的不想进行适当的身份验证,然后经过身份验证的用户将使用 API 密钥调用远程端点,并以更“肮脏”的方式解决任务,那么您可以做什么是:

  • 创建您自己的AuthenticationProvider,它将扩展原来的https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php

  • 覆盖checkAuthentication 方法,您将拥有与原始代码相同的代码,但不检查空密码(可能还有该 else 语句中相关的所有其他内容)

  • 覆盖service definition 以指向您自己创建的AuthenticationProvider

     <service id="security.authentication.provider.dao" class="XXXX Your class here XXXX" abstract="true">
         <argument /> <!-- User Provider -->
         <argument /> <!-- User Checker -->
         <argument /> <!-- Provider-shared Key -->
         <argument type="service" id="security.encoder_factory" />
         <argument>%security.authentication.hide_user_not_found%</argument>
     </service>
    
  • 清空缓存试试

覆盖服务:

services:
  ...
  ...
  security.authentication.provider.dao:
    alias: MyProject\Service\Security\OverriddenDaoAuthenticationProvider
    public: true

在你的OverriddenDaoAuthenticationProvider类中记得调用原来的构造函数来传递参数:

public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, EncoderFactoryInterface $encoderFactory, bool $hideUserNotFoundExceptions = true)
{
    parent::__construct($userProvider, $userChecker, $providerKey, $encoderFactory, $hideUserNotFoundExceptions);
}

【讨论】:

  • 谢谢,这看起来很有希望。我创建了自己的 AuthenticationProvider。如何覆盖服务定义?我有一个services.yaml 文件,它处理这个项目中类的依赖注入。我可以用那个吗?
  • @dans 在 Symfony 4 中,服务大多是自动装配的,所以下一个链接明确展示了我们在自动装配之前的生活方式。 Link to version 3.1 。在 Symfony 4 中,您仍然可以使用链接中描述的方法来显式定义(重新定义)服务。重要的是,您使用服务别名并将其设置为您可以在上面的 xml 定义中看到的服务 ID,因为在 Symfony4 中我们可以定义有别名和没有别名的服务。
  • 当你定义一个别名 = 'security.authentication.provider.dao' 的服务并且你上课时,它会覆盖原来的
  • 非常感谢您对此的帮助。我正在尝试按照您的建议使用别名重新定义服务,但我不确定我是否有正确的语法。在我的services.yaml 文件中,我现在有:MyProject\Service\Security\OverriddenDaoAuthenticationProvider: alias: security.authentication.provider.dao public: true 但是,我似乎仍然没有说服 Symfony 使用我的 OverriddenDaoAuthenticationProvider,因为我仍然遇到原始 DaoAuthenticationProvider 引发的相同错误。你能看看我的语法有没有错误?
  • 我觉得这一定越来越近了。我尝试了您建议的语法,现在我得到了一个 Symfony OutOfBoundsException,上面写着“服务“security.authentication.provider.dao.secured_area”:如果尚未配置参数,则无法替换参数。”我是否需要更改我的 security.yaml 文件中的其他内容?
猜你喜欢
  • 2016-07-05
  • 2016-09-06
  • 2013-05-31
  • 2021-10-18
  • 2017-09-01
  • 2014-04-04
  • 1970-01-01
  • 2023-03-05
  • 2019-07-22
相关资源
最近更新 更多