如何从安全组件覆盖 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;
}
}
注意我做了两件事:
- 添加 AuthenticationEntryPointInterface 的使用。
- 将 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;
我在 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;
}
}
注意我做了两件事:
- 添加 AuthenticationEntryPointInterface 的使用。
- 将 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;