Does Urllib2 Support Preemptive Authentication Authentication?
Solution 1:
Here's a simple Preemptive HTTP basic auth handler, based on the code from urllib2.HTTPBasicAuthHandler
. It can be used in the exact same manner, except an Authorization
header will be added to every request with a matching URL. Note that this handler should be used with a HTTPPasswordMgrWithDefaultRealm
. That's because there is no realm coming back in a WWW-Authenticate
challenge since you're being preemptive.
classPreemptiveBasicAuthHandler(urllib2.BaseHandler):
def__init__(self, password_mgr=None):
if password_mgr isNone:
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
self.passwd = password_mgr
self.add_password = self.passwd.add_password
defhttp_request(self,req):
uri = req.get_full_url()
user, pw = self.passwd.find_user_password(None,uri)
#logging.debug('ADDING REQUEST HEADER for uri (%s): %s:%s',uri,user,pw)if pw isNone: return req
raw = "%s:%s" % (user, pw)
auth = 'Basic %s' % base64.b64encode(raw).strip()
req.add_unredirected_header('Authorization', auth)
return req
Solution 2:
similar to @thom-nichols's answer; but subclassing HTTPBasicAuthHandler
also handling HTTPS requests.
import urllib2
import base64
classPreemptiveBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
'''Preemptive basic auth.
Instead of waiting for a 403 to then retry with the credentials,
send the credentials if the url is handled by the password manager.
Note: please use realm=None when calling add_password.'''defhttp_request(self, req):
url = req.get_full_url()
realm = None# this is very similar to the code from retry_http_basic_auth()# but returns a request object.
user, pw = self.passwd.find_user_password(realm, url)
if pw:
raw = "%s:%s" % (user, pw)
auth = 'Basic %s' % base64.b64encode(raw).strip()
req.add_unredirected_header(self.auth_header, auth)
return req
https_request = http_request
here is an example for dealing with a jenkins server which does not send you 401
http errors (retry with auth). I'm using urllib2.install_opener
to make things easy.
jenkins_url = "https://jenkins.example.com"
username = "johndoe"
api_token = "some-cryptic-value"
auth_handler = PreemptiveBasicAuthHandler()
auth_handler.add_password(
realm=None, # default realm.
uri=jenkins_url,
user=username,
passwd=api_token)
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
Solution 3:
Depending on what kind of authentication is required, you can send the Authorization headers manually by adding them to your request before you send out a body.
Post a Comment for "Does Urllib2 Support Preemptive Authentication Authentication?"