2012-01-15 30 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個響應頭中。不幸的是,這臺服務器返回兩種認證。

要解決此問題,可以使用基本身份驗證,也可以使用其他庫,如「請求」。

相關問題