He intentado automatizar un inicio de sesión en un sitio web que frecuento, www.bungie.net. El sitio está asociado con Microsoft y Xbox Live, y como tal hace uso de la API de Windows Live ID cuando las personas inician sesión en su sitio.Inicio de sesión en un sitio que usa la autenticación de Live.com
Soy relativamente nuevo en la creación de arañas web/robots, y me preocupa no entender bien algunos de los conceptos más básicos. He simulado inicios de sesión en otros sitios como Facebook y Gmail, pero live.com no me ha dado más que problemas.
De todos modos, he estado usando Wireshark y el complemento de Firefox Tamper Data para tratar de averiguar qué necesito publicar y qué cookies debo incluir con mis solicitudes. Hasta donde yo sé, estos son los pasos que uno debe seguir para iniciar sesión en este sitio.
1. Visita https: //login.live.com/login.srf?wa=wsignin1.0 & rpsnv = 11 & ct = 1268167141 & rver = 5.5.4177.0 & wp = LBI & Wreply = http :% 2F% 2Fwww.bungie.net% 2FDefault.aspx & id = 42917
2. recibir las galletas MSPRequ y MSPOK.
3. Publica los valores de la forma de identificación "PPSX", los valores de la forma de identificación "PPFT", su nombre de usuario, la contraseña sólo a una URL similar a cambiar: https: //login.live. com/ppsecure/post.srf? wa = wsignin1.0 & rpsnv = 11 & ct = (hay algunos números que cambian al final de la URL)
4. Live.com devuelve al usuario una página con más formas ocultas para publicar. El cliente luego publica los valores del formulario "ANON", el valor de la forma "ANONExp" y los valores de la forma "t" a la URL: http: //www.bung ie.net/Default.aspx?wa = wsignin1.0
5. Después de publicar esos datos, el usuario recibe una variedad de cookies, la más importante de las cuales es "BNGAuth", que es la cookie de inicio de sesión del sitio.
Donde estoy teniendo problemas está en el quinto paso, pero eso no necesariamente significa que he hecho todos los demás pasos correctamente. Publiqué los datos de "ANON", "ANONExp" y "t" pero, en lugar de devolverme una cookie BNGAuth, recibí una cookie llamada "RSPMaybe" y la redirigí a la página de inicio.
Cuando reviso el registro de Wireshark, noté algo que al instante me llamó la atención como diferente entre el registro cuando entré con Firefox y cuando se ejecutó mi programa. No podría ser nada , pero incluiré la imagen aquí para que revise. Me devuelven un paquete HTTP del sitio antes de publicar los datos en el cuarto paso. No estoy seguro de cómo está sucediendo esto, pero debe ser un efecto secundario de algo que estoy haciendo mal en los pasos de HTTPS.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Net;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Web;
namespace SpiderFromScratch
{
class Program
{
static void Main(string[] args)
{
CookieContainer cookies = new CookieContainer();
Uri url = new Uri("https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=11&ct=1268167141&rver=5.5.4177.0&wp=LBI&wreply=http:%2F%2Fwww.bungie.net%2FDefault.aspx&id=42917");
HttpWebRequest http = (HttpWebRequest)HttpWebRequest.Create(url);
http.Timeout = 30000;
http.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729)";
http.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
http.Headers.Add("Accept-Language", "en-us,en;q=0.5");
http.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
http.Headers.Add("Keep-Alive", "300");
http.Referer = "http://www.bungie.net/";
http.ContentType = "application/x-www-form-urlencoded";
http.CookieContainer = new CookieContainer();
http.Method = WebRequestMethods.Http.Get;
HttpWebResponse response = (HttpWebResponse)http.GetResponse();
StreamReader readStream = new StreamReader(response.GetResponseStream());
string HTML = readStream.ReadToEnd();
readStream.Close();
//gets the cookies (they are set in the eighth header)
string[] strCookies = response.Headers.GetValues(8);
response.Close();
string name, value;
Cookie manualCookie;
for (int i = 0; i < strCookies.Length; i++)
{
name = strCookies[i].Substring(0, strCookies[i].IndexOf("="));
value = strCookies[i].Substring(strCookies[i].IndexOf("=") + 1, strCookies[i].IndexOf(";") - strCookies[i].IndexOf("=") - 1);
manualCookie = new Cookie(name, "\"" + value + "\"");
Uri manualURL = new Uri("http://login.live.com");
http.CookieContainer.Add(manualURL, manualCookie);
}
//stores the cookies to be used later
cookies = http.CookieContainer;
//Get the PPSX value
string PPSX = HTML.Remove(0, HTML.IndexOf("PPSX"));
PPSX = PPSX.Remove(0, PPSX.IndexOf("value") + 7);
PPSX = PPSX.Substring(0, PPSX.IndexOf("\""));
//Get this random PPFT value
string PPFT = HTML.Remove(0, HTML.IndexOf("PPFT"));
PPFT = PPFT.Remove(0, PPFT.IndexOf("value") + 7);
PPFT = PPFT.Substring(0, PPFT.IndexOf("\""));
//Get the random URL you POST to
string POSTURL = HTML.Remove(0, HTML.IndexOf("https://login.live.com/ppsecure/post.srf?wa=wsignin1.0&rpsnv=11&ct="));
POSTURL = POSTURL.Substring(0, POSTURL.IndexOf("\""));
//POST with cookies
http = (HttpWebRequest)HttpWebRequest.Create(POSTURL);
http.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729)";
http.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
http.Headers.Add("Accept-Language", "en-us,en;q=0.5");
http.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
http.Headers.Add("Keep-Alive", "300");
http.CookieContainer = cookies;
http.Referer = "https://login.live.com/login.srf?wa=wsignin1.0&rpsnv=11&ct=1268158321&rver=5.5.4177.0&wp=LBI&wreply=http:%2F%2Fwww.bungie.net%2FDefault.aspx&id=42917";
http.ContentType = "application/x-www-form-urlencoded";
http.Method = WebRequestMethods.Http.Post;
Stream ostream = http.GetRequestStream();
//used to convert strings into bytes
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
//Post information
byte[] buffer = encoding.GetBytes("PPSX=" + PPSX +"&PwdPad=IfYouAreReadingThisYouHaveTooMuc&login=YOUREMAILGOESHERE&passwd=YOURWORDGOESHERE" +
"&LoginOptions=2&PPFT=" + PPFT);
ostream.Write(buffer, 0, buffer.Length);
ostream.Close();
HttpWebResponse response2 = (HttpWebResponse)http.GetResponse();
readStream = new StreamReader(response2.GetResponseStream());
HTML = readStream.ReadToEnd();
response2.Close();
ostream.Dispose();
foreach (Cookie cookie in response2.Cookies)
{
Console.WriteLine(cookie.Name + ": ");
Console.WriteLine(cookie.Value);
Console.WriteLine(cookie.Expires);
Console.WriteLine();
}
//SET POSTURL value
string POSTANON = "http://www.bungie.net/Default.aspx?wa=wsignin1.0";
//Get the ANON value
string ANON = HTML.Remove(0, HTML.IndexOf("ANON"));
ANON = ANON.Remove(0, ANON.IndexOf("value") + 7);
ANON = ANON.Substring(0, ANON.IndexOf("\""));
ANON = HttpUtility.UrlEncode(ANON);
//Get the ANONExp value
string ANONExp = HTML.Remove(0, HTML.IndexOf("ANONExp"));
ANONExp = ANONExp.Remove(0, ANONExp.IndexOf("value") + 7);
ANONExp = ANONExp.Substring(0, ANONExp.IndexOf("\""));
ANONExp = HttpUtility.UrlEncode(ANONExp);
//Get the t value
string t = HTML.Remove(0, HTML.IndexOf("id=\"t\""));
t = t.Remove(0, t.IndexOf("value") + 7);
t = t.Substring(0, t.IndexOf("\""));
t = HttpUtility.UrlEncode(t);
//POST the Info and Accept the Bungie Cookies
http = (HttpWebRequest)HttpWebRequest.Create(POSTANON);
http.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729)";
http.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
http.Headers.Add("Accept-Language", "en-us,en;q=0.5");
http.Headers.Add("Accept-Encoding", "gzip,deflate");
http.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
http.Headers.Add("Keep-Alive", "115");
http.CookieContainer = new CookieContainer();
http.ContentType = "application/x-www-form-urlencoded";
http.Method = WebRequestMethods.Http.Post;
http.Expect = null;
ostream = http.GetRequestStream();
int test = ANON.Length;
int test1 = ANONExp.Length;
int test2 = t.Length;
buffer = encoding.GetBytes("ANON=" + ANON +"&ANONExp=" + ANONExp + "&t=" + t);
ostream.Write(buffer, 0, buffer.Length);
ostream.Close();
//Here lies the problem, I am not returned the correct cookies.
HttpWebResponse response3 = (HttpWebResponse)http.GetResponse();
GZipStream gzip = new GZipStream(response3.GetResponseStream(), CompressionMode.Decompress);
readStream = new StreamReader(gzip);
HTML = readStream.ReadToEnd();
//gets both cookies
string[] strCookies2 = response3.Headers.GetValues(11);
response3.Close();
}
}
}
Solo un lado ... otra gran herramienta para mirar el cable es Fiddler. No estoy seguro de qué tan bien se acumula el wireshark, pero uno podría atrapar algo (¿https?) Y el otro no. – Will
Tendré que verificarlo, filtré el tráfico SSL en este simplemente para ilustrar la perculiaridad que noté. La forma en que C# maneja SSL es definitivamente diferente a la forma en que Firefox lo maneja, y esa podría ser también la fuente de mis problemas. Parece que cada vez que realizo una solicitud a una nueva página usando SSL y C#, tiene que volver a autenticarse. No tengo suficiente experiencia en esta área para saber si eso sería un problema o no. – JoshVarty
Puedo recomendar también usar el complemento de Firefox llamado Firebug, luego usar la pestaña de la consola con la opción "Persistir". Puede ver las solicitudes y respuestas detalladas para el proceso de autenticación de Live.com. – ReinierDG