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.

Description:

 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
successfully.


 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)


Cheers,
Clemens

--- 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)
     else:
         realm=RESPONSE.realm
-        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:
         REQUEST['RESPONSE'].redirect(referrer)
_______________________________________________
Zope-PAS mailing list
Zope-PAS@zope.org
http://mail.zope.org/mailman/listinfo/zope-pas

Reply via email to