> So, leaving other issues aside *wink*, I'm no puzzled by the challenge
> code in PAS. It looks like there was some attempt at distinguishing
> challenging by some sort of 'protocol', but it leaves a lot to be
> desired, or I don't understand how it's supposed to work.

Probably both ;)

The discussion on this is a little spread out, but almost all threads at
http://mail.zope.org/pipermail/zope-pas/2004-October/thread.html relate to
it in some way.

> The problem I'm facing now is that using the Cookie Auth plugin
> effectively breaks WebDAV (and possibly FTP and XML-RPC), because as
> soon as the Cookie Auth plugin is hit on challenge, it does a redirect
> to the login form.

Yeah, that is by design IIUC.

The problem was that a cookie auth plugin wants to reponds to an
unauthorized exception by doing a redirect, but http auth wants to do it via

IIRC, the basic flow was:
* via a little magic, PAS would arrange for an Unauthorized exception to
call the main PAS 'unauthorized' function.  That may be what Chris patched
in his previous mail.
* PAS would call all "challenge" plugins in the order they were defined.

PAS needs to call *all* plugins - it can not simply stop after it finds a
plugin that does something.  Consider HTTP basic and NTLM authentication -
*both* those plugins must be called, so both the www-authenticate headers
appear.  However, as soon as the cookie plugin is invoked, which does a
redirect, the challenges setup by the other plugins have been lost.

Thus, a "protocol" was invented.  The first plugin to set a protocol means
that protocol "wins".  All plugins that use www-authenticate use the same
prefix - so once initiated, an Unauthorized challenge will not get "trumped"
by a redirect.

> Changing the Cookie Auth to come after Basic Auth doesn't help either,
> as then instead of a browser client being directed to the login form
> it gets a basic auth dialog instead.

Yep - as above, that is by design.

> Is it possible that nobody noticed this yet? Or is it just me not
> getting enough sleep last night?

It sounds like the problem is that PAS does not have any concept of the
"source" of the request.  The existing behaviour seems correct (enough) for
the standard case of a web browser hitting the site on a standard HTTP
port - but not for the other ways to get at the site.

What *might* be possible is something like the following untested patch,
adapted from what Chris posted:

--- PluggableAuthService.py     27 May 2005 19:10:45 -0000      1.31
+++ PluggableAuthService.py     12 Aug 2005 01:00:58 -0000
@@ -990,7 +990,13 @@
         plugins = self._getOb('plugins')
         challengers = plugins.listPlugins( IChallengePlugin )

-        protocol = None
+        if self.isDAVRequest(request):
+            # DAV clients/EE can't deal with form-based auth, so
+            # we insist on the http protocol
+            protocol = "http"
+        else:
+            # Other sources get anything that might be configured.
+            protocol = None

         for challenger_id, challenger in challengers:
             challenger_protocol = getattr(challenger, 'protocol',

However, I assume the same concerns exist even when the request comes via
xmlrpc, ftp, etc.  I'm not sure what to do about those cases.

Also, the above patch will not work if someone wants something other than
http auth on their dav port.  eg, consider a site that is configured to not
use cookies or http, but their own custom auth scheme, and therefore with
its own protocol.  The above patch would kill their site as their existing,
working plugin would be excluded.  It would not be hard to handle that

Hope that helped a little,


Zope-PAS mailing list

Reply via email to