【问题标题】:How to overwrite a class from the Security Component?如何覆盖安全组件中的类?
【发布时间】:2015-02-03 00:25:39
【问题描述】:

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

我不希望这种情况发生。在 StackOverflow 中,他们说唯一的两种解决方案是返回 400 而不是 401,或者将 WWW-Authenticate 标头更改为“FormBased”之类的内容。

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

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

【问题讨论】:

  • 所以你不想使用来自网络服务器的 http auth 而是你自己的登录系统?
  • 我确实想在网络服务器中使用基本身份验证。但仅针对我返回令牌的请求。给定凭据,我正在对用户进行身份验证并返回令牌,这样我就不需要在后端保留状态,但 js 应用程序只需要在以后的每个请求中添加令牌。
  • 好吧,听起来你只需创建自己的provider,然后使用它来设置series of custom classes,这将允许你定义自己的入口点类。我不确定编排是如何工作的,所以我目前无法向您提供详细信息,我只能说这是可能的,并为您指明这个大方向。
  • 谢谢,这很有帮助!

标签: php symfony authentication silex


【解决方案1】:

好的,如果有人想知道,这就是我所做的:

首先在我的安全文件夹中,我创建了自己的 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”,这是对原始文件的实际修改,这样当服务器返回 401 Unauthorized 时,浏览器不会显示默认提示。 (您也可以返回 400,但您不会真正遵守标准)

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

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

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

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

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

【讨论】:

  • 看起来这是我需要的,但我不知道在哪里放置 "$this['security.entry_point.main.http'] = $this->share..." 行代码 ?应用内核.php ?对不起,如果我错过了什么。我唯一拥有的 Application.php 是 vendor/symfony 中的那个,我相信您永远不想更改此文件...
  • 以防万一有人正在寻找这个问题的详细答案:github.com/symfony/symfony/issues/10035 TL;DR:您可以通过防火墙下的 entry_point 配置设置自己的“入口点”来做到这一点:@ 987654322@。只需创建一个实现 AuthenticationEntryPointInterface 的类,将其注册为服务,并将 id 放在那里
猜你喜欢
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 2020-09-06
  • 2019-01-14
  • 2014-06-03
  • 2019-11-30
  • 2020-10-11
  • 2017-12-07
相关资源
最近更新 更多