python-urllib2 HTTPPasswordMgr不起作用-凭据未发送错误
作者:互联网
以下python curl调用具有以下成功结果:
>>> import subprocess
>>> args = [
'curl',
'-H', 'X-Requested-With: Demo',
'https://username:password@qualysapi.qualys.com/qps/rest/3.0/count/was/webapp' ]
>>> xml_output = subprocess.check_output(args).decode('utf-8')
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
138 276 0 276 0 0 190 0 --:--:-- 0:00:01 --:--:-- 315
>>> xml_output
u'<?xml version="1.0" encoding="UTF-8"?>\n<ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://qualysapi.qualys.com/qps/xsd/3.0/was/webapp.xsd">\n<responseCode>SUCCESS</responseCode>\n <count>33</count>\n</ServiceResponse>'
不幸的是,此调用无法成功转换为urllib2.我收到另一个XML响应,指出用户未提供授权凭证:
>>> import urllib2
>>> # Create a password manager.
... password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
>>> # Add the username and password.
... top_level_url = 'https://qualysapi.qualys.com'
>>> password_mgr.add_password(None, top_level_url, username, password)
>>> handler = urllib2.HTTPBasicAuthHandler(password_mgr)
>>> opener = urllib2.build_opener(handler)
>>> urllib2.install_opener(opener)
>>> headers = {'X-Requested-With':'Demo'}
>>> uri = 'https://qualysapi.qualys.com/qps/rest/3.0/count/was/webapp'
>>> req = urllib2.Request(uri,None,headers)
>>> result = urllib2.urlopen(req)
>>> result
'<ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://qualysapi.qualys.com/qps/xsd/3.0/was/webapp.xsd">\n <responseCode>INVALID_CREDENTIALS</responseCode>\n <responseErrorDetails>\n <errorMessage>User did not supply any authentication headers</errorMessage>\n </responseErrorDetails>\n</ServiceResponse>'
顺便说一句,我收到与httplib相同的错误消息:
>>> import httplib, base64
>>> auth = 'Basic ' + string.strip(base64.encodestring(username + ':' + password))
>>> h = httplib.HTTPSConnection('qualysapi.qualys.com')
>>> h.request("GET", "/qps/rest/3.0/count/was/webapp/")
>>> r1 = h.getresponse()
>>> print r1.status, r1.reason
200 OK
>>> data1 = r1.read()
>>> data1
'<ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://qualysapi.qualys.com/qps/xsd/3.0/was/webapp.xsd">\n <responseCode>INVALID_CREDENTIALS</responseCode>\n <responseErrorDetails>\n <errorMessage>User did not supply any authentication headers</errorMessage>\n </responseErrorDetails>\n</ServiceResponse>'
我了解httplib& urllib2仅在将SSL编译到套接字(该SSL编译到套接字的模块)中时才有效.实际上,我已经成功地将urllib2用于不同API上的其他调用.该问题仅限于这一特定的API.
urllib2(和httplib)与curl有何不同?
注意:在所有示例中,使用的用户名和密码都相同.
更新:
问题出在基本身份验证密码管理器上.当我手动添加基本授权标头时,urllib2 cal可以工作:
>>> import base64
>>> base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
>>> req.add_header("Authorization", "Basic %s" % base64string)
>>> # Make request to fetch url.
... result = urllib2.urlopen(req)
>>> # Read xml results.
... xml = result.read()
>>> xml
'<?xml version="1.0" encoding="UTF-8"?>\n<ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://qualysapi.qualys.com/qps/xsd/3.0/was/webapp.xsd">\n <responseCode>SUCCESS</responseCode>\n <count>33</count>\n</ServiceResponse>'
解决方法:
从Python urllib2 Basic Auth Problem
The problem [is] that the Python libraries, per HTTP-Standard, first send an unauthenticated request, and then only if it’s answered with a 401 retry, are the correct credentials sent. If the … servers don’t do “totally standard authentication” then the libraries won’t work.
第一次尝试时,此特定API不会以401 Unauthored进行响应,而是以XML响应进行响应,其中包含未使用200 OK响应代码发送凭据的消息.
标签:python,curl,urllib2,httplib 来源: https://codeday.me/bug/20191011/1892743.html