我正在使用urllib2。 登录服务器时遇到问题,该服务器返回基本身份验证和摘要身份验证。
它返回:
WWW-Authenticate: Digest realm="rets@aus.rets.interealty.com",nonce="c068c3d7d30cc0cd80db4d1c599e6d54",opaque="e75078c8-a825-474b-b101-f8ca2d1627ca",qop="auth" WWW-Authenticate: Basic realm="rets@aus.rets.interealty.com"
这是我的代码:
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(realm=None, uri='http://aus.rets.interealty.com', user='user', passwd='pwd')
opener = urllib2.build_opener(urllib2.HTTPDigestAuthHandler(passman))
urllib2.install_opener(opener)
retsRequest= urllib2.Request('http://aus.rets.interealty.com/Login.asmx/Login')
retsRequest.add_header("User-Agent", 'userAgent')
retsRequest.add_header("RETS-Version",'retsVersion')
response=urllib2.urlopen(retsRequest)
print response.read()
我可以使用IE登录此服务器,似乎IE使用摘要式身份验证。
答案 0 :(得分:0)
我没有遇到同样的问题,但曾经惊讶地发现urllib2.HTTPBasicAuthHandler
的开启者实际上只有两个请求而不是一个请求:第一个没有身份验证,然后是第二个带有身份验证的后退。
这可能会导致您的案件需要三个请求,其中第三个请求可能会忘记第二个请求的验证 - 应该检查。
你应该将两者:urllib2.HTTPDigestAuthHandler
和urllib2.HTTPBasicAuthHandler
添加到开场白。
答案 1 :(得分:0)
最近我有时间回顾这个问题,我想我找到了答案。这是python urllib2的一个bug。在urllib2中:
class AbstractDigestAuthHandler:
def http_error_auth_reqed(self, auth_header, host, req, headers):
authreq = headers.get(auth_header, None)
if self.retried > 5:
# Don't fail endlessly - if we failed once, we'll probably
# fail a second time. Hm. Unless the Password Manager is
# prompting for the information. Crap. This isn't great
# but it's better than the current 'repeat until recursion
# depth exceeded' approach <wink>
raise HTTPError(req.get_full_url(), 401, "digest auth failed",
headers, None)
else:
self.retried += 1
if authreq:
scheme = authreq.split()[0]
if scheme.lower() == 'digest':
return self.retry_http_digest_auth(req, authreq)
这里的authreq是:
Basic realm="rets@tra.rets.interealty.com", Digest realm="rets@tra.rets.interealty.com",nonce="512f616ed13813817feddb4fb0ce9e2d",opaque="84f5e814-d38a-44b4-8239-3f5be6ee3153",qop="auth"
authreq.split()[0]将是“基本”,它永远不会是“摘要”,因此urllib2将不会在摘要认证中执行第二个请求。
基本上,urllib2假设只有一个身份验证可以在第一个401响应头中。不幸的是,这个服务器返回两种类型的身份验证。
要解决此问题,您可以使用基本身份验证,也可以使用“请求”等其他库。