2012-02-27 26 views
7

Ok, tôi đã bỏ lỡ bộ não của mình trong một solo này quá lâu. Tôi đã không thể để crack nó ngay cả với giờ dành cho việc này và nhiều trang web khác.Phiên đăng nhập không chuyển sang trang web mới bằng WebRequest/Response?

Về cơ bản, tôi đang cố gắng tách một số dữ liệu khỏi trang web phía sau trang Đăng nhập bằng WebRequest/Response. (Tôi đã làm việc này bằng cách sử dụng một điều khiển WebBrowser với một số sự kiện xếp lớp dẫn đến các trang web khác nhau nhưng nó gây ra một số vấn đề khi cố gắng refactor - chưa kể nó được sử dụng một biểu mẫu ẩn để thực hiện công việc là ' . thực hành xấu')

Đây là những gì tôi có:

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

cho đến nay, tôi có thể đến được trang thích hợp từ các liên kết đầu tiên nhưng khi tôi đi đến thứ hai, nó sẽ gửi tôi quay lại trang đăng nhập như thể tôi không đăng nhập.

Sự cố có thể nằm trong cookie không nhận được c aptured một cách chính xác nhưng tôi là một người mới vì vậy có lẽ tôi chỉ làm điều đó sai. Nó nắm bắt các cookie được gửi trở lại từ POST: JSESSIONID và S2V tuy nhiên, khi chúng tôi đi đến "GET", sử dụng FireFox WebConsole, trình duyệt cho thấy rằng nó gửi JSESSIONID, S2V một SPRING_SECURITY_REMEMBER_ME_COOKIE, mà tôi tin là cookie được sử dụng khi tôi nhấp vào ô "Ghi nhớ" trên biểu mẫu đăng nhập.

Tôi đã thử nhiều cách khác nhau để thực hiện việc này bằng cách sử dụng tài nguyên của SO nhưng tôi chưa truy cập vào trang mình cần. Vì vậy, vì lợi ích của mái tóc tôi đã để lại, tôi đã quyết định yêu cầu giúp đỡ về tốt ole SO. (Đây là một trong những điều tôi không muốn từ bỏ - bướng bỉnh như vậy đôi khi)

Nếu ai đó muốn địa chỉ thực của trang web tôi đang cố gắng đăng nhập, tôi muốn được nhiều hơn hạnh phúc hơn khi gửi cho một vài người trong một tin nhắn riêng.

Mã mà tôi phải phản ánh một câu trả lời gợi ý của 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; 
} 

gợi ý này, ít nhất là cách tôi thực hiện nó, đã không làm việc.

Như Krizz đã đề xuất, tôi đã thay đổi mã để sử dụng CookieContainer và chuyển cookie từ yêu cầu này sang yêu cầu khác, phản hồi chỉ trả về trang đăng nhập ban đầu như thể tôi không đăng nhập.

Có những trang web nhất định chỉ S W KHÔNG cho phép loại hành vi này không?

chung kết Giải pháp

Các giải pháp cuối cùng đã được đề xuất bởi Adrian Iftode nơi ông tuyên bố rằng các trang web tôi đang cố gắng để đăng nhập có thể không cho phép để có một chứng thực mà không có một phiên hợp lệ nên thêm một GET vào đầu quá trình cho phép tôi lấy cookie đó.

Cảm ơn tất cả các bạn trợ giúp!

+0

Tư vấn thiết thực nhận Fiddler http://fiddler2.com và xem tiêu đề nào được gửi và nhận bởi trình duyệt của bạn chính xác sau khi bạn đăng nhập. Sau đó mô phỏng các mã đó trong mã C# của bạn. –

+0

@zespri Tôi đã sử dụng Fiddler trước đây và, thành thật mà nói, ở cấp độ hiện tại của tôi về khả năng lập trình, nó vượt qua đầu tôi. Đó là một cái gì đó tôi đang làm việc trên nhưng nó đã không giúp đỡ nhiều và tôi có cùng một hình thức thông tin giao diện điều khiển web FireFox. – Josh

Trả lời

5

tôi đang làm một số loại chuyển cookie cho một trang web viết bằng PHP. Rõ ràng bạn đang đi qua cookie, nhưng có lẽ cũng giống như trong tình huống đó

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

Tiêu đề Set-Cookie chứa thông tin khác có liên quan về cookie và có thể hướng dẫn khác cho các tập tin cookie khác. Tôi đã có một cookie với thông tin của nó (Path), id phiên mà tôi cần gửi trở lại máy chủ để máy chủ biết rằng tôi là cùng một máy khách đã thực hiện yêu cầu GET.

Các yêu cầu mới phải bao gồm cookie này

request.Headers["Cookie"] = phpsessid; 

Bạn đã làm điều này, nhưng chắc chắn rằng các tập tin cookie bạn nhận được, bạn gửi lại cho máy chủ.

Xem xét phiên và xác thực, có hai cookie, một cho phiên, một cho xác thực và một số máy chủ/ứng dụng có thể không cho phép xác thực mà không có phiên hợp lệ. Những gì tôi muốn nói là bạn có thể cần phải vượt qua cookie phiên quá. Vì vậy, các bước sẽ là:

  • Thực hiện yêu cầu GET trước tiên để nhận cookie phiên.
  • Tiếp theo làm yêu cầu POST để xác thực và nhận cookie xác thực.
  • Sử dụng cả hai cookie để điều hướng đến các trang được bảo vệ.

Đồng thời kiểm tra this question, nó không hiển thị toàn bộ lớp học, nhưng ý tưởng là giữ CookieContainer trong cùng một lớp, thêm cookie mới từ yêu cầu POST/GET và gán cho mỗi yêu cầu mới, như @Krizz trả lời.

+1

Đây là viên đạn bạc. Sau một số thử nghiệm bổ sung, tôi thấy rằng việc thêm GET đầu tiên vào mã là thủ thuật. Tôi thậm chí không cần phải cắt "; path = /" khỏi cookie. Cảm ơn người đàn ông. – Josh

+1

Tôi chắc chắn sẽ trao cho bạn tiền thưởng sau 18 giờ (trang web sẽ không cho phép tôi thực hiện ngay). – Josh

1

Hãy thử sử dụng CookieContainer là lớp để giữ ngữ cảnh cookie giữa một số yêu cầu. Bạn chỉ cần tạo một thể hiện của nó và gán nó cho mỗi WebRequest.

Do đó, thay đổi mã của bạn:

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

Tôi giả định rằng tôi cần phải thay đổi thành HttpWebResponse/Request vì WebResponse không có CookieContainer? – Josh

+0

@Josh có bạn đúng, mã số cố định – Krizz

Các vấn đề liên quan