Wednesday, October 10, 2012

Rack::Auth::Basic with Apache and mod_fcgid

I recently struggled to find the answer, but I've finally got a working configuration and wanted to share it. I was using Rack::Auth::Basic for a project that I didn't need a full blown authentication system, but just to keep the site from being totally public. I had my rackup server using it just fine, but trying to run it through Apache and mod_fcgid was not working. My breakthrough came after a long time of scouring over the Internet finding the following post (finder's credit to my brother who helped me debug the issue): https://metacpan.org/module/Plack::Middleware::Auth::Basic#LIMITATIONS This idea and a few Apache docs later we came up with the following configuration:
<Directory /www/site>
  Options +ExecCGI +FollowSymLinks
  AllowOverride None
  RewriteEngine On
  # Make sure HTTP_AUTHORIZATION has something in it before trying to hand it over!
  RewriteCond %{HTTP:Authorization} ^(.+)$
  # Add HTTP_AUTHORIZATION to the environment so our rack app can get at it.
  RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
</Directory>
The first RewriteRule is used because of this:
Flags that alter metadata associated with the request (T=, H=, E=) have no affect in per-directory and htaccess context, when a substitution (other than '-') is performed during the same round of rewrite processing.
Tested Versions:
Rack      1.4.0, 1.4.1
Apache    2.2.6, 2.2.15 
mod_fcgid 2.3.5, 2.3.7
Side note:
When testing something like this, your browser likes to cache the username and password, which is really nice for actual use, but if you're trying to get it working, and you've possibly got cached values, change your password in your app. It will cause authentication with the cached values to fail and require you to enter new credentials.