2011-02-03 2 views
8

Я ударяю головой о стену с этим. Я пробовал каждый пример, читая каждый последний бит, который я могу найти в Интернете, об основной авторизации http с urllib2, но я не могу понять, что вызывает мою конкретную ошибку.urllib2 basic authentication oddites

Добавление к разочарованию заключается в том, что код работает для одной страницы, но не для другого. Вход в www.mysite.com/adm идет абсолютно гладко. Он не аутентифицирует проблему. Тем не менее, если я изменить адрес для «http://mysite.com/adm/items.php?n=201105 & с = 200» Я получаю эту ошибку:

<h4 align="center" class="teal">Add/Edit Items</h4> 
<p><strong>Client:</strong> </p><p><strong>Event:</strong> </p><p class="error">Not enough information to complete this task</p> 

<p class="error">This is a fatal error so I am exiting now.</p> 

Поиск Google привела к нулевой информации о эта ошибка.

Администратор - это страница с рамкой, я не уверен, что это актуально вообще.

Вот текущий код:

import urllib2, urllib 
import sys 

import re 
import base64 
from urlparse import urlparse 

theurl = 'http://xxxxxmedia.com/adm/items.php?n=201105&c=200' 
username = 'XXXX' 
password = 'XXXX' 

passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 
passman.add_password(None, theurl,username,password) 

authhandler = urllib2.HTTPBasicAuthHandler(passman) 

opener = urllib2.build_opener(authhandler) 

urllib2.install_opener(opener) 

pagehandle = urllib2.urlopen(theurl) 

url = 'http://xxxxxxxmedia.com/adm/items.php?n=201105&c=200' 
values = {'AvAudioCD': 1, 
      'AvAudioCDDiscount': 00, 'AvAudioCDPrice': 50, 
      'ProductName': 'python test', 'frmSubmit': 'Submit' } 

#opener2 = urllib2.build_opener(urllib2.HTTPCookieProcessor()) 
data = urllib.urlencode(values) 
req = urllib2.Request(url, data) 
response = urllib2.urlopen(req) 

Это только один из многих вариантов, которые я пробовал. Я следовал за каждым примером из Urllib2 Missing Manual, но все же получал ту же ошибку.

Может ли кто-нибудь указать на то, что я делаю неправильно?

+1

Похоже, что ваш код работает, но не сайт, к которому вы подключаетесь. Работает ли он в браузере? Поскольку страница содержит фреймы, посмотрели ли вы на ее источник? –

+0

Да, это работает в браузере. Я проверил его источник с firebug. Сайт администратора отправляется на страницу html с этим кодом стиля: – Zack

+0

@jd Да, он работает в браузере. Я проверил его источник с firebug. Я не совсем уверен, что искать. Я заметил, что я могу аутентифицироваться с помощью python на каждой странице, кроме тех, которые имеют параметры в адресе IE. ..dia.com/ADM/items.php? п = 201105 & с = 200' . – Zack

ответ

2

Около года назад я прошел один и тот же процесс и задокументировал, как я решил проблему. Прямой и простой способ аутентификации и стандартный. Выберите то, что считаете нужным.

HTTP Authentication in Python

Существует объясняемое описание, в missing urllib2 document.

+0

Итак, после многих проводов, похоже, я на самом деле еще не аутентифицируюсь. попробовал все примеры в вашем связанном сообщении. Я скачал точный сценарий из пространства сайта ничтожного, но во время просмотра питона с Wireshark, я все еще получаю эту ошибку:

требуется авторизация

Этот сервер не может проверить, что вы уполномочены получить доступ к документу запрашивал. Либо вы указали неверные учетные данные (например, неверный пароль), либо ваш браузер не понимает, как предоставить требуемые учетные данные.

Любые идеи ..? – Zack

1

Из HTML, который вы отправили, он по-прежнему считает, что вы успешно прошли аутентификацию, но столкнулись с ошибкой после обработки вашего запроса POST. Я попробовал ваш URL и не прошел аутентификацию, я получил стандартную страницу 401.

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

+0

Кажется, вы правы. Это подтвердило ОК. Это просто неудача по другой причине. После его закрытия тег - это когда он выплевывает ошибку.Я установил Wireshark и наблюдал за различиями между запросами браузеров и запросами python. Честно говоря, я не совсем уверен в том, что я ищу. Но при подключении к python он выделял определенные кадры красным цветом, что, я думаю, плохое tcp .. Их около 6 из них: [TCP ZeroWindow] lbc-watchdog> http [ACK] Seq = 181. Может ли это быть причиной ошибки? И как я буду использовать эту информацию, чтобы исправить мою проблему ..? – Zack

+0

В Wireshark найдите один пакет TCP, который относится к правильному соединению (из адресов dst/src и порта), затем щелкните правой кнопкой мыши Follow TCP stream: есть HTTP-запрос вашего клиента и ответ сервера. –

3

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

Вот несколько вещей, которые вы можете использовать для отладки проблемы:

  1. я использовал slumber.in и httplib2 для целей тестирования. Я запустил оба из оболочки ipython, чтобы узнать, какие ответы я получаю.
  2. Снег фактически использует httplib2 под обложками, поэтому они действуют аналогично. Я использовал tcpdump и позже tcpflow (который показывает информацию в гораздо более читаемой форме), чтобы увидеть, что действительно отправлено и получено. Если вы хотите использовать графический интерфейс, см. Проводки или альтернативы.
  3. Я проверил свой сайт с завитом, и когда я использовал завиток с моим именем пользователя/паролем, он работал правильно и показал запрошенную страницу. Но сон и httplib2 все еще не работали.
  4. Я проверил свой сайт и browserspy.dk, чтобы узнать, в чем были отличия.Важно, что веб-сайт браузеров работает для базовой проверки подлинности, и мой веб-сайт этого не сделал, поэтому я мог сравнить их. Я читал во многих местах, которые вам нужно отправить HTTP 401 Not Authorized, чтобы браузер или инструмент, который вы используете, могли отправить имя пользователя/пароль, который вы указали. Но то, чего я не знал, вам также понадобилось поле WWW-Authenticate в заголовке. Так что это был недостающий кусок.
  5. То, что сделало всю эту ситуацию нечеткой, было при тестировании. Я бы увидел, что httplib2 отправляет основные заголовки аутентификации с большинством запросов (tcpflow покажет это). Оказывается, библиотека не отправляет аутентификацию имени пользователя и пароля по первому запросу. Если в ответе находится «Статус 401» и «WWW-Authenticate», учетные данные отправляются по второму запросу и все запросы в этот домен с этого момента.

Итак, ваше заявление может быть правильным, но вы можете не возвращать стандартные заголовки и код состояния для отправки клиентом учетных данных. Используйте инструменты отладки, чтобы найти, что есть. Кроме того, есть режим отладки для httplib2, просто установите httplib2.debuglevel=1, чтобы отладочная информация печаталась на стандартном выходе. Это гораздо полезнее, чем использование tcpdump, поскольку оно находится на более высоком уровне.

Надеюсь, это поможет кому-то.

+1

Если это правда, я думаю, вы, возможно, ответили на вопросы, которые я и многие пытались понять. Это именно то, что говорит [отсутствующий справочник urllib2] (http://www.voidspace.org.uk/python/articles/authentication.shtml#error-401-and-realms): 'В заголовки ответов будут включены быть «заголовком WWW-аутентификации», но я не получал его. Спасибо, что написали все на простом английском. В моем случае я пытался Github v2 api, который отправляет обратно 401, но он никогда не отправляет 'www-authenticate', поэтому Python urllib2 никогда не отправляет логин. –

0

Я также обнаружил, что материал passman не работает (иногда?). Добавление заголовка/пароля base64 в соответствии с этим ответом https://stackoverflow.com/a/18592800/623159 действительно сработало для меня. Я доступ к Дженкинс URL, как это: Http: /// работа // lastCompletedBuild/testR ОКЛАД/API/питон

Это работает для меня:

import urllib2 
import base64 

baseurl="http://jenkinsurl" 
username=... 
password=... 

url="%s/job/jobname/lastCompletedBuild/testReport/api/python" % baseurl 

base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') 
request = urllib2.Request(url) 
request.add_header("Authorization", "Basic %s" % base64string) 
result = urllib2.urlopen(request) 
data = result.read() 

Это не работает для меня , ошибка 403 каждый раз:

import urllib2 

baseurl="http://jenkinsurl" 
username=... 
password=... 

##urllib2.HTTPError: HTTP Error 403: Forbidden 
passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 
passman.add_password(None, url, username,password) 
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPBasicAuthHandler(passman))) 
req = urllib2.Request(url) 
result = urllib2.urlopen(req) 
data = result.read()