Просмотр веб-сайта, защищенного NTLM, с использованием python с python NTLM

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

После безуспешного использования urllib2 (я пытаюсь сделать это на python) для подключения и около 4 или 5 часов поиска в Google я определил, что причина, по которой я не могу подключиться, связана с аутентификацией NTLM на веб-странице. Я пробовал кучу разных процессов для подключения, найденных на этом сайте и других, но безрезультатно. На основе примера NTLM я сделал следующее:

import urllib2
from ntlm import HTTPNtlmAuthHandler

user = 'username'
password = "password"
url = "https://portal.whatever.com/"

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, url, user, password)
# create the NTLM authentication handler
auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman)

# create and install the opener
opener = urllib2.build_opener(auth_NTLM)
urllib2.install_opener(opener)

# create a header
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
header = { 'Connection' : 'Keep-alive', 'User-Agent' : user_agent}

response = urllib2.urlopen(urllib2.Request(url, None, header))

Когда я запускаю это (с реальным именем пользователя, паролем и URL-адресом), я получаю следующее:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ntlm2.py", line 21, in <module>
    response = urllib2.urlopen(urllib2.Request(url, None, header))
  File "C:\Python27\lib\urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "C:\Python27\lib\urllib2.py", line 400, in open
    response = meth(req, response)
  File "C:\Python27\lib\urllib2.py", line 513, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python27\lib\urllib2.py", line 432, in error
    result = self._call_chain(*args)
  File "C:\Python27\lib\urllib2.py", line 372, in _call_chain
    result = func(*args)
  File "C:\Python27\lib\urllib2.py", line 619, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "C:\Python27\lib\urllib2.py", line 400, in open
    response = meth(req, response)
  File "C:\Python27\lib\urllib2.py", line 513, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python27\lib\urllib2.py", line 432, in error
    result = self._call_chain(*args)
  File "C:\Python27\lib\urllib2.py", line 372, in _call_chain
    result = func(*args)
  File "C:\Python27\lib\urllib2.py", line 619, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "C:\Python27\lib\urllib2.py", line 400, in open
    response = meth(req, response)
  File "C:\Python27\lib\urllib2.py", line 513, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python27\lib\urllib2.py", line 438, in error
     return self._call_chain(*args)
  File "C:\Python27\lib\urllib2.py", line 372, in _call_chain
     result = func(*args)
  File "C:\Python27\lib\urllib2.py", line 521, in http_error_default
     raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
  urllib2.HTTPError: HTTP Error 401: Unauthorized

Самое интересное в этой трассировке для меня то, что последняя строка говорит об ошибке 401, которая была отправлена ​​обратно. Из того, что я прочитал, ошибка 401 — это первое сообщение, отправленное клиенту. при запуске NTLM. У меня сложилось впечатление, что цель python-ntml заключалась в том, чтобы обрабатывать процесс NTLM для меня. Это неправильно или я просто неправильно его использую? Кроме того, я не обязан использовать для этого python, поэтому, если есть более простой способ сделать это на другом языке, дайте мне знать (из того, что я видел в гугле, нет). Спасибо!


person jias    schedule 21.06.2011    source источник
comment
401 — это первый ответ, отправленный обратно для инициации проверки подлинности NTLM/Negotiate. Но это также окончательный ответ, когда ваша аутентификация не удалась. Вы уверены, что сервер поддерживает аутентификацию NTLM? Часто это отключено, и поддерживается только аутентификация Negotiate (также известная как SPNEGO или Kerberos).   -  person Edward Thomson    schedule 21.06.2011
comment
Так что это может быть другой тип (Kerberos?). Если подумать, когда я пытался получить к нему доступ другим способом, он всегда говорил «Переговоры» в поле WWWWAuthenticate, взятом из заголовка. Знаете ли вы, есть ли какая-либо поддержка Kerberos?   -  person jias    schedule 21.06.2011
comment
Таким образом, заголовки аутентификации в основном представляют собой только входные и выходные значения base64 для вызовов GSSAPI. Может помочь что-то вроде python-krb5 fedorahosted.org/python-krbV. Но если вы еще не применяете kerberos на своем сайте, это может стать совершенно новым червем. Вы можете попытаться убедиться, что в IIS включен NTLM: support.microsoft.com/kb/215383< /а>   -  person Edward Thomson    schedule 21.06.2011
comment
Да, может быть, но в любом случае спасибо за помощь, я начну изучать этот материал.   -  person jias    schedule 21.06.2011


Ответы (1)


Если сайт использует аутентификацию NTLM, атрибут заголовков результирующего HTTPError должен указывать следующее:

>>> try:
...   handle = urllib2.urlopen(req)
... except IOError, e:
...   print e.headers
... 
<other headers>
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
person SeanB    schedule 15.02.2013