Поддерживает ли urllib2 сервер, который возвращает как базовую, так и дайджест-аутентификацию - PullRequest
0 голосов
/ 15 января 2012

Я использую 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 использует дайджест-аутентификацию.

Ответы [ 2 ]

0 голосов
/ 24 июня 2013

В последнее время у меня есть время, чтобы рассмотреть этот вопрос, я думаю, что нашел ответ. Это своего рода ошибка Python urllib2. В 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] будет "Basic", никогда не будет "digest", поэтому urllib2 не будет выполнять второй запрос в дайджест-аутентификации.

Обычно urllib2 предполагает, что в первом заголовке ответа 401 может быть только одна аутентификация. К сожалению, этот сервер возвращает два типа аутентификации.

Чтобы решить эту проблему, вы можете использовать обычную аутентификацию или другую библиотеку, например «запросы».

0 голосов
/ 15 января 2012

Я не сталкивался с той же проблемой, но однажды был удивлен, когда узнал, что открывающая программа с urllib2.HTTPBasicAuthHandler фактически делает два запроса вместо одного: первый без аутентификации, а затем как запасной второй с аутентификацией.

То есть может оказаться, что в вашем случае потребуются три запроса, при этом третий запрос может забыть аутентификацию второго - нужно проверить.

И вам, вероятно, следует добавить и: urllib2.HTTPDigestAuthHandler, иurllib2.HTTPBasicAuthHandler к открывателю.

...