2012-02-27 11 views
7

Ok, he estado trabajando duro en este solo durante demasiado tiempo. No he podido descifrarlo incluso con las horas pasadas en este y muchos otros sitios.¿La sesión de inicio de sesión no se transfiere a una nueva página web usando WebRequest/Response?

Básicamente, estoy tratando de quitar algunos datos de una página web detrás de una página de inicio de sesión usando WebRequest/Response. (He conseguido esto para trabajar usando un control WebBrowser con algunos eventos en capas que navegan a las diferentes páginas web pero está causando algunos problemas al tratar de refactorizar, sin mencionar que se ha dicho que usar una forma oculta para hacer el trabajo es ' . mala práctica')

Esto es lo que tengo:

 string formParams = string.Format("j_username={0}&j_password={1}", userName, userPass); 
     string cookieHeader; 

     WebRequest request = WebRequest.Create(_signInPage); 
     request.ContentType = "text/plain"; 
     request.Method = "POST"; 
     byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
     request.ContentLength = bytes.Length; 
     using (Stream os = request.GetRequestStream()) 
     { 
      os.Write(bytes, 0, bytes.Length); 
     } 
     WebResponse response = request.GetResponse(); 
     cookieHeader = response.Headers["Set-Cookie"]; 

     WebRequest getRequest = WebRequest.Create(sessionHistoryPage); 
     getRequest.Method = "GET"; 
     getRequest.Headers.Add("Cookie", cookieHeader); 
     WebResponse getResponse = getRequest.GetResponse(); 
     try 
     { 
      using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
      { 
       textBox1.AppendText(sr.ReadToEnd()); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
      throw; 
     } 

hasta ahora, soy capaz de llegar a la página correcta desde el primer eslabón pero cuando voy a la segunda, envía volver a la página de inicio de sesión como si no hubiera iniciado sesión.

El problema puede residir en que las cookies no obtienen c correctamente pero soy un principiante así que tal vez solo lo estoy haciendo mal. Captura las cookies enviadas desde el POST: JSESSIONID y S2V; sin embargo, cuando vamos a "GET", utilizando FireFox WebConsole, el navegador muestra que envía JSESSIONID, S2V y un SPRING_SECURITY_REMEMBER_ME_COOKIE, que creo que es la cookie utilizada cuando hago clic en el cuadro "Recordarme" en el formulario de inicio de sesión.

He intentado muchas maneras diferentes de hacer esto utilizando los recursos de SO, pero todavía tengo que llegar a la página que necesito. Entonces, por el bien del pelo que me queda, he decidido pedir ayuda en good ole SO. (Esta es una de esas cosas que no quiero dejar pasar - terca como esa a veces)

Si alguien quiere la dirección real del sitio en el que estoy intentando iniciar sesión, sería más que feliz de enviarlo a un par de personas en un mensaje privado.

código que tengo que reflejan una respuesta sugerida por Wal:

var request = (HttpWebRequest)WebRequest.Create(sessionHistoryPage); 
request.Credentials = new NetworkCredential(userName, userPass); 
request.CookieContainer = new CookieContainer(); 
request.PreAuthenticate = true; 


WebResponse getResponse = request.GetResponse(); 
try 
{ 
    using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
    { 
      textBox1.AppendText(sr.ReadToEnd()); 
    } 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
    throw; 
} 

Esta sugerencia, al menos la forma en que se implemente, no funcionó.

Como sugirió Krizz, cambié el código para usar CookieContainer y transferir las cookies de una solicitud a otra, sin embargo, la respuesta simplemente me devuelve la página de inicio de sesión original como si no hubiera iniciado sesión.

¿Hay sitios que simplemente NO permitirán este tipo de comportamiento?

Solución Final

La solución final fue propuesto por Adrian Iftode donde afirmó que el sitio web que estoy tratando de conectarse podría no permite tener una autenticación sin una sesión válida por lo que añadir un GET al comienzo del proceso me permitió obtener esa cookie.

Gracias por toda su ayuda, muchachos!

+0

Consejos prácticos para obtener Fiddler http://fiddler2.com y ver qué encabezados son enviados y recibidos por su navegador exactamente después de iniciar sesión. Luego emulé aquellos en su código C#. –

+0

@zespri He usado Fiddler anteriormente y, para ser honesto, en mi nivel actual de competencia de programación, se me ha pasado por la cabeza. Es algo en lo que estoy trabajando, pero no ayudó mucho y obtuve la misma información de la consola web de FireFox. – Josh

Respuesta

5

que estaba haciendo algún tipo de transferencia de cookies de un sitio web escrito en PHP. Es evidente que están pasando la cookie, pero tal vez es como en esa situación

var phpsessid = response.Headers["Set-Cookie"].Replace("; path=/", String.Empty); 

La cabecera Set-Cookie contiene otra información relacionada sobre la cookie y otros posibles instrucciones de otras cookies. Tenía una cookie con su información (Ruta), la identificación de la sesión que necesitaba enviar de vuelta al servidor para que el servidor supiera que soy el mismo cliente que hizo la solicitud GET.

La nueva solicitud tenía que incluir esta cookie

request.Headers["Cookie"] = phpsessid; 

Ya hace esto, pero asegúrese de que las cookies que recibe, le envió de nuevo al servidor.

Considerando la sesión y la autenticación, hay dos cookies, una para la sesión, otra para la autenticación y algunos servidores/aplicaciones pueden no permitir tener una autenticación sin una sesión válida. Lo que quiero decir es que también podría necesitar pasar la cookie de la sesión. Entonces los pasos serían:

  • Realice primero una solicitud GET para obtener la cookie de sesión.
  • A continuación, realice la solicitud POST para autenticar y obtener la cookie de autenticación.
  • Use ambas cookies para navegar a las páginas protegidas.

También compruebe this question, que no muestra toda la clase, pero la idea es mantener el CookieContainer en la misma clase, agregar las nuevas galletas de la POST/GET peticiones y asignarlos a la cada nueva petición, como @Krizz respondió.

+1

Esta fue la bala de plata. Después de algunas pruebas adicionales, descubrí que agregar el primer GET al código era el truco. Ni siquiera necesité cortar el "; path = /" de las cookies. Gracias hombre. – Josh

+1

Me aseguraré de otorgarle la recompensa después de 18 horas (el sitio no me permite hacerlo de inmediato). – Josh

1

Pruebe usar CookieContainer que es una clase para mantener el contexto de las cookies entre varias solicitudes. Simplemente crea una instancia de la misma y asígnala a cada WebRequest.

Por lo tanto, la modificación de su código:

string formParams = string.Format("j_username={0}&j_password={1}", userName, userPass); 
string cookieHeader; 

var cookies = new CookieContainer(); // added this line 

var request = WebRequest.Create(_signInPage) as HttpWebRequest; // modified line 
request.CookieContainer = cookies; // added this line 
request.ContentType = "text/plain"; 
request.Method = "POST"; 
byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
request.ContentLength = bytes.Length; 
using (Stream os = request.GetRequestStream()) 
{ 
    os.Write(bytes, 0, bytes.Length); 
} 

request.GetResponse(); // removed some code here, no need to read response manually 

var getRequest = WebRequest.Create(sessionHistoryPage) as HttpWebRequest; //modified line 
getRequest.CookieContainer = cookies; // added this line 
getRequest.Method = "GET"; 
WebResponse getResponse = getRequest.GetResponse(); 
try 
{ 
    using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
    { 
     textBox1.AppendText(sr.ReadToEnd()); 
    } 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
    throw; 
} 
+0

Supongo que tengo que cambiar a HttpWebResponse/Request porque WebResponse no tiene un CookieContainer? – Josh

+0

@Josh sí, tienes razón, código fijo – Krizz

Cuestiones relacionadas