简体   繁体   English

请求标头包缺少 Symfony 2 中的授权 header?

[英]Request headers bag is missing Authorization header in Symfony 2?

I'm trying to implement a custom authentication provider in Symfony 2. I'm sending a test request using Fiddler and printing all headers server side;我正在尝试在 Symfony 2 中实现自定义身份验证提供程序。我正在使用 Fiddler 发送测试请求并打印所有标头服务器端; well, Authorization header is missing.好吧,缺少Authorization header。

Am i doing something wrong?难道我做错了什么?

GET /RESTfulBackend/web/index.php HTTP/1.1
Authorization: FID 44CF9590006BF252F707:jZNOcbfWmD/
Host: localhost
User-Agent: Fiddler
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it-it,it;q=0.8,en-us;q=0.5,en;q=0.3

Listener just prints the headers and quits:侦听器只是打印标题并退出:

class HMACListener implements ListenerInterface
{
    private $securityContext;

    private $authenticationManager;

    public function handle(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        print_r($request->headers->all()); 
        die();
     }
}

Response is missing Authorization header:响应缺少Authorization header:

Array
(
    [host] => Array
        (
            [0] => localhost
        )
    [user-agent] => Array
        (
            [0] => Fiddler
        )
    [accept] => Array
        (
            [0] => text/html,application/xhtml+xml,application/xml
        )
    [accept-language] => Array
        (
            [0] => it-it,it;q=0.8,en-us;q=0.5,en;q=0.3
        )
)

You must add this code to your virtualhost 您必须将此代码添加到虚拟主机

    RewriteEngine On
    RewriteCond %{HTTP:Authorization} ^(.*)
    RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

Work in Virtualhost tag, not in Directory tag. 在Virtualhost标记中工作,而不是在Directory标记中。

Akambi's answer didn't work for me, but found this answer in the php website: Akambi的回答对我不起作用,但在php网站上找到了这个答案:

"Workaround for missing Authorization header under CGI/FastCGI Apache: “在CGI / FastCGI Apache下缺少授权标头的解决方法:

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

Now PHP should automatically declare $_SERVER[PHP_AUTH_*] variables if the client sends the Authorization header." 现在,如果客户端发送Authorization标头,PHP应该自动声明$ _SERVER [PHP_AUTH_ *]变量。“

Thanks derkontrollfreak+9hy5l! 谢谢derkontrollfreak + 9hy5l!

The verified solution worked for me at the time to get the Authorization header through. 经过验证的解决方案当时对我有用,可以获得Authorization标题。 However, it generated an empty Authorization header when there was none in the incoming request. 但是,当传入请求中没有时,它会生成一个空的Authorization标头。 This is how I solved it: 这就是我解决它的方式:

RewriteEngine On
RewriteCond %{HTTP:Authorization} .+
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

I had the same problem when writing a public API with custom Authorization header. 在使用自定义Authorization标头编写公共API时,我遇到了同样的问题。 To fix the HeaderBag I used a listener: 为了修复HeaderBag我使用了一个监听器:

namespace My\Project\Frontend\EventListener;

use Symfony\Component\HttpFoundation\HeaderBag;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;

/**
 * Listener for the REQUEST event. Patches the HeaderBag because the
 * "Authorization" header is not included in $_SERVER
 */
class AuthenticationHeaderListener
{
    /**
     * Handles REQUEST event
     *
     * @param GetResponseEvent $event the event
     */
    public function onKernelRequest(GetResponseEvent $event)
    {
        $this->fixAuthHeader($event->getRequest()->headers);
    }
    /**
     * PHP does not include HTTP_AUTHORIZATION in the $_SERVER array, so this header is missing.
     * We retrieve it from apache_request_headers()
     *
     * @param HeaderBag $headers
     */
    protected function fixAuthHeader(HeaderBag $headers)
    {
        if (!$headers->has('Authorization') && function_exists('apache_request_headers')) {
            $all = apache_request_headers();
            if (isset($all['Authorization'])) {
                $headers->set('Authorization', $all['Authorization']);
            }
        }
    }
}

and bound it to kernel.request in the service definition: 并将其绑定到服务定义中的kernel.request

services:
  fix_authentication_header_listener:
    class: My\Project\Frontend\EventListener\AuthenticationHeaderListener
    tags:
      - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 255 }

Authorization header is used for http basic authentication which is discarded by apache if not in valid format. 授权标头用于http基本认证 ,如果不是有效格式,则由apache丢弃。 Try using another name. 尝试使用其他名称。

Another option that worked for Apache 2.4 when other options did not was to set the CGIPassAuth option in the relevant <Directory> context, like this: 当其他选项没有在Apache 2.4中使用的另一个选项是在相关的<Directory>上下文中设置CGIPassAuth选项,如下所示:

CGIPassAuth On

According to the documentation, it is available since Apache 2.4.13. 根据文档,它自Apache 2.4.13起可用。

另一个解决方案是更改PHP处理程序以将PHP作为Apache Module而不是CGI application

We should authorise this header "Authorization" on the server side, 我们应该在服务器端授权这个标题“Authorization”,

it's also simply done with nelmioCorsBundle nelmio_cors: defaults: allow_credentials: false allow_origin: [] allow_headers: [] allow_methods: [] expose_headers: [] max_age: 0 hosts: [] origin_regex: false forced_allow_origin_value: ~ paths: '^/api/': allow_origin: ['*'] allow_headers: ['Authorization'] 它也是用nelmioCorsBundle nelmio_cors: defaults: allow_credentials: false allow_origin: [] allow_headers: [] allow_methods: [] expose_headers: [] max_age: 0 hosts: [] origin_regex: false forced_allow_origin_value: ~ paths: '^/api/': allow_origin: ['*'] allow_headers: ['Authorization']完成的nelmio_cors: defaults: allow_credentials: false allow_origin: [] allow_headers: [] allow_methods: [] expose_headers: [] max_age: 0 hosts: [] origin_regex: false forced_allow_origin_value: ~ paths: '^/api/': allow_origin: ['*'] allow_headers: ['Authorization']

If you're using apache and you already have a header override set in your .htaccess file but you're still getting 401 errors如果您正在使用 apache 并且您已经在 .htaccess 文件中设置了 header 覆盖,但您仍然会收到 401 错误

RewriteCond %{HTTP:Authorization} .+
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0]

Then make sure you enable config overrides in your VirtualHost .然后确保在VirtualHost中启用配置覆盖。 Set the value to All for the AllowOverride parameter in the Directory tagDirectory标记中AllowOverride参数的值设置为All

<VirtualHost *:80>
    ...
    <Directory /var/www/***>
        AllowOverride All
        ...
    </Directory> 

</VirtualHost> 

Don't forget to restart apache after making changes修改后别忘了重启 apache

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM