Вопрос или проблема
Я работаю в корпоративной среде, где мне необходимо подключиться к внешнему серверу через прокси, используя Python. Прокси требует аутентификацию NTLM, и я постоянно сталкиваюсь с ошибкой 407 (Требуется аутентификация прокси), даже несмотря на то, что я настроил свой код на включение учетных данных. Я успешно подключался с использованием аналогичных настроек на C#, но Python оказывается более сложным.
Код возвращает ошибку 407 Требуется аутентификация прокси, что указывает на то, что мои учетные данные не принимаются прокси. Когда я дублирую запрос на C#, используя аналогичные учетные данные и настройки, я успешно аутентифицируюсь через прокси без проблем.
Ошибка:
HTTPSConnectionPool(host="target-host.com", port=443): Max retries exceeded with url: / (Caused by ProxyError('Unable to connect to proxy', OSError('Tunnel connection failed: 407 Proxy Authentication Required')))
Прокси работает нормально, когда я делаю запросы curl из командной строки с помощью следующей команды:
curl -v --proxy-negotiate -x http://proxy.com:port https://target-host.com/
Кто-нибудь знает, почему запросы могут не срабатывать здесь, когда curl работает нормально? Есть ли определенный подход в Python для обработки аутентификации NTLM/Negotiate через прокси, который я мог бы упустить?
Что я пробовал:
- Настроил requests_ntlm для обработки аутентификации NTLM через прокси.
- Указал переменные окружения HTTP_PROXY и HTTPS_PROXY в соответствии с корпоративными стандартами.
- Использовал requests-kerberos, requests-negotiate-sspi и requests-ntlm безуспешно и с той же ошибкой.
- Аутентифицировался с помощью requests следующим образом:
import requests
from requests.auth import HTTPBasicAuth
url = "https://target-host.com/"
return_obj = "-"
proxies = {
"http": "http://proxy.com:port",
"https": "http://proxy.com:port"
}
auth = HTTPBasicAuth('domain\\username', 'password')
try:
response = requests.get(url, proxies=proxies, auth=auth)
return_obj = response.text
print(f"Код состояния: {response.status_code}")
print(f"Тело ответа: {response.text}")
except requests.exceptions.RequestException as e:
# Обработка любых исключений (например, проблемы с сетью, тайм-ауты)
print(f"Произошла ошибка: {e}")
return return_obj
Системные и пакетные данные:
Python 3.9.13
requests-kerberos==0.15.0
requests-negotiate-sspi==0.5.2
requests_ntlm==1.3.0
ОС: Windows 11
Ответ или решение
Ошибка 407 Proxy Authentication Required в Python, несмотря на корректную настройку прокси
Ваша ситуация, связанная с ошибкой 407 Proxy Authentication Required при использовании Python для подключения через прокси с NTLM аутентификацией, на первый взгляд может показаться сложной, особенно если аналогичный подход работает в C#. Тем не менее, существует несколько нюансов, которые следует учесть для правильной работы с прокси и аутентификацией в Python.
1. Понимание ошибки 407
Ошибка 407 возникает, когда прокси-сервер требует аутентификацию перед предоставлением доступа к запрашиваемому ресурсу. В вашем случае, несмотря на то что вы используете правильные учетные данные, прокси может их не распознавать по нескольким причинам, связанным с особенностями аутентификационного протокола NTLM и используемыми библиотеками.
2. Убедитесь в корректности настроек прокси
Убедитесь, что конфигурация прокси правильно указана в вашем коде. Попробуйте явным образом задать настройки прокси в виде словарей, как вы уже сделали, но удостоверитесь, что используете правильный адрес и порт. Кроме того, важно проверить, требует ли ваш прокси-сервер для HTTP и HTTPS отдельные настройки.
3. Использование библиотеки requests
и необходимых модулей аутентификации
Для работы с NTLM аутентификацией через прокси необходимо использовать специализированные библиотеки, так как стандартная реализация requests
не поддерживает NTLM через прокси из коробки. Вы уже упоминали использование библиотек requests-ntlm
, requests-kerberos
, и requests-negotiate-sspi
, однако стоит убедиться, что вы применяете их правильным образом.
Вот пример, как можно подключиться к прокси с NTLM аутентификацией:
import requests
from requests_ntlm import HttpNtlmAuth
url = "https://target-host.com/"
proxy = {
"http": "http://proxy.com:port",
"https": "http://proxy.com:port"
}
# Убедитесь, что 'domain\\username' правильно задан
auth = HttpNtlmAuth('domain\\username', 'password')
try:
response = requests.get(url, proxies=proxy, auth=auth)
print(f"Статус код: {response.status_code}")
print(f"Тело ответа: {response.text}")
except requests.exceptions.RequestException as e:
print(f"Произошла ошибка: {e}")
4. Настройки окружения
Если вы работаете в корпоративной среде, важно установить переменные окружения HTTP_PROXY
и HTTPS_PROXY
с корректными значениями прокси. Это может повлиять на поведение библиотек, использующих системные настройки для маршрутизации HTTP-запросов.
5. Использование curl
как отправная точка
Вы упомянули успешное использование curl
с флагом --proxy-negotiate
. Это может указывать на то, что сервер ожидает другой тип аутентификации. Если requests
не работает, вы также можете попробовать использовать pycurl
, который предоставляет доступ к libcurl
и может быть более гибким при работе с аутентификацией.
6. Обновление библиотек
Убедитесь, что все используемые библиотеки обновлены до последних версий. Иногда проблемы с совместимостью и ошибками устраняются в новых релизах.
Заключение
Использование Python для доступа к ресурсам через прокси с аутентификацией может быть непростой задачей, особенно в корпоративной среде. Убедитесь, что вы правильно используете необходимые библиотеки и учитываете ограничения, связанные с NTLM аутентификацией. Если ни один из предложенных способов не работает, рассмотрите возможность обращения к администратору вашего прокси-сервера для получения дополнительной информации о возможных ограничениях или настройках, которые могут быть применены.