Hi all,

 I ran into some small issue concerning logout with PAS; it would be
nice if the developers would consider the attached patch or address the
issue in other ways.


 When having installed PAS users from plain Zope user folders using
plain HTTP authentication cannot logout if sending a "Referrer" header,
e.g. by following a link in the ZMI.

 Steps to reproduce:

   - You need a Zope server with PAS installed and a plain user folder
     in the Zope root.
     (One way to get it is to set up a plain Zope instance, and install
     PluginRegistry and PluggableAuthService.)
   - log in the the server with "/manage", so You get the
     full ZMI frameset
   - select "logout" from the drop down in the upper frame
     -> does not logout, instead shows in the content frame
     the ZMI top frame, i.e. "/manage_top_frame", a second time
   - type in "/manage_zmi_logout" manually
     -> HTTP auth popup appears, logout is possible

 (I have tested this with Mozilla 1.7.8 and Opera8 under Linux, with sending
referrers enabled. Other browsers might show a different behaviour.
 With Opera, one can switch off referrers with "Preferences" >
"Advanced" > "Network"; then uncheck the checkbox labelled
"Enable referrer logging". If disabling referrers, logging out
via the drop down in the upper frame works.)

 Possible Explanation:

 It seems the problem has something to do with the monkey patch to
"/manage_zmi_logout" done in the __init__.py.

The patch checks if the next user folder in the current context is a
PAS; if this is not the case, it sets the response code to 401,
triggering a HTTP authentication popup if send to the client. 

 Afterwards the code checks for a HTTP 'Referrer' header in the request;
if there is an referrer, the client is redirected there. In that
case the 401 status code is overwritten with a 302 status code; no
authentication popup opens at the client. 

 Because at least my browser sends a 'Referrer' header if clicking on a
link, but not if typing in the URL manually, this explains (to me), why
logging out by following a link (in the case above via JavaScript) does
not work. One has to send a request without referrer to log out

 Suggested workaround:

  Instead of setting the 401 status code manually raise an
"Unauthorized" exception -- this bypasses the following redirect. 
 In a PAS user folder this is what the HTTPBasicAuthHelper does on
logout, so it cannot be all wrong.

 A patch is attached. The patch is against PluggableAuthService1.1b2,
but seems to be applicable for the svn trunk, too. Thanks for reading
this lengthy mail, in any way.

Used software versions:

 python 2.3.5
 Zope   2.7.8
 PluginRegistry 1.0
 PAS    1.1b2

 Mozilla 1.7.8 (Debian package 1.7.8-1sarge3)
 Opera 8.51    (Debian package opera8-binary)


--- PluggableAuthService/__init__.py.orig	2005-01-27 20:00:22.000000000 +0100
+++ PluggableAuthService/__init__.py	2006-01-27 22:31:18.000000000 +0100
@@ -62,6 +62,7 @@
 # monkey patch Zope to cause zmi logout to be PAS-aware
 from App.Management import Navigation
 from interfaces.authservice import IPluggableAuthService
+from zExceptions import Unauthorized
 def manage_zmi_logout(self, REQUEST, RESPONSE):
     """Logout current user"""
@@ -73,8 +74,8 @@
         acl_users.resetCredentials(REQUEST, RESPONSE)
-        RESPONSE.setStatus(401)
-        RESPONSE.setHeader('WWW-Authenticate', 'basic realm="%s"' % realm, 1)    
+        RESPONSE.setHeader('WWW-Authenticate', 'basic realm="%s"' % realm, 1)
+        raise Unauthorized, '<p>You have been logged out.</p>'
     referrer = REQUEST.get('HTTP_REFERER') # HTTP_REFERER is optional header
     if referrer:
Zope-PAS mailing list

Reply via email to