登录会话未使用WebRequest/Response转移到新网页?

Jos*_*osh 6 .net c# forms-authentication webrequest

好吧,我已经在这个独奏上绞尽脑汁待了太久.即使花了很多时间在这个和许多其他网站上,我也无法破解它.

基本上,我试图使用WebRequest/Response从LogIn页面后面的网页中删除一些数据. (我已经使用WebBrowser控件执行此操作,其中一些分层事件导航到不同的网页,但在尝试重构时会导致一些问题 - 更不用说已经声明使用隐藏的表单来完成工作是'坏的实践'.)

这就是我所拥有的:

        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;
        }
Run Code Online (Sandbox Code Playgroud)

到目前为止,我能够从第一个链接到达正确的页面,但是当我转到第二个链接时,它会将我发送回登录页面,就好像我没有登录一样.

问题可能在于cookie没有被正确捕获但我是新手所以也许我只是做错了.它捕获从POST发回的cookie:JSESSIONID和S2V然而,当我们使用FireFox WebConsole进入"GET"时,浏览器显示它发送了JSESSIONID,S2V SPRING_SECURITY_REMEMBER_ME_COOKIE,我认为这是我使用的cookie单击登录表单上的"记住我"框.

我已经尝试了许多不同的方法来使用SO的资源,但我还没有到达我需要的页面.因此,为了我留下的头发,我决定寻求有关好的SO的帮助.(这是我不想放松的事情之一 - 有时像这样顽固)

如果有人想要我正在尝试登录的网站的实际地址,我会非常乐意通过私信将其发送给几个人.

我必须反映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;
}
Run Code Online (Sandbox Code Playgroud)

这个建议,至少我实现它的方式,都没有用.

正如Krizz建议的那样,我更改了代码以使用CookieContainer并将cookie从一个请求转移到另一个请求,然而,响应只是让我回到原始登录页面,就好像我没有登录一样.

是否有某些网站不允许这种行为?

最终解决方案

最终的解决方案是由Adrian Iftode提出的,他说我尝试登录的网站可能不允许在没有有效会话的情况下进行身份验证,因此在流程开始时添加GET允许我获取该cookie.

谢谢你们的帮助!

Adr*_*ode 6

我正在为使用PHP编写的网站进行某种cookie转移.很明显,你传递的是cookie,但也许就像那种情况一样

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

Set-Cookie头包含有关该cookie和其他可能的指令其他饼干等相关信息.我有一个cookie及其信息(路径),我需要发送回服务器的会话ID,所以服务器会知道我是做同一个GET请求的客户端.

新请求必须包含此cookie

request.Headers["Cookie"] = phpsessid;
Run Code Online (Sandbox Code Playgroud)

您已经这样做,但确保收到的cookie,您已发送回服务器.

考虑会话和身份验证,有两个cookie,一个用于会话,一个用于身份验证,一些服务器/应用程序可能不允许在没有有效会话的情况下进行身份验证.我想说的是你可能也需要传递会话cookie.所以步骤是:

  • 首先执行GET请求以获取会话cookie.
  • 接下来执行POST请求以进行身份​​验证并获取身份验证cookie.
  • 使用两个cookie导航到受保护的页面.

同样检查这个问题,它没有显示整个类,但想法是将CookieContainer保持在同一个类中,从POST/GET请求添加新的cookie并将它们分配给每个新请求,如@Krizz回答.