Request headers bag is missing Authorization header in Symfony 2?

40,529

Solution 1

You must add this code to a virtualhost tag

It will not work if you put it in a Directory tag.

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

Solution 2

Akambi's answer didn't work for me, but found this answer in the php website:

"Workaround for missing Authorization header under CGI/FastCGI Apache:

SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

Now PHP should automatically declare $_SERVER[PHP_AUTH_*] variables if the client sends the Authorization header."

Thanks derkontrollfreak+9hy5l!

Solution 3

The verified solution worked for me at the time to get the Authorization header through. However, it generated an empty Authorization header when there was none in the incoming request. This is how I solved it:

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

Solution 4

I had the same problem when writing a public API with custom Authorization header. To fix the HeaderBag I used a listener:

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:

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

Solution 5

Authorization header is used for http basic authentication which is discarded by apache if not in valid format. Try using another name.

Share:
40,529

Related videos on Youtube

Polmonino
Author by

Polmonino

Updated on July 09, 2022

Comments

  • Polmonino
    Polmonino almost 2 years

    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; well, Authorization header is missing.

    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:

    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
            )
    )
    
  • Polmonino
    Polmonino over 11 years
    Thanks. How for example Amazon S3 can use it? s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.h‌​tml
  • Mun Mun Das
    Mun Mun Das over 11 years
    Well if you see Apache implementation it expects the request token to be base_64 encoded string and on server side it base64_decodes the string and set PHP_AUTH_USER and PHP_AUTH_PW server variable. As you see the implementation is server specific. So Amazon S3 web servers have implemented the scheme differently.
  • Polmonino
    Polmonino over 11 years
    What you would suggest then? using apache_request_headers() (apache specific) or using a custom header?
  • Mun Mun Das
    Mun Mun Das over 11 years
    You can make an apache module to make your authentication scheme compliance with http basic authentication. For example check this module. Or you can use custom header e.g X-FID-Authorization.
  • chacham15
    chacham15 over 10 years
    this worked like a charm for me, can you just explain what it does?
  • webaba
    webaba almost 10 years
    Thank you that works, however there might be a problem. It looks like an authorization header field gets created even if it's not present in the incoming request. This should not be the behavior
  • Poiple Shadow
    Poiple Shadow over 9 years
    AFAIK Apache will accept any format Authorization header. It is PHP which discards anything else than valid Basic or Digest header.
  • mezod
    mezod over 9 years
    that is right, it is creating an authorization header field even when none in the request, any ideas on the matter?
  • mezod
    mezod over 9 years
    I added the following to the .htaccess: RewriteCond %{HTTP:Authorization} .+
  • Loïc Faugeron
    Loïc Faugeron about 9 years
    Note that you need to intall PHP's Apache extension, in order to have the apache_request_headers function available.
  • Jorj
    Jorj over 8 years
    Not a good solution though because it will be slower as module than as CGI. Also there are problems with the rights in cache and logs folder during the development.
  • Wilt
    Wilt over 8 years
    @Jorj "problems" can you be more specific? I bet it is just a matter of configuration. It is a working solution. Never said it was the "best". That is a matter of opinion..
  • Jorj
    Jorj over 8 years
    Sure, here is what happens: as a developer on a unix box you would create files under your user, right ? Then you would launch some commands from your console which would create files in cache and logs folder. If PHP is configured as module in Apache it will run with Apache's user, that is "www" or "nobody" or something similar. As a result it will try to overwrite the files created by you in cache and logs folders and it will throw errors because they belongs to another owner. Of course, there are workarounds to this too, but still is an additional headache.
  • Wilt
    Wilt over 8 years
    This is exactly the same as the answer here.
  • Mohamed Nagy
    Mohamed Nagy about 8 years
    this answer is working fine with http request, but it is not working with https requests
  • anna
    anna over 7 years
    Thank you. Do you know why the header is not sent?
  • Artur Cichosz
    Artur Cichosz over 7 years
    In my case it only works if the URL does not contain the bootstrap-script e.g. server.tld/some/path. It does not work for the following URL server.tld/app_dev.php/some/path
  • Artur Cichosz
    Artur Cichosz over 7 years
    It seems that we can use the header name ''Php-Auth-Digest" as an alternative to "Authorization". see Symfony\Component\HttpFoundation\ServerBag::getHeaders()
  • Twisty
    Twisty over 7 years
    Applied this fix but it's still not responding to 401 header in my script.
  • tom10271
    tom10271 about 7 years
    This is the only solution works, RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]'s one is not working
  • G_Gus
    G_Gus almost 7 years
    This is what worked for me. Otherwise the Authorization header was simply missing from both getallheaders and $_SERVER
  • Vahid Amiri
    Vahid Amiri over 6 years
    Worked when I added it to .htaccess
  • Zorox
    Zorox almost 5 years
    Worked in .htaccess too
  • Omar Tariq
    Omar Tariq over 4 years
    This worked for me by adding it in the VirtualHost config file. It should work fine in .htaccess too, just make sure there is no proxies, container etc in between before the request reaches your app.
  • Cristian Budzicz
    Cristian Budzicz almost 4 years
    where is the virtualhost tag? in my .htaccess i dont see it
  • Oleg
    Oleg almost 2 years
    Using symfony 5.4, - GetResponseEvent was renamed to RequestEvent.