48

Summary: Apache 2.4's mod_proxy does not seem to be passing the Authorization headers to PHP-FPM. Is there any way to fix this?

Long version: I am running a server with Apache 2.4 and PHP-FPM. I am using APC for both opcode caching and user caching. As recommended by the Internet, I am using Apache 2.4's mod_proxy_fcgi to proxy the requests to FPM, like this:

ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/foo/bar/$1

The setup works fine, except one thing: APC's bundled apc.php, used to monitor the status of APC does not allow me to log in (required for looking at user cache entries). When I click "User cache entries" to see the user cache, it asks me to log in, clicking on the login button displays the usual HTTP login form, but entering the correct login and password yields no success. This function is working perfectly when running with mod_php instead of mod_proxy + php-fpm.

After some googling I found that other people had the same issue and figured out that it was because Apache was not passing the Authorization HTTP headers to the external FastCgi process. Unfortunately I only found a fix for mod_fastcgi, which looked like this:

FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization

Is there an equivalent setting or some workaround which would also work with mod_proxy_fcgi?

1
  • Thanks for the "-pass-header Authorization" snippet! Helped me out w/ fastcgi.
    – Sergio
    Commented Nov 6, 2013 at 21:44

6 Answers 6

108

Various Apache modules will strip the Authorization header, usually for "security reasons". They all have different obscure settings you can tweak to overrule this behaviour, but you'll need to determine exactly which module is to blame.

You can work around this issue by passing the header directly to PHP via the env:

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

See also Zend Server Windows - Authorization header is not passed to PHP script

In some scenarios, even this won't work directly and you must also change your PHP code to access $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] rather than $_SERVER['HTTP_AUTHORIZATION']. See When setting environment variables in Apache RewriteRule directives, what causes the variable name to be prefixed with "REDIRECT_"?

5
  • 7
    This might help PHP 5.5+ and Apache 2.4 users. After adding SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 to the .htaccess you must use $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] variable instead of $_SERVER['HTTP_AUTHENTICATION'].
    – Rahi
    Commented Feb 16, 2015 at 17:11
  • where u add this=¿? Commented Aug 23, 2016 at 20:24
  • 3
    To the apache configuration, in .htaccess or /etc/httpd/conf
    – Rich
    Commented Aug 24, 2016 at 14:31
  • Is stripping out Auth header for "security reasons" somehow redundant, misguided? Your mod to .htaccess worked for me, but am wondering what side effects there might be from blanket passing the Auth header.
    – Bytech
    Commented Jul 5, 2019 at 12:15
  • @Bytech: I believe it is almost always pointless. For example mod_fcgid witholds this header and its docs say "Only pass these request headers if absolutely required." ( httpd.apache.org/mod_fcgid/mod/mod_fcgid.html#fcgidpassheader ), but they do not give any justification for that. I couldn't see anything in the mod_fcgid history which further explains this. Maybe open a new question "why does mod_fcgid withold the Authorization header" and link it here? I suppose that it might be a good idea if the web server didn't trust its hosted apps???
    – Rich
    Commented Jul 6, 2019 at 6:31
61

This took me a long time to crack, since it's not documented under mod_proxy or mod_proxy_fcgi.

Add the following directive to your apache conf or .htaccess:

CGIPassAuth on

See here for details.

3
  • 4
    Note this only works on Apache 2.4.13 or later, i.e. not on any version of Ubuntu as of 15.10. Commented Dec 31, 2015 at 0:51
  • 1
    This solution makes more sense as it is closer to the proxy setting that disabled passing auth headers, i.e. : <FilesMatch \.php$> SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch> CGIPassAuth on
    – Julz
    Commented Oct 12, 2017 at 16:50
  • 2
    Thanks for this, definitely the best answer. Note this only works if you're using SetHandler, rather than the older ProxyPassMatch method.
    – Gannet
    Commented Feb 21, 2020 at 21:21
3

Recently I haven'd problem with this arch.

In my environement, the proxy to php-fpm was configured as follow:

<IfModule proxy_module>
    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache2/htdocs/$1
    ProxyTimeout 1800
</IfModule>

I fixed the issue set up the SetEnvIf directive as follow:

<IfModule proxy_module>
    SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache2/htdocs/$1
    ProxyTimeout 1800
</IfModule>
0
1

I've added the

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

inside the VirtualHost node

<VirtualHost *:80>
    SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
0

This is what I needed to add to get it to work for a particular host. For whatever reason, the key was then REDIRECT_HTTP_AUTHORIZATION instead of HTTP_AUTHORIZATION:

RewriteRule . /index.php [L,E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

$token = $_SERVER['HTTP_AUTHORIZATION'] ?? ($_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? null);
-2

I didn't find any similar settings with mod_proxy_fcgi BUT it just works for me by default. It asks for user authorization (.htaccess as usual) and the php gets it, and works like with mod_php or fastcgi and pass-header. I don't know if I was helpful...

EDIT: it only works on teszt.com/ when using the DirectoryIndex... If i pass the php file name (even if the index.php!) it just doesn't work, don't pass the auth to the php. This is a blocker for me, but I don't want to downgrade to apache 2.2 (and mod_fastgi) so I migrate to nginx (on this machine too).

Not the answer you're looking for? Browse other questions tagged or ask your own question.