Apache user authentication multiplexing
There are occasions when it would be useful to be able to use two different authentcation mechanisms for the same Web site, for instance to allow a site with some non-Cambridge users still to use Raven for its Cambridge users. The following snippet of apache.conf suggests a (fairly hairy) way to accomplish this using Apache 2.0.40 or later. Unauthenticated visitors to a URL in the protected space get an error page (the "401" ErrorDocument) offering them a choice of authentication mechanisms. When one of them succeeds, a cookie is set recording which one it was, and all further authentication happens transparently.
In this example, the DocumentRoot is /var/www, and the protected area is /var/www/protected. The example authentication methods are Raven and HTTP Basic authentication. It should be possible to transplant the whole thing into .htaccess if you really want to.
<Directory "/var/www/protected"> AACookieKey "Some random string" # Make a 'cancel' from ucam_webauth go to the right error document AACancelMsg "<a href='/protected/_ucam_webauth/_bounce'>Raven</a><a href='/protected/_basic/_bounce'>Basic</a>" RewriteEngine on RewriteBase /protected RewriteCond %{HTTP:Cookie} (^|;\s*)bounceurl=([^;]*)($|;) RewriteRule ^_(ucam_webauth|basic)/_bounce _$1/%2 # For magic URIs, if we know who the user is, then redirect either # internally or externally to the real version. In the former case, # remember who the user was. RewriteCond %{REMOTE_USER} !="" RewriteCond %{ENV:REDIRECT_STATUS} !="" RewriteRule ^_(ucam_webauth|basic)/(.*)$ $2 [L,E=IU:%{REMOTE_USER}] RewriteCond %{REMOTE_USER} !="" RewriteRule ^_(ucam_webauth|basic)/(.*)$ $2 [L,R,CO=authtype:$1:%{SERVER_NAME}] RewriteRule ^_(ucam_webauth|basic)/(.*)$ - [L] # For non-magic URIs, if we already know who the user is, let them # through. RewriteCond %{ENV:REDIRECT_IU} !="" RewriteRule ^(.*)$ - [L,E=REMOTE_USER:%{ENV:REDIRECT_IU}] # If we don't yet know who the user is, but it looks as if they've # logged in, pass the request on to the correct authenticator. RewriteCond %{HTTP:Cookie} (^|;\s*)authtype=(ucam_webauth|basic)($|;) RewriteRule ^(.*)$ _%2/$1 [L] # Otherwise, generate a "401" response, recording the URL they first # thought of in a cookie, and let them choose how to authenticate. RewriteRule ^(.*)$ _authfail [L,CO=bounceurl:$1:%{SERVER_NAME}] Redirect 401 /protected/_authfail # If this ErrorDocument were dynamic, it could arrange to refer to # protected/_ucam_webauth/$1, and we wouldn't need the bounceurl # cookie. ErrorDocument 401 "<a href='/protected/_ucam_webauth/_bounce'>Raven</a><a href='/protected/_basic/_bounce'>Basic</a>" </Directory> # The _ucam_webauth and _basic directories must exist, but they can be # empty. "Require" lines can obviously be changed to be more useful. <Directory "/var/www/protected/_ucam_webauth"> AuthType Ucam-WebAuth Require valid-user </Directory> <Directory "/var/www/protected/_basic"> AuthType basic AuthName "Test thingy" AuthUserFile "htpasswd" Require valid-user </Directory>