Basic HTTP Authentication & PHP-FastCGI

I’m sure its possible, but I can’t seem to find any documentation on
it…

How would I pass the Basic HTTP Authentication user & password over to
PHP to do the check?

Phillip B Oldham
The Activity People
[email protected] mailto:[email protected]


Policies

This e-mail and its attachments are intended for the above named
recipient(s) only and may be confidential. If they have come to you in
error, please reply to this e-mail and highlight the error. No action
should be taken regarding content, nor must you copy or show them to
anyone.

This e-mail has been created in the knowledge that Internet e-mail is
not a 100% secure communications medium, and we have taken steps to
ensure that this e-mail and attachments are free from any virus. We must
advise that in keeping with good computing practice the recipient should
ensure they are completely virus free, and that you understand and
observe the lack of security when e-mailing us.

like PHP_AUTH_USER that Apache gives you and stuff?

you can do it purely in PHP:
http://www.php.net/features.http-auth

it would be neat if the server would pass an environment variable of
the name of the logged in user after it’s done it’s password check
though.

On Tue, Jul 22, 2008 at 12:59:32, mike said…

it would be neat if the server would pass an environment variable of
the name of the logged in user after it’s done it’s password check
though.

Isn’t that what REMOTE_USER is for?

I think this might be a suitable application for a FastCGI Authorizer,
but I don’t think nginx’s auth module supports making FCGI authorizer
requests.
If that’s so, are there any plans to implement this? Seems like it
would be a very useful addition.

Hi,

On 23 Jul 2008, at 10:27, Phillip B Oldham wrote:

mike wrote:

like PHP_AUTH_USER that Apache gives you and stuff?

Yep, just like that.

I could be wrong but I think that this only happens once Apache has
already done the authorisation and granted access to the resource.

you can do it purely in PHP:
PHP: HTTP authentication with PHP - Manual
I thought nginx would have to pass the user/pass through to PHP via
the fastcgi params?

As I understand it, if PHP sends HTTP/1.1 401 Unauthorized then the
browser should ask the user for credentials, and then send them back
through the Authorization header. If this is in a location block
without auth_basic, then nginx will pass this header through to PHP,
and PHP can base64-decode the credentials, do what it needs to do in
order to work out whether they’re good credentials, and then return a
200 or another 401 appropriately. You may need to set
fastcgi_pass_header Authorization, I’m not sure - I’ve seen this
referred to in various nginx configs on the web but the version of
nginx I have on hand to test (0.5.35) seems to pass the
HTTP_AUTHORIZATION header through with or without this setting.

Cheers
i

Igor C. wrote:

On 23 Jul 2008, at 10:27, Phillip B Oldham wrote:

Yep, just like that.

I could be wrong but I think that this only happens once Apache has
already done the authorisation and granted access to the resource.
Not necessarily. If you connect to the resource using
http://user:[email protected] those variables are accessible.
Authorisation happens within PHP.
fastcgi_pass_header Authorization, I’m not sure - I’ve seen this
referred to in various nginx configs on the web but the version of
nginx I have on hand to test (0.5.35) seems to pass the
HTTP_AUTHORIZATION header through with or without this setting.
Thanks. I’ll test with the “fastcgi_pass_header Authorisation” and see
where I get.

On 23 Jul 2008, at 10:58, Phillip B Oldham wrote:

Igor C. wrote:

On 23 Jul 2008, at 10:27, Phillip B Oldham wrote:

Yep, just like that.

I could be wrong but I think that this only happens once Apache has
already done the authorisation and granted access to the resource.
Not necessarily. If you connect to the resource using http://user:[email protected]
those variables are accessible. Authorisation happens within PHP.

Ah, OK. Prepending credentials to the URL simply makes the browser
send the Authorization: header on the first request, but I see from
http://php.net/features.http-auth
that, as you say, Apache’s mod_php adds PHP_AUTH_USER and
PHP_AUTH_PW to PHP’s $_SERVER array whenever the Authorization header
is presented, whether originating from Apache or PHP. Gotcha.

mike wrote:

like PHP_AUTH_USER that Apache gives you and stuff?

Yep, just like that.

you can do it purely in PHP:
PHP: HTTP authentication with PHP - Manual
I thought nginx would have to pass the user/pass through to PHP via the
fastcgi params?

On 7/23/08, Phillip B Oldham [email protected] wrote:

I thought nginx would have to pass the user/pass through to PHP via the
fastcgi params?

Yeah the idea would be you put in a user/pass check at the top of each
script (when you initialize the user) to check for valid credentials.
It’s not the cleanest but it would probably work.

For PHP to get it from the webserver like it can with Apache then yes,
nginx needs to be able to pass the information that was successful
from the auth_basic/auth module(s) to a variable that can be grabbed
from within PHP (I’d expect $_SERVER[‘HTTP_AUTH_USER’] or something
like that) - not sure if the password can be given (or is needed) or
depends if it’s plaintext vs. digest, etc…

Hi,

On 23 Jul 2008, at 11:19, mike wrote:

For PHP to get it from the webserver like it can with Apache then yes,
nginx needs to be able to pass the information that was successful
from the auth_basic/auth module(s) to a variable that can be grabbed
from within PHP (I’d expect $_SERVER[‘HTTP_AUTH_USER’] or something
like that) - not sure if the password can be given (or is needed) or
depends if it’s plaintext vs. digest, etc…

Not sure if it does, but if so, doesn’t this (“information that was
successful from the auth_basic/auth module”) mean that auth is being
done twice, once by nginx + htpasswd file, and then by PHP + its own
auth scheme?

On śro, lip 23, 2008 at 11:40:26 +0100, Igor C. wrote:

Not sure if it does, but if so, doesn’t this (“information that was
successful from the auth_basic/auth module”) mean that auth is being
done twice, once by nginx + htpasswd file, and then by PHP + its own
auth scheme?

I didn’t try it with nginx but in general you should be able to
implement your own authentication in the application (e.g. in PHP)
without any support from the web server other than passing
Authorization header from the client ($_SERVER[“HTTP_AUTHORIZATION”] in
PHP?).

Best regards,
Grzegorz N.

On 23 Jul 2008, at 11:14, Igor C. wrote:

Not necessarily. If you connect to the resource using http://user:[email protected]
those variables are accessible. Authorisation happens within PHP.

Ah, OK. Prepending credentials to the URL simply makes the browser
send the Authorization: header on the first request, but I see from PHP: HTTP authentication with PHP - Manual
that, as you say, Apache’s mod_php adds PHP_AUTH_USER and
PHP_AUTH_PW to PHP’s $_SERVER array whenever the Authorization
header is presented, whether originating from Apache or PHP. Gotcha.

I mean, whether presented by the browser because of a prior 401 from
Apache or PHP. Duh.

Hi Grzegorz ,

On 23 Jul 2008, at 11:48, Grzegorz N. wrote:

in
PHP?).

Absolutely - I’m only saying (without knowing details of the filter
chain) that in order to do what Philip and Mike said, i.e. have nginx
pass “user” and “pass” to PHP, logically:

  • auth_basic would need to be in order for nginx to decode the (e.g.)
    “Basic aWdvcjpub2Jub3NlMg==” into ‘user’ and ‘pass’ variables to PHP
  • in order for it to pass those on to PHP, the authentication would
    need to be successful, meaning that as it’s auth_basic, it has to
    check against auth_basic_user_file

and if those details are then used for authentication in PHP, then
there are two separate auth mechanisms going on.

As I’ve understood, mod_php in Apache decodes the u/p from the
Authorization header (if present) and passes to PHP in an environment
variable; nginx/fastcgi doesn’t do this, so therefore, exactly as you
said, the PHP app would need to decode the u/p from
$_SERVER[‘HTTP_AUTHORIZATION’].

Phew :slight_smile:
igor

On Wed, Jul 23, 2008 at 10:27:09AM +0100, Phillip B Oldham wrote:

mike wrote:

like PHP_AUTH_USER that Apache gives you and stuff?

Yep, just like that.

you can do it purely in PHP:
PHP: HTTP authentication with PHP - Manual
I thought nginx would have to pass the user/pass through to PHP via the
fastcgi params?

There is $remote_user variable, but there is no $remote_password.

On 7/23/08, Igor S. [email protected] wrote:

There is $remote_user variable, but there is no $remote_password.

Okay, then you should be able to add in your fastcgi params

fastcgi_param REMOTE_USER $remote_user;

and it should pass it to PHP, only if the user is properly
authenticated right? $remote_user is only populated if the
authentication is passed, I assume.

I don’t think people typically need the password. They either need to
choose to let the webserver handle auth, or the PHP/scripting language
to handle it.

re: Igor C. - no, it won’t be doing the auth twice. This is
assuming nginx is doing all the auth stuff, you’re simply passing the
user to the script so you can grab the username.

If you need more flexibility and password info, I’d suggest going a
pure PHP route then.

(Also I assume that if $remote_user is not set - because it’s not
under an authed directory, or it’s an invalid password/etc, that it
will not show an error, but just pass an empty REMOTE_USER string - so
your PHP app would want to understand a non-existent
$_SERVER[‘REMOTE_USER’] or an empty one means invalid auth)

Hi,

On 23 Jul 2008, at 19:09, mike wrote:

authentication is passed, I assume.

I don’t think people typically need the password. They either need to
choose to let the webserver handle auth, or the PHP/scripting language
to handle it.

re: Igor C. - no, it won’t be doing the auth twice. This is
assuming nginx is doing all the auth stuff, you’re simply passing the
user to the script so you can grab the username.

The original question was “How would I pass the Basic HTTP
Authentication user & password over to PHP to do the check?”

Meaning that if nginx was also doing auth, it would be 2 checks, and
all Philip needed was HTTP_AUTHORIZATION header, as has been stated.

But sure, in the case you describe, the auth is only done by nginx.

On 7/24/08, Igor C. [email protected] wrote:

The original question was “How would I pass the Basic HTTP Authentication
user & password over to PHP to do the check?”

Meaning that if nginx was also doing auth, it would be 2 checks, and all
Philip needed was HTTP_AUTHORIZATION header, as has been stated.

But sure, in the case you describe, the auth is only done by nginx.

Oh okay. I was just thinking he wanted auth and he wanted to know the
user info if the auth passed.

I guess the original question was a bit lost in my head by the time I
replied. :slight_smile:

On Tue, Jul 22, 2008 at 04:47:47PM +0100, Phillip B Oldham wrote:

I’m sure its possible, but I can’t seem to find any documentation on it…

How would I pass the Basic HTTP Authentication user & password over to
PHP to do the check?

User and password are passed in HTTP_AUTHORIZATION parameter in base64:
“user:passwd” value is encoded as “dXNlcjpwYXNzd2Q=”.

mike wrote:

On 7/23/08, Igor S. [email protected] wrote:

There is $remote_user variable, but there is no $remote_password.

Okay, then you should be able to add in your fastcgi params

fastcgi_param REMOTE_USER $remote_user;

Perfect. I’ll try with:

fastcgi_param HTTP_AUTH $remote_user;

will let you guys know how I get on.