Сеанс входа не переносится на новую веб-страницу с помощью WebRequest / Response? - PullRequest
6 голосов
/ 27 февраля 2012

Хорошо, я слишком долго ломал голову над этим соло.Мне не удалось взломать его даже за часы, проведенные на этом и многих других сайтах.

По сути, я пытаюсь удалить некоторые данные с веб-страницы за страницей входа в систему с помощью WebRequest / Response. (Я получил это для работы с использованием элемента управления 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;
        }

Пока что я могу попасть на нужную страницу по первой ссылке, но когдаЯ перехожу ко второму: он отправляет меня обратно на страницу входа, как будто я не вошел в систему.

Проблема может заключаться в неправильной записи файлов cookie, но я новичок, поэтому, возможно, япросто делаю это неправильно.Он захватывает файлы cookie, отправленные обратно из POST: JSESSIONID и S2V, однако, когда мы переходим в «GET», используя FireFox WebConsole, браузер показывает, что он отправляет JSESSIONID, S2V и SPRING_SECURITY_REMEMBER_ME_COOKIE, что, я считаю,это файл cookie, который используется, когда я нажимаю на поле «Запомнить меня» в форме входа в систему.

Я пробовал много разных способов сделать это, используя ресурсы 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;
}

Это предложение,по крайней мере, способ, которым я это реализовал, не сработал.

Как предложил Krizz, я изменил код для использования CookieContainer и переноса файлов cookie из одного запроса в другой, однако ответ просто возвращает мне оригиналСтраница входа, как если бы я не входил в систему.

Существуют ли определенные сайты, которые просто НЕ ДОПУСКАЮТ такого поведения?

Окончательное решение

Окончательное решение было предложено Адрианом Ифтоде, в котором он заявил, что веб-сайт, на который я пытаюсь войти , может не разрешить иметь аутентификацию без действительного сеанса , поэтому добавление GET в начало процесса позволиломне, чтобы получить это печенье.

Спасибо за вашу помощь, ребята!

Ответы [ 2 ]

6 голосов
/ 01 марта 2012

Я выполнял передачу файлов cookie для веб-сайта, написанного на PHP.Ясно, что вы передаете куки, но, может быть, это как в этой ситуации

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

Заголовок Set-Cookie содержит другую связанную информацию о куки и возможные другие инструкции для других куки.У меня был один файл cookie с информацией (путь), идентификатором сеанса, который мне нужно было отправить обратно на сервер, чтобы сервер знал, что я тот же клиент, который выполнил запрос GET.

Новый запрос имелвключить этот файл cookie

request.Headers["Cookie"] = phpsessid;

Вы уже делаете это, но убедитесь, что полученные вами файлы cookie отправлены обратно на сервер.

С учетом сеанса и аутентификации существует два файла cookie, одиндля сеанса один для аутентификации, а некоторые серверы / приложения могут не разрешить аутентификацию без действительного сеанса.Что я хочу сказать, так это то, что вам также может понадобиться передать cookie сессии.Таким образом, следующие шаги:

  • Сначала выполните запрос GET для получения файла cookie сеанса.
  • Затем выполните запрос POST для аутентификации и получения файла cookie аутентификации.
  • Используйте оба куки для перехода на защищенные страницы.

Также отметьте этот вопрос , он не показывает весь класс, но идея состоит в том, чтобы CookieContainer оставался втого же класса, добавьте новые куки-файлы из запросов POST / GET и назначьте их каждому новому запросу, как ответил @Krizz.

2 голосов
/ 01 марта 2012

Попробуйте использовать CookieContainer, который является классом для сохранения контекста файлов cookie между несколькими запросами. Вы просто создаете его экземпляр и назначаете его каждому 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...