Apache user authentication multiplexing: Difference between revisions

From RavenWiki
Jump to navigationJump to search
(This turns out to need a relatively recent Apache)
(Don't try to set empty cookies. Spotted by Martin Lucas-Smith.)
 
Line 12: Line 12:
         RewriteBase /protected
         RewriteBase /protected


         RewriteCond %{HTTP:Cookie} (^|;\s*)bounceurl=([^;]*)($|;)
         RewriteCond %{HTTP:Cookie} (^|;\s*)bounceurl=/([^;]*)($|;)
         RewriteRule ^_(ucam_webauth|basic)/_bounce      _$1/%2
         RewriteRule ^_(ucam_webauth|basic)/_bounce      _$1/%2


Line 37: Line 37:
         # Otherwise, generate a "401" response, recording the URL they first
         # Otherwise, generate a "401" response, recording the URL they first
         # thought of in a cookie, and let them choose how to authenticate.
         # thought of in a cookie, and let them choose how to authenticate.
         RewriteRule ^(.*)$ _authfail    [L,CO=bounceurl:$1:%{SERVER_NAME}]
         RewriteRule ^(.*)$ _authfail    [L,CO=bounceurl:/$1:%{SERVER_NAME}]
         Redirect 401 /protected/_authfail
         Redirect 401 /protected/_authfail



Latest revision as of 13:46, 18 April 2006

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>