Bug 41685 - Implement optional HTTP Authentication in a standards-compliant fashion
Summary: Implement optional HTTP Authentication in a standards-compliant fashion
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: Core (show other bugs)
Version: 2.5-HEAD
Hardware: All All
: P2 enhancement with 4 votes (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Depends on:
Reported: 2007-02-22 17:33 UTC by Tim Nelson
Modified: 2011-03-10 04:43 UTC (History)
1 user (show)


Note You need to log in before you can comment on or make changes to this bug.
Description Tim Nelson 2007-02-22 17:33:41 UTC
It would be possible to implement optional HTTP Authentication (something that
people seem to want often enough; see links below) without violating any RFCs.  

Optional Auth Process
The idea is that (if the feature were turned on) the process would work as follows:
1. A request comes in from a web browser for a page marked with optional
2. Seeing no authentication, Apache passes this on to the CGI/mod_perl that will
process it
3. The CGI/mod_perl sends back a response with a 401/WWW-Authenticate
4. Apache, seeing authentication in the response this time, processes the
authentication.  Either way, it passes control back to the CGI/mod_perl, but if
the authentication failed, it will not populate the variables containing the
username and the like.  It is up to the CGI/mod_perl how to respond to this.

Changes required
The change required in Apache to achieve this is fairly simple: if optional auth
is specified (eg. in a .htaccess), pass control to the CGI/mod_perl even if the
auth fails; don't respond with a 401 or a WWW-Authenticate.

Suggested config syntax:
AuthOptional On

Presumably, this should also be part of AllowOverride AuthConfig

Additional Information
I'm not 100% sure this belongs in the core, but I was unsure where it did belong

For reference, the complaints that people have about using HTTP Auth are
summarised in the following articles:

Some of their solutions involve changing RFCs.  Mine only involves adding a
configuration option which doesn't violate RFCs
Comment 1 alec-keyword-apache.d8a97a 2011-03-08 09:18:50 UTC
An alternative solution to this can be implemented with this tiny patch:

brock% cat files/require-auth.patch 
--- httpd-2.2.16/server/request.c.orig	2011-03-08 12:36:08.701398059 +0000
+++ httpd-2.2.16/server/request.c	2011-03-08 12:47:46.159477808 +0000
@@ -1631,6 +1631,11 @@
     require_line *reqs;
     int i;
+    const char* auth_header = apr_table_get(r->headers_in, "Authorization");
+    if (auth_header && strlen(auth_header)) {
+    	return 1;
+    }
     if (!reqs_arr) {
         return 0;

This changes the requires_auth function to return true if the browser happens to have sent authentication credentials.  The assumption here is that whatever resource is being protected will detect the authentication and apply whatever authorization is needed.
Comment 2 Tim Nelson 2011-03-09 16:12:25 UTC
I haven't read the code, but the description makes it sound like this would work.  Is there any chance it can be included in Apache?
Comment 3 Nick Kew 2011-03-09 17:15:25 UTC
Slightly confused.  What standard are you referencing here?
Comment 4 alec-keyword-apache.d8a97a 2011-03-09 17:41:18 UTC
(In reply to comment #3)
> Slightly confused.  What standard are you referencing here?

I think rfc2617 is most relevant, although this really isn't a standards issue, it's an issue with the way apache configures and handles authentication.  Currently, apache will only process an Authorization: header if there is a require directive on the request.  My change above changes it so apache will always process an Authorization header.  This allows a module or CGI program (or .asis file) to send a WWW-Authenticate challenge back to a client, but then have Apache handle the resulting Authorization header.  Without this, the module/CGI program would have to re-implement the authentication code that is already in apache.  For HTTP basic, this is a trivial effort, but Digest or Negotiate are both hard enough that it is attractive to use the existing code in Apache rather than re-implementing it.  I have a program that sends a WWW-Authenticate header, and then I use this config:

    <Location /semiprivate>
        AuthType Kerberos
        #require valid-user
        Krb5Keytab /path/to/keytab
        KrbMethodK5Passwd off
        KrbAuthoritative off

which, with the above patch, allows anonymous access until the program sends a WWW-Authenticate header, at which point browsers will send an Authorization header, and then Apache will authenticate them.  Prior to the time the program sends the WWW-Authenticate header, the user can access resources in /semiprivate anonymously.
Comment 5 Nick Kew 2011-03-10 02:40:05 UTC
What you describe isn't a standards-issue, but the description of the issue ("Implement optional HTTP Authentication in a standards-compliant fashion") indicates that it is.  Who is at cross-purposes here?
Comment 6 Tim Nelson 2011-03-10 04:43:08 UTC
Sorry, that's my fault.  The links provided in my first post suggest altering the standards.  My point is that is possible to fix one of the problems that they list in their articles without altering the standards, and that's what I'm suggesting here.  So what I'm saying is, "People have always thought that fixing the problem requires altering the standards, but I've found a way to do it without altering the standards".  My apologies for any miscommunication.