web-dev-qa-db-fra.com

Comment passer l'authentification par proxy (nécessite une authentification par résumé) en utilisant python module de requêtes

J'utilisais le module Mechanize il y a quelque temps et j'essaie maintenant d'utiliser le module Requests.
( la mécanisation Python ne fonctionne pas lorsque l'authentification HTTPS et proxy est requise )

Je dois passer par un serveur proxy lorsque j'accède à Internet.
Le serveur proxy nécessite une authentification. J'ai écrit les codes suivants.

import requests
from requests.auth import HTTPProxyAuth

proxies = {"http":"192.168.20.130:8080"}
auth = HTTPProxyAuth("username", "password")

r = requests.get("http://www.google.co.jp/", proxies=proxies, auth=auth)

Les codes ci-dessus fonctionnent bien lorsque le serveur proxy nécessite une authentification de base.
Maintenant, je veux savoir ce que je dois faire lorsque le serveur proxy requiert une authentification Digest.
HTTPProxyAuth ne semble pas être efficace dans l'authentification Digest (r.status_code renvoie 407).

17
yutaka2487

J'ai écrit la classe qui peut être utilisée dans l'authentification proxy (basée sur l'authentification Digest).
J'ai emprunté presque tous les codes à request.auth.HTTPDigestAuth.

import requests
import requests.auth

class HTTPProxyDigestAuth(requests.auth.HTTPDigestAuth):
    def handle_407(self, r):
        """Takes the given response and tries digest-auth, if needed."""

        num_407_calls = r.request.hooks['response'].count(self.handle_407)

        s_auth = r.headers.get('Proxy-authenticate', '')

        if 'digest' in s_auth.lower() and num_407_calls < 2:

            self.chal = requests.auth.parse_dict_header(s_auth.replace('Digest ', ''))

            # Consume content and release the original connection
            # to allow our new request to reuse the same one.
            r.content
            r.raw.release_conn()

            r.request.headers['Authorization'] = self.build_digest_header(r.request.method, r.request.url)
            r.request.send(anyway=True)
            _r = r.request.response
            _r.history.append(r)

            return _r

        return r

    def __call__(self, r):
        if self.last_nonce:
            r.headers['Proxy-Authorization'] = self.build_digest_header(r.method, r.url)
        r.register_hook('response', self.handle_407)
        return r

Usage:

proxies = {
    "http" :"192.168.20.130:8080",
    "https":"192.168.20.130:8080",
}
auth = HTTPProxyDigestAuth("username", "password")

# HTTP
r = requests.get("http://www.google.co.jp/", proxies=proxies, auth=auth)
r.status_code # 200 OK

# HTTPS
r = requests.get("https://www.google.co.jp/", proxies=proxies, auth=auth)
r.status_code # 200 OK
10
yutaka2487

Pas besoin d'implémenter le vôtre! dans la plupart des cas

Requests a intégré la prise en charge des proxys, pour l'authentification de base:

proxies = { 'https' : 'https://user:password@proxyip:port' } 
r = requests.get('https://url', proxies=proxies) 

voir plus sur le docs

Ou si vous avez besoin d'une authentification Digest, HTTPDigestAuth peut vous aider.
Ou vous pourriez avoir besoin de l'étendre comme yutaka2487 l'a fait ci-dessous.

Remarque: doit utiliser l'IP du serveur proxy et non son nom!

17
eusoubrasileiro
import requests
import os


# in my case I had to add my local domain
proxies = {
  'http': 'proxy.myagency.com:8080',
  'https': 'user@localdomain:[email protected]:8080',
}


r=requests.get('https://api.github.com/events', proxies=proxies)
print(r.text)
1
Odysseus Ithaca

Pour ceux d'entre vous qui finissent toujours ici, il semble y avoir un projet appelé requêtes-toolbelt qui a cela ainsi que d'autres fonctionnalités communes mais non intégrées des demandes.

https://toolbelt.readthedocs.org/en/latest/authentication.html#httpproxydigestauth

1
pcreech

Vous pouvez utiliser l'authentification Digest en utilisant requests.auth.HTTPDigestAuth au lieu de requests.auth.HTTPProxyAuth

0
barracel

Voici une réponse qui n'est pas pour l'authentification de base http - par exemple un proxy transparent au sein de l'organisation.

import requests

url      = 'https://someaddress-behindproxy.com'
params   = {'apikey': '123456789'}                     #if you need params
proxies  = {'https': 'https://proxyaddress.com:3128'}  #or some other port
response = requests.get(url, proxies=proxies, params=params)

J'espère que ça aidera quelqu'un.

0
Belial

J'ai écrit un Python (disponible ici ) qui permet de s'authentifier avec un proxy HTTP en utilisant le schéma de résumé. Il fonctionne lors de la connexion à des sites Web HTTPS ( via le patch de singe) et permet également de s'authentifier auprès du site Web. Cela devrait fonctionner avec la dernière bibliothèque requests pour les deux Python 2 et 3).

L'exemple suivant récupère la page Web https://httpbin.org/ip via le proxy HTTP 1.2.3.4:8080 qui nécessite une authentification HTTP digest à l'aide du nom d'utilisateur user1 et mot de passe password1:

import requests
from requests_digest_proxy import HTTPProxyDigestAuth

s = requests.Session()
s.proxies = {
        'http': 'http://1.2.3.4:8080/',
        'https': 'http://1.2.3.4:8080/'
}
s.auth = HTTPProxyDigestAuth(('user1', 'password1'))

print(s.get('https://httpbin.org/ip').text)

Si le site Web nécessite une sorte d'authentification HTTP, cela peut être spécifié au constructeur HTTPProxyDigestAuth de cette façon:

# HTTP Basic authentication for website
s.auth = HTTPProxyDigestAuth(('user1', 'password1'),
        auth=requests.auth.HTTPBasicAuth('user1', 'password0'))
print(s.get('https://httpbin.org/basic-auth/user1/password0').text))

# HTTP Digest authentication for website
s.auth = HTTPProxyDigestAuth(('user1', 'password1'),,
        auth=requests.auth.HTTPDigestAuth('user1', 'password0'))
print(s.get('https://httpbin.org/digest-auth/auth/user1/password0').text)
0
Tey'