HttpWebRepense Cookie未设置为重定向



我正在尝试执行以下操作:

  1. 发送GET请求以获取登录页面(提示输入用户名、密码并设置cookie)
  2. 构建一个POST请求,从#1发送cookie和用户名/密码主体(这将返回一个Set cookie并重定向到登录用户的网站登录页)

我的问题是302重定向。Web服务器返回一个带有Set-Cookie的302,但当HttpWebRequest自动重定向时,它不会传递现在更新的cookie。为了解决这个问题,我尝试设置.AllowAutoRedirect = false,将cookie保存在CookieCollection中,然后构建第三个HTTP请求:一个到最终302位置的get。很遗憾,我无法设置此请求的Cookie。我不知道为什么,这让我很生气。

HTTP请求依次为named request、postRequest、redirectRequest。

string loginGetUrl = "https://<..>/signin.htm";
string loginPostUrl = "https://<..>/j_acegi_security_check";
string loginRedirectUrl = "https://<..>/centraladmin/poslinks.htm";
string postData = String.Format("j_username={0}&j_password={1}", username, password);
CookieCollection cookies = new CookieCollection();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginGetUrl); 
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
//Get the response from the server and save the cookies from the first request..
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
cookies = response.Cookies;        
HttpWebRequest postRequest = (HttpWebRequest)WebRequest.Create(loginPostUrl);
postRequest.CookieContainer = new CookieContainer();
// Add the received Cookies from the HTTP Get
postRequest.CookieContainer.Add(cookies); 
postRequest.Method = WebRequestMethods.Http.Post;
postRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
postRequest.AllowWriteStreamBuffering = false;
postRequest.ProtocolVersion = HttpVersion.Version11;
postRequest.AllowAutoRedirect = false;
postRequest.ContentType = "application/x-www-form-urlencoded";
byte[] byteArray = Encoding.ASCII.GetBytes(postData);
postRequest.ContentLength = byteArray.Length;
Stream newStream = postRequest.GetRequestStream(); //open connection
newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
newStream.Close();
HttpWebResponse postResponse = (HttpWebResponse)postRequest.GetResponse();
// Save the cookies from the POST login request, then send them on to the redirected URL
cookies = postResponse.Cookies;
HttpWebRequest redirectRequest = (HttpWebRequest)WebRequest.Create(loginRedirectUrl);
redirectRequest.CookieContainer = new CookieContainer();
// add cookies from POST
redirectRequest.CookieContainer.Add(cookies);
HttpWebResponse redirectResponse = (HttpWebResponse)redirectRequest.GetResponse();

redirectRequest.CookieContainer.Add(cookies);,cookie对象包含正确的cookie。但当我看Fiddler时,我只看到以下信息:

GET https://<...>/centraladmin/poslinks.htm HTTP/1.1
Host: host:port

在这一点上,我的头有点撞到墙上了。有什么建议吗?我指的是什么不对吗?小心,我通常不写C#代码

我自己无法解决这个问题,但从@malte-clasen的这篇博客文章中找到了一个有用的代码片段。代码在Github上,我把它附在这里是为了保留。

我删除了异步组件,因为它在我的代码中不是必需的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace DracWake.Core
{
public class WebClient : IWebClient
{
private readonly CookieContainer _cookies = new CookieContainer();
private HttpWebRequest CreateRequest(Uri uri)
{
var request = HttpWebRequest.CreateHttp(uri);
request.AllowAutoRedirect = false;
request.CookieContainer = _cookies;
SetHeaders(request);
var defaultValidator = System.Net.ServicePointManager.ServerCertificateValidationCallback;
request.ServerCertificateValidationCallback =
(sender, certificate, chain, sslPolicyErrors) =>
certificate.Subject.Contains("O=DO_NOT_TRUST, OU=Created by http://www.fiddler2.com")
|| (certificate.Subject == "CN=DRAC5 default certificate, OU=Remote Access Group, O=Dell Inc., L=Round Rock, S=Texas, C=US")
|| (defaultValidator != null && defaultValidator(request, certificate, chain, sslPolicyErrors));
return request;
}
private async Task<string> DecodeResponse(HttpWebResponse response)
{
foreach (System.Net.Cookie cookie in response.Cookies)
{
_cookies.Add(new Uri(response.ResponseUri.GetLeftPart(UriPartial.Authority)), cookie);
}
if (response.StatusCode == HttpStatusCode.Redirect)
{
var location = response.Headers[HttpResponseHeader.Location];
if (!string.IsNullOrEmpty(location))
return await Get(new Uri(location));
}   
var stream = response.GetResponseStream();
var buffer = new System.IO.MemoryStream();
var block = new byte[65536];
var blockLength = 0;
do{
blockLength = stream.Read(block, 0, block.Length);
buffer.Write(block, 0, blockLength);
}
while(blockLength == block.Length);
return Encoding.UTF8.GetString(buffer.GetBuffer());
}
public async Task<string> Get(Uri uri)
{
var request = CreateRequest(uri);
var response = (HttpWebResponse) await request.GetResponseAsync();
return await DecodeResponse(response);
}
private void SetHeaders(HttpWebRequest request)
{
request.Accept = "text/html, application/xhtml+xml, */*";
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers[HttpRequestHeader.AcceptLanguage] = "en-US,en;q=0.8,de-DE;q=0.5,de;q=0.3";
request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";
request.Headers[HttpRequestHeader.CacheControl] = "no-cache";
}
public async Task<string> Post(Uri uri, byte[] data)
{
var request = CreateRequest(uri);
request.Method = "POST";
request.GetRequestStream().Write(data, 0, data.Length);
var response = (HttpWebResponse) await request.GetResponseAsync();
return await DecodeResponse(response);
}
}
}

DecodeResponse解决了我的问题。

相关内容

  • 没有找到相关文章

最新更新