2012-01-15 48 views
0

我正在使用urllib2。 我有问题登录一个服务器返回基本和摘要认证。是否urllib2支持返回基本和摘要认证的服务器

返回:

 
WWW-Authenticate: Digest realm="[email protected]",nonce="c068c3d7d30cc0cd80db4d1c599e6d54",opaque="e75078c8-a825-474b-b101-f8ca2d1627ca",qop="auth" 
WWW-Authenticate: Basic realm="[email protected]" 

这里是我的代码:

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

我还没有遇到同样的问题,但曾经惊讶地发现urllib2.HTTPBasicAuthHandler的开瓶器实际上使两个请求,而不是一个:第一个没有认证,然后第二个与验证后退。

也就是说,您的情况可能需要三个请求,其中第三个请求可能会忘记第二个请求的验证 - 应该检查。

而你应该把两个:urllib2.HTTPDigestAuthHandlerurllib2.HTTPBasicAuthHandler添加到开启者。

+0

我试着添加urllib2.HTTPDigestAuthHandler和urllib2.HTTPBasicAuthHandler,它不起作用。 我可以通过简单添加一个头来登录这个服务器: base64string = base64.encodestring('%s:%s'%(retsUSER,retsPWD))[: - 1] retsRequest.add_header(“Authorization”,“Basic% s“%base64string) 所以我决定选择这种方式。 – suyugo 2012-01-16 04:29:12

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="[email protected]", Digest realm="[email protected]",nonce="512f616ed13813817feddb4fb0ce9e2d",opaque="84f5e814-d38a-44b4-8239-3f5be6ee3153",qop="auth" 

authreq.split()[0]将是 “基本”,它永远不会被 “消化”,这样的urllib2不会做第二在摘要认证中请求。

基本上urllib2假定只有一个身份验证可以在第401个响应头中。不幸的是,这台服务器返回两种认证。

要解决此问题,可以使用基本身份验证,也可以使用其他库,如“请求”。

相关问题