Overriding Raven authentication for parts of a site
[NB Primarily relevant to Apache servers using mod_ucam_webauth, though also relevant to other authentication mechanisms on Apache.]
One problem with Apache authentication (Basic Auth, Raven via mod_ucam_webauth, etc.) is that the configuration settings (AuthType etc.) are "inherited". In consequence, if you enable Raven authentication in a <Location /> block, it will apply e.g. to /error-pages, which may be a problem if you have custom error pages that should be shown for login failures (user cancelled logins, cookies not working, etc.).
Apache does not provide a built-in way to override inherited AuthType etc. - there's no "AuthType None" - so the only solution (that I've found) is to add a pair of "null" authentication and authorisation handlers and specify those.
If the Apache server has been built with mod_perl support, there is an easy Perl-based way to add such "null" handlers.
Just add (in perl.conf or equivalent if the Perl configuration is in a separate file, otherwise httpd.conf or wherever seems best)
<perl> { package Ucam::Apache::AuthNull; use strict; use Apache::Constants qw(:common); use Apache::Log; sub handler { my $r = shift; return DECLINED if lc($r->auth_type) ne 'ucam-authnull'; my $uri = $r->uri; $r->log->debug("AuthNull for $uri"); return OK; } package Ucam::Apache::AuthzNull; use strict; use Apache::Constants qw(:common); use Apache::Log; sub handler { my $r = shift; return DECLINED if lc($r->auth_type) ne 'ucam-authnull'; my $uri = $r->uri; $r->log->debug("AuthZNull for $uri"); my $requires = $r->requires; foreach my $req (@$requires) { my $value = lc($req->{'requirement'}); if ($value eq 'any-user') { $r->user('AuthNull'); return OK; } else { $r->server->log->warn("AuthzNull: bad 'require' type $value"); return DECLINED; # maybe another module will say OK } } return OK; } } </perl> PerlAuthenHandler Ucam::Apache::AuthNull PerlAuthzHandler Ucam::Apache::AuthzNull
and then in whichever file (e.g. http.conf) contains the access control details include
<Location /error-pages> Order deny,allow Allow from all # In order for Ucam-AuthNull to take precedence over Ucam-WebAuth (Raven), # we appear to need Satisfy all (not any). Satisfy all Require any-user AuthType Ucam-AuthNull </Location>
and the AuthType etc., should override any inherited Raven or Basic Auth configuration for URLs with the specified prefix (and similarly for directory-based access controls).
Caveats, cautions and other comments
- I've only tried the above with the Apache 1.3.29 server that's included in SUSE's SLES9 Linux distribution, and in particular it would need adjustments for the Apache 2 version of mod_perl due to incompatible mod_perl changes.
- For reasons which I've not investigated, simply specifying "Satisfy any" does not have the expected effect of allowing access according to the address-based controls and involving the authentication module only if address-based access is denied. It only works with "Satisfy all".
- It's not clear whether the auth handler is required to set a username, or the potential consequences if it doesn't, so it returns dummy user "AuthNull".
- Rather than "Require valid-user", you must specify "Require any-user", chosen to make clear that it's not applying any restrictions. Any/all users (that meet address-based restrictions) will be allowed access.
- The main purpose of the debug-level logging calls is to provide a way of confirming that the handlers really are being invoked, if they don't seem to be working.
jml4 14:27, 21 June 2006 (BST)