urllib2 and HTTPBasicAuthHandler

M

m.banaouas

Hi all,
I started to use urllib2 library and HTTPBasicAuthHandler class in order
to authenticate with a http server (Zope in this case).
I don't know why but it doesn't work, while authenticating with direct
headers manipulation works fine!

WinXP Sp2
Python 2.4.4

Thanks in advance for your help/comments

# TestAuthHandler.py
import base64, httplib, urllib2
httplib.HTTPConnection.debuglevel = 1
#
def TestAuth(method):
data =
{'prot':'http','user':'admin','pass':'xxxxxx','host':'localhost','port':'8080','path':'manage','realm':'Zope'}
url = '%(prot)s://%(host)s:%(port)s/%(path)s' % data
req = urllib2.Request(url)
#
if (method == 'headers'):
base64string = base64.encodestring('%s:%s' % (data['user'],
data['pass']))[:-1]
req.add_header("Authorization", "Basic %s" % base64string)
elif (method == 'handler'):
auth_url = '%(host)s:%(port)s/%(path)s' % data
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(data['realm'], auth_url, data['user'],
data['pass'])
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
#
f = urllib2.urlopen(req)
data = f.read()
print data
#
TestAuth('headers')
TestAuth('handler')
-------------------------
output:
-------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>Zope on http://localhost:8080</title>
</head>
.... all right page ...
</html>


Traceback (most recent call last):
File "C:\Test\TestAuthHandler.py", line 25, in ?
TestAuth('handler')
File "C:\Test\TestAuthHandler.py", line 20, in TestAuth
f = urllib2.urlopen(req)
File "C:\Python\Lib\urllib2.py", line 130, in urlopen
return _opener.open(url, data)
File "C:\Python\Lib\urllib2.py", line 364, in open
response = meth(req, response)
File "C:\Python\Lib\urllib2.py", line 471, in http_response
response = self.parent.error(
File "C:\Python\Lib\urllib2.py", line 402, in error
return self._call_chain(*args)
File "C:\Python\Lib\urllib2.py", line 337, in _call_chain
result = func(*args)
File "C:\Python\Lib\urllib2.py", line 480, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 401: Unauthorized

Process "Python" completed with Exit Code 1, at 16/01/2007 16:51:18.
 
M

Max Erickson

m.banaouas said:
Hi all,
I started to use urllib2 library and HTTPBasicAuthHandler class
in order to authenticate with a http server (Zope in this case).
I don't know why but it doesn't work, while authenticating with
direct headers manipulation works fine!
....
port':'8080','path':'manage','realm':'Zope'}
url = '%(prot)s://%(host)s:%(port)s/%(path)s' % data
....

Are you certain that the realm on the server matches 'Zope'?

HTTPBasicAuthHandler uses the realm to look for the password, if the
realm the server provides is different, urllib2 will respond as if it
does not have a user/password.

If you are only doing one request, it isn't that big a deal; if you
are doing many requests or want urllib2 to handle the response for
other reseans, you can use a default realm, see the bottom of this
example:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305288

(The advantage of using a default rather than making sure the realm is
correct is that it can change and you won't have to do anything)



max
 
M

m.banaouas

Max,
I verified and determined that Zope realm is "Zope", by tcp spy tool
witch shows me the server headers.
Actually, I tried differents ways without success.
It seems like it's not so easy to negociate a basic authentication
process with urllib2, while it's based on very simple specifications,
however urllib2 is considered as one of the most powerfull library in
its category.

You suggest to use default realm:
# this creates a password manager
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
# because we have put None at the start it will always use this
username/password combination
passman.add_password(None, auth_url, data['user'] , data['pass'])
# create the AuthHandler
auth_handler = urllib2.HTTPBasicAuthHandler(passman)
# build an 'opener' using the handler we've created
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
req = urllib2.Request(url)
f = urllib2.urlopen(req)
data = f.read()
print data
but it doesn't work: urllib2.HTTPError: HTTP Error 401: Unauthorized

Max Erickson a écrit :
 
M

Max Erickson

....
passman.add_password(None, auth_url, data['user'] ,
....


The only thing I can come up with is that auth_url can't begin with a
protocol, like http:// or whatever.


max
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top