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: 690
        
apache2
I have a small PHP/Apache2 web application wherein I'd like to do two seemingly incompatible operations:
- Route all requests through a single PHP script (a "front controller", if you will)
- 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