Cannot exclude a path from basic auth when using a front controller script

Posted by Adam Monsen on Server Fault See other posts from Server Fault or by Adam Monsen
Published on 2012-06-08T06:40:14Z Indexed on 2012/06/09 4:42 UTC
Read the original article Hit count: 608

Filed under:

I have a small PHP/Apache2 web application wherein I'd like to do two seemingly incompatible operations:

  1. Route all requests through a single PHP script (a "front controller", if you will)
  2. Secure everything except API calls with HTTP basic authentication

I can satisfy either requirement just fine in isolation, it's when I try to do both at once that I am blocked. For no good reason I'm trying to accomplish these requirements solely with Apache configuration.

Here are the requirements stated as an example. A GET request for this URL:

http://basic/api/listcars?max=10

should be sent through front.php without requiring basic auth. front.php will get /api/listcars?max=10 and do whatever it needs to with that.

Here's what I think should work. In my /etc/hosts I added

127.0.0.1 basic

and I am using this Apache config:

<Location />
  AuthType Basic
  AuthName "Home Secure"
  AuthUserFile /etc/apache2/passwords
  require valid-user
</Location>

<VirtualHost *:80>
  ServerName basic
  DocumentRoot /var/www/basic
  <Directory /var/www/basic>
    <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{SCRIPT_FILENAME} !-f
      RewriteCond %{SCRIPT_FILENAME} !-d
      RewriteRule ^(.*)$ /front.php/$1 [QSA,L]
    </IfModule>
  </Directory>
  <Location /api>
    Order deny,allow
    Allow from all
    Satisfy any
  </Location>
</VirtualHost>

But I still always get a HTTP 401: Authorization Required response. I can make it work by changing <Location /api> into

<Location ~ /api>

but this allows more than I want to past basic auth.

I also tried changing the <Directory /var/www/basic> section into <Location />, but this doesn't work either (and it results in some strange values for PATH_TRANSLATED being passed to the script).

I searched around and found many examples of selective exclusion of basic auth, but none that also incorporated a front controller.

I could certainly do something like handle basic auth in the front controller, but if I can have Apache do that instead I'll be able to keep all authentication logic out of my PHP code.

A friend suggested splitting this into two vhosts, which I know also works. This used to be two separate vhosts, actually.

I'm using Apache 2.2.22 / PHP 5.3.10 on Ubuntu 12.04.

© Server Fault or respective owner

Related posts about apache2