2011-02-03 20 views
8

Estoy golpeando mi cabeza contra la pared con este. He estado probando cada ejemplo, leyendo hasta el último bit que puedo encontrar en línea sobre la autorización http básica con urllib2, pero no puedo entender qué está causando mi error específico.urllib2 autenticación básica oddites

Además de la frustración, el código funciona para una página, pero no para otra. iniciando sesión en www.misitio.com/adm va absolutamente sin problemas. No autentica ningún problema. Sin embargo, si cambio de la dirección a 'http://mysite.com/adm/items.php?n=201105 & c = 200' que recibo este error:

<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> 

búsqueda Google ha llevado a cero en la información este error.

La adm es una página de conjunto de marcos, no estoy seguro si eso es relevante en absoluto.

Aquí está el código actual:

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) 

Ésta es sólo una de las muchas versiones que he probado. He seguido todos los ejemplos de Urllib2 Missing Manual pero aún recibo el mismo error.

¿Alguien puede señalar lo que estoy haciendo mal?

+1

Parece que su código funciona, pero no el sitio al que se está conectando. ¿Funciona en un navegador? Como la página contiene marcos, ¿ha mirado su origen? –

+0

Sí, funciona en el navegador. He revisado su fuente con Firebug. El sitio de administración va a la página html con este código de estilo: – Zack

+0

@jd Sí, funciona en el navegador. He revisado su fuente con Firebug. No estoy del todo seguro de lo que estoy buscando. Me di cuenta de que puedo autenticar con Python en todas las páginas, excepto las que tienen parámetros en la dirección IE. ..dia.com/adm/items.php? n = 201105 & c = 200 '. – Zack

Respuesta

2

Hace aproximadamente un año, pasé por el mismo proceso y documenté cómo resolví el problema: la forma directa y simple de autenticación y la estándar. Elija lo que considere apropiado.

HTTP Authentication in Python

Hay una descripción explicado, en el missing urllib2 document.

+0

Así que, después de mucho wireharking resulta que en realidad todavía no estoy autenticando .. He intenté todos los ejemplos en su publicación vinculada. He descargado el guión exacto de la página web espacio vacío, sin embargo, mientras se ve pitón con wireshark, sigo teniendo este error: Se requiere autorización

Este servidor no ha podido comprobar que está autorizado para acceder al documento solicitado. O bien proporcionó las credenciales incorrectas (por ejemplo, una contraseña incorrecta) o su navegador no entiende cómo proporcionar las credenciales requeridas.

¿Alguna idea ...? – Zack

1

Desde el código HTML que publicó, todavía cree que se autentica correctamente pero se encuentra con un error después, en el procesamiento de su solicitud POST. Intenté su URL y la autenticación fallida. Obtengo una página estándar de 401.

En cualquier caso, le sugiero que intente de nuevo ejecutando su código y realizando la misma operación manualmente en Firefox, solo que esta vez con Wireshark para capturar el intercambio. Puede tomar el texto completo de la solicitud y respuesta HTTP en ambos casos y comparar las diferencias. En la mayoría de los casos eso te llevará a la fuente del error que obtienes.

+0

Parece que tienes razón. Estaba autenticando bien. Simplemente está fallando por alguna otra razón. Después de que se cierra, la etiqueta es cuando escupe el error.Instalé Wireshark y observé las diferencias entre las solicitudes del navegador y las solicitudes de Python. Honestamente, no estoy del todo seguro de lo que estoy buscando ... Pero cuando me conecté con Python resaltó ciertos fotogramas en rojo, lo que supongo que es un tcp incorrecto. Hay aproximadamente 6 de estos en una fila: [TCP ZeroWindow] lbc-watchdog> http [ACK] Seq = 181. ¿Podría ser esto lo que está causando el error? ¿Y cómo usaría esta información para corregir mi problema ...? – Zack

+0

En Wireshark, busque un paquete tcp que pertenezca a la conexión correcta (desde direcciones y puerto dst/src), luego haga clic con el botón derecho en Seguir secuencia TCP: está la solicitud HTTP de su cliente y la respuesta del servidor. –

3

Corre en un problema similar hoy. Estaba usando la autenticación básica en el sitio web que estoy desarrollando y no pude autenticar a ningún usuario.

Aquí están algunas cosas que usted puede utilizar para depurar el problema:

  1. que utilicé slumber.in y httplib2 para propósitos de prueba. Ejecuté ambos desde el shell ipython para ver qué respuestas estaba recibiendo.
  2. Slumber en realidad usa httplib2 debajo de las cubiertas para que actúen de manera similar. Usé tcpdump y luego tcpflow (que muestra información en una forma mucho más legible) para ver lo que realmente se estaba enviando y recibiendo. Si desea una GUI, consulte wireshark o alternativas.
  3. Probé mi sitio web con curl y cuando usé curl con mi nombre de usuario/contraseña funcionó correctamente y se mostró la página solicitada. Pero el sueño y httplib2 todavía no funcionaban.
  4. Probé mi sitio web y browserspy.dk para ver cuáles eran las diferencias.Lo importante es que el sitio web de browserspy funciona para la autenticación básica y mi sitio web no, por lo que podría comparar entre los dos. Leí en muchos lugares que necesita enviar HTTP 401 No autorizado para que el navegador o la herramienta que está utilizando puedan enviar el nombre de usuario/contraseña que proporcionó. Pero lo que no sabía era que también necesitabas el campo WWW-Authenticate en el encabezado. Entonces esta era la pieza que faltaba.
  5. Lo que hizo que toda esta situación fuera extraña fue durante la prueba, vi que httplib2 enviaba encabezados básicos de autenticación con la mayoría de las solicitudes (tcpflow lo mostraría). Resulta que la biblioteca no envía autenticación de nombre de usuario/contraseña en la primera solicitud. Si "Estado 401" AND "WWW-Autentica" está en la respuesta, entonces las credenciales se envían en la segunda solicitud y todas las solicitudes a este dominio a partir de ese momento.

En resumen, su aplicación puede ser correcta pero es posible que no devuelva los encabezados estándar y el código de estado para que el cliente envíe las credenciales. Use sus herramientas de depuración para encontrar cuál es cuál. Además, hay modo de depuración para httplib2, simplemente configure httplib2.debuglevel=1 para que la información de depuración se imprima en la salida estándar. Esto es mucho más útil que utilizar tcpdump porque está en un nivel superior.

Espero que esto ayude a alguien.

+1

Si esto es cierto, creo que es posible que haya respondido a las preguntas que yo y tantos hemos intentado comprender. Esto es exactamente lo que el [manual de urllib2 que faltaba] (http://www.voidspace.org.uk/python/articles/authentication.shtml#error-401-and-realms) está diciendo aquí: 'Incluido en los encabezados de respuesta se ser un encabezado 'WWW-authenticate'. pero no lo conseguía. Gracias por deletrearlo todo en inglés simple. En mi caso, estaba probando la API de Github v2, que envía de vuelta 401, pero nunca devuelve 'www-authenticate', por lo que Python urllib2 nunca envía el inicio de sesión. –

0

También encontré que las cosas del passman no funcionan (a veces?). Agregar el encabezado user/pass de base64 según esta respuesta https://stackoverflow.com/a/18592800/623159 funcionó para mí. Yo soy el acceso a Jenkins URL como esta: http: // /// trabajo lastCompletedBuild/testr nforme/api/pitón

Esto funciona para mí:

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() 

Esto no funciona para mí , error 403 cada vez:

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() 
Cuestiones relacionadas