2010-03-24 28 views
12

Ich habe versucht, eine Anmeldung bei einer Website zu automatisieren, die ich häufig verwende, www.bungie.net. Die Site ist mit Microsoft und Xbox Live verknüpft und verwendet daher die Windows Live ID-API, wenn sich Benutzer bei ihrer Site anmelden.Anmelden bei einer Website mit Live.com-Authentifizierung

Ich bin relativ neu in der Erstellung von Web-Spinnen/Roboter, und ich mache mir Sorgen, dass ich einige der grundlegendsten Konzepte missverstehen. Ich habe Logins auf anderen Seiten wie Facebook und Gmail simuliert, aber live.com hat mir nur Ärger gemacht.

Wie auch immer, ich habe Wireshark und das Firefox-Addon Tamper Data verwendet, um herauszufinden, was ich posten muss und welche Cookies ich in meine Anfragen aufnehmen muss. Soweit ich weiß, sind dies die Schritte, die man befolgen muss, um sich auf dieser Seite einzuloggen.

1. Besuchen Sie 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. Recieve die Cookies MSPRequ und MSPOK.

3. Geben Sie die Werte aus dem Formular-ID „PPSX“, die Werte aus dem Formular-ID „PPFT“, Ihren Benutzernamen, Ihr Passwort alle an eine sich verändernde URL ähnelt: https: //login.live. com/ppsecure/post.srf? wa = wsignin1.0 & rpsnv = 11 & ct = (es gibt ein paar Zahlen, die am Ende dieser URL ändern)

4. Live.com den Benutzer zurückgibt eine Seite mit mehr versteckten Formen zum Posten. Der Client bucht dann die Werte aus der Form "ANON", den Wert aus der Form "ANONExp" und die Werte aus der Form "t" auf die URL: http: //www.bung ie.net/Default.aspx?wa = wsignin1.0

5. Nach der Veröffentlichung dieser Daten gibt der Benutzer eine Vielzahl von Cookies zurück, von denen die wichtigste "BNGAuth" ist, welches der Login-Cookie für die Site ist.

Wo ich Probleme habe ist im fünften Schritt, aber das bedeutet nicht unbedingt, dass ich alle anderen Schritte richtig gemacht habe. Ich poste die Daten von "ANON", "ANONExp" und "t", aber anstatt einen BNGAuth-Cookie zurückzusenden, habe ich einen Cookie namens "RSPMaybe" zurückgegeben und auf die Homepage umgeleitet.

Als ich das Wireshark-Protokoll durchgelesen habe, ist mir etwas aufgefallen, das mir sofort auffiel, wie unterschiedlich das Protokoll ist, wenn ich mich mit Firefox anmeldete und wenn mein Programm lief. Es könnte nichts sein , aber ich werde das Bild hier für Sie zur Überprüfung enthalten. Ich werde von der Site ein HTTP-Paket zurückgegeben, bevor ich die Daten im vierten Schritt posten kann. Ich bin mir nicht sicher, wie das passiert, aber es muss ein Nebeneffekt von etwas sein, das ich in den HTTPS-Schritten falsch mache.

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(); 
     } 
    } 
} 
+2

Nur eine Seite ... ein weiteres großartiges Werkzeug, um den Draht zu beobachten, ist Fiddler. Nicht sicher, wie gut wirtshark es stapelt, aber man kann etwas fangen (https?), Das andere nicht. – Will

+0

Ich muss es überprüfen, ich filterte den SSL-Verkehr in diesem einfach um die Eigenständigkeit zu illustrieren, die mir aufgefallen ist. Die Art, wie C# SSL behandelt, ist definitiv anders als die Art, wie Firefox es behandelt, und das könnte sehr wohl auch die Ursache meiner Probleme sein. Es scheint wie jedes Mal, wenn ich eine neue Seite mit SSL und C# anfordern, muss es erneut authentifizieren. Ich habe nicht genug Erfahrung in diesem Bereich, um zu wissen, ob das ein Problem sein würde oder nicht. – JoshVarty

+0

Ich kann empfehlen, auch das Firefox-Add-On Firebug zu verwenden, dann benutzen Sie den Konsolenreiter mit der Option "Persist" an. Sie können die detaillierten Anfragen und Antworten für den Authentifizierungsprozess von Live.com sehen. – ReinierDG

Antwort

1

Ich bin mir nicht sicher, ob Sie immer noch daran arbeiten oder nicht, aber die Windows Live Gelände eine Menge Informationen über sie mit der Verwendung des Live ID-API zu helfen hat. Ich hatte nicht viel davon, aber ihre Getting Started Seite hat eine Menge von Informationen sowie einen Link zum Download von Beispielanwendungen, die detailliert beschreiben, wie man den Dienst in einer Vielzahl von Sprachen (einschließlich C#) benutzt.

Sie können die Beispielanwendung von dort herunterladen.

Es klingt ziemlich interessant, was Sie zu tun versuchen, so sehr, dass ich ziemlich Lust habe, mit mir selbst zu spielen!

0

Ändern Sie Ihr Timing und sehen Sie, ob Sie die gleichen Ergebnisse erhalten.

-2

Es ist so viel einfacher, einfach ein UI-Automatisierungsframework wie WatiN zu verwenden, als httpwebrequest zu verwenden, es sei denn, dies würde Ihre Anforderungen verletzen. Mit WatiN denken Sie darüber nach, was auf der Benutzeroberfläche angezeigt wird und nicht auf dem HTML-Code.

+1

-1: Wenn Sie den Code sorgfältig lesen, werden Sie sehen, dass er überhaupt HTML überhaupt nicht verarbeitet. –

Verwandte Themen