2012-02-27 7 views
7

私はこの1つのソロに長すぎるために頭を抱えています。私はこのサイトや他の多くのサイトに何時間も費やしてもそれを解読することができませんでした。WebRequest/Responseを使用してログインセッションが新しいWebページに転送されませんか?

基本的に、WebRequest/Responseを使用してLogInページの後ろのWebページからデータを取り除こうとしています。 (これは、WebBrowserコントロールを使用して、別のWebページに移動するいくつかの階層化されたイベントで動作するようになっていますが、リファクタリングを試みるときにいくつかの問題を引き起こしています。悪い習慣」)

これは私が持っているものです。

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

これまでのところ、私は最初のリンクから適切なページを取得することができるが、私が第二に行くとき、それが送信します私がログインしていないかのように私をログインページに戻します。

この問題は、私は初心者ですので多分私は間違っているだけです。それはPOSTから返されたクッキーをキャプチャします:JSESSIONIDとS2Vしかし、私たちがFireFox WebConsoleを使って "GET"に行くと、ブラウザーはJSESSIONID、S2V を送信したことを示します、SPRING_SECURITY_REMEMBER_ME_COOKIEログインフォームの[Remember Me]ボックスをクリックしたときに表示されます。

私はSOのリソースを使用してこれを行うさまざまな方法を試しましたが、私は必要なページにまだ到達していません。だから、私が残した髪の毛のために、私は良いオレの助けを求めることにしました。 (これは、あまりにも頑固なものではありません)。

私がログインしようとしているサイトの実際のアドレスが必要な場合は、非公開のメッセージでカップルの人々に送信することを喜んでより。私はウォルマートによって提案答えを反映する必要が

コード:

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

この提案、私は動作しませんでした、それを実装し、少なくとも方法。

CookieContainerを使用して1つのリクエストから別のリクエストにクッキーを転送するようにコードを変更しましたが、レスポンスでは私がログインしなかったかのように元のログインページが返されます。

この種の動作を許可しないサイトはありますか?

最終解決は

彼は私がにログインしようとしているウェブサイトは、有効なセッションなしで認証を持つことができない可能性があることを述べたところ、最終的な解決策は、エイドリアンIftodeによって提案されたので、GETを追加プロセスの始めまで、私はそのクッキーを入手することができました。

皆さん、ありがとうございます!

+0

実用的なアドバイスは、Fiddler http://fiddler2.comを取得し、ログイン後に正確にどのヘッダがあなたのブラウザによって送受信されているかを確認します。そしてそれらをあなたのC#コードでエミュレートします。 –

+0

@zespri私は以前にFiddlerを使ってきましたが、正に言えば、私の現在のプログラミング能力レベルでは、それは私の頭の中です。それは私が取り組んでいることですが、それほど役に立たず、私はFireFoxウェブコンソールから同じ情報を得ました。 – Josh

答えて

5

私はPHPで書かれたWebサイトのCookie転送のいくつかの並べ替えをしていました。 は明らかにあなたはクッキーを渡しているが、そのような状況で

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

Set-Cookieヘッダはクッキーや他のクッキーのための可能な他の命令に関するその他の関連情報が含まれているように多分あります。私はその情報(Path)を持つクッキーを1つ持っていました。セッションIDは、サーバーに送り返す必要があったため、サーバーはGET要求を行ったクライアントと同じであることを認識します。

が新しい要求が、このクッキーを含めるように

request.Headers["Cookie"] = phpsessid; 

を持っていたあなたはすでにこれを行うが、あなたが受け取るクッキーを確認して、サーバーに送り返さ。

セッションと認証を考慮すると、セッション用と認証用の2つのCookieがあり、一部のサーバー/アプリケーションでは有効なセッションがないと認証できない場合があります。私が言いたいのは、セッションクッキーも渡す必要があるかもしれないということです。したがって、手順は次のようになります。

  • セッションクッキーを取得するためのGET要求を最初に行います。
  • 次は、認証するためのPOST要求を行い、認証Cookieを取得します。
  • 両方のCookieを使用して保護されたページに移動します。

またthis questionをチェックし、それがクラス全体が表示されませんが、考え方は、同じクラスにCookieContainerを保つPOSTから新しいクッキーを追加/ GETリクエストし、それぞれの新しい要求に割り当てることで、 @Krizzのように答えた。

+1

これは銀色の弾丸だった。追加のテストをした後、最初のGETをコードに追加するのが難しいことが分かりました。私はクッキーから ";パス= /"を切り捨てる必要はありませんでした。ありがとう。 – Josh

+1

18時間後に賞金を授与されることになります(サイトではすぐにはできません)。 – Josh

1

CookieContainerを使用してください。これは、いくつかの要求の間でクッキーコンテキストを維持するクラスです。単にそのインスタンスを作成し、それを各WebRequestに割り当てるだけです。

したがって、あなたのコードを変更:

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

WebResponseにCookieContainerがないので、私はHttpWebResponse/Requestに変更する必要があると思いますか? – Josh

+0

@Joshはい、あなたは正しい、コードは固定 – Krizz

関連する問題