HTTP authentication is the standard way to authenticate access to resources. It has a number of flaws, and it not the most common way to do authentication on the web -- using standard forms is more common. However, in some circumstances it is the only possible way -- in particular, using non-browser tools to access pages (like a DAV client, an XML-RPC client, etc.)
HTTP authentication occurs when the server returns a 401 status (as in self.response().setStatus(401, 'Authorization Required') ) The server also must set another header, WWW-Authenticate: Basic realm="<i>realm name</i>" The realm name is the only message the user will see explaining what they are logging into (though they should know what page they are trying to access).
Clients will sent a header like Authorization: Basic xxx (where xxx is the authorization information)
Clients generally do not send authentication information until they are asked to do so (by receiving a 401 error). In typical usage, this back and forth will occur for every page access. (Though I don't see any reason you can't use the session and cookies like you would with normal, form-based authentication).
There is another style of authentication (this style is termed "Basic"), called "Digest" -- it sends a hash of the password, in a challenge-response style. This is more secure, as you can't sniff passwords. However, for reasons I cannot fathom, many major browsers <i>still</i> do not support this kind of authentication. Instead, you may use SSL to secure the password.
Apache does not normally send the Authorization header onto clients. To get around this you must use mod_rewrite (this is also typical with Zope, but I haven't gotten their technique to work for me)
Put this rewrite rule in:
<Location /WK> RewriteEngine On RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule /WK(.*) /WK2$1?AUTH=%1 [QSA,L,PT] </Location>
/WK2 is the real location of the WebKit hander -- either a location set up for mod_webkit, or another adapter. The RewriteCond line will capture the Authorization: header, which can be referenced by %1. The RewriteRule line will add a variable AUTH to the query string.
(I'm not entirely sure about the security of this -- the authentication information doesn't show up in the log, though)
In the servlet, you must both send the right information, and then receive that authorization. To require authentication:
res = self.response() res.setStatus(401, 'Authorization Required') res.setHeader('WWW-Authenticate', 'Basic realm="%s"' % realm)
To process it:
import base64 def authorized(self): req = self.request() httpAuth = req.field('AUTH', None) if not httpAuth: return 0 authType, auth = httpAuth.split(' ', 1) assert authType.lower() == 'basic', 'Only basic HTTP authentication is supported' name, password = base64.decodestring(auth.strip()).split(':', 1) return self.authorizeUser(name, password)
(If you are using HTTPAdapter, you will receive the authentication information in self.request().environ()['HTTP_AUTHORIZATION'] )
-- IanBicking - 10 May 2002
You can compile Apache 1.3 with SECURITY_HOLE_PASS_AUTHORIZATION which will cause apache to pass the HTTP_AUTHORIZATION environment variable to your script. If you don't want to recompile apache, you can use a much simpler mod_rewrite setup to add an additional environment variable:
<Location /WK> WKServer localhost 8086 SetHandler webkit-handler RewriteEngine On RewriteRule /WK(.*) - [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},PT] </Location>
With this you scan check self.request().environ()['HTTP_AUTHORIZATION'] and self.request().environ()['X-HTTP_AUTHORIZATION'] to find authorization Information.
There is also a patch to mod_webkit implementing passing of Authorisation Info to the Application Server available at http://blogs.23.nu/c0re/stories/1410/