如何从安全组件覆盖 class?

How to overwrite a class from the Security Component?

我在 API (Silex) 中使用基本身份验证,端点从客户端接收用户+密码,通过基本身份验证验证用户,然后 returns 令牌用于进一步的要求。现在,当我的应用程序进行 AJAX 调用时,如果凭据正确,一切都会顺利进行。如果凭据错误,则 API return 是一个 401 和一组 WWW-Authenticate header。这会导致浏览器自动显示默认的浏览器登录表单。

我不希望发生这种情况。在 Whosebug 中,他们说唯一的两个解决方案是 return 400 而不是 401,或者将 WWW-Authenticate header 更改为 'FormBased'.

在安全组件的 BasicAuthenticationEntryPoint.php 中,statusCode 设置为 401,WWW-Authenticate 设置为 "Basic ..."。

如果我在那里应用更改,它会起作用...但我需要将其作为我的项目的一部分...我应该如何覆盖 Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint.php 以适应它我的需要?知道是否有解决方法吗?我理解这应该是一个很普遍的问题,一般是怎么解决的?

好的,下面是我所做的以防有人疑惑:

首先在我的安全文件夹中,我创建了我自己的 BasicAuthenticationEntryPoint.php

版本
<?php

/*
 * Redefinition of the Symfony's BasicAuthenticationEntryPoint
 */

namespace multikanban\multikanban\Security\Http\EntryPoint;

use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;

/**
 * BasicAuthenticationEntryPoint starts an HTTP Basic authentication.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface
{
    private $realmName;

    public function __construct($realmName)
    {
        $this->realmName = $realmName;
    }

    /**
     * {@inheritdoc}
     */
    public function start(Request $request, AuthenticationException $authException = null)
    {
        $response = new Response();
        $response->headers->set('WWW-Authenticate', 'FormBased');
        $response->setStatusCode(401);

        return $response;
    }
}

注意我做了两件事:

  1. 添加 AuthenticationEntryPointInterface 的使用。
  2. 将 WWW-Authenticate 值更改为 'FormBased',这是对原始文件的实际修改,这样浏览器就不会在服务器 return 出现 401 Unauthorized 时显示默认提示. (您也可以 return 400,但那样您就不会真正遵守标准)

其次,我在我的 Silex 应用程序中定义了服务,如下所示:

    $this['security.entry_point.main.http'] = $this->share(function() {
        return new BasicAuthenticationEntryPoint('main');
    });

'main' 是我的防火墙名称。

显然,我还在Application.php的顶部添加了用法:

use multikanban\multikanban\Security\Http\EntryPoint\BasicAuthenticationEntryPoint;