Авторизация ASP.NET из консольного приложения и время ожидания - PullRequest
0 голосов
/ 17 января 2011

Мне удалось получить консольное приложение для аутентификации в существующем веб-приложении ASP.NET.Он просто имитирует страницу входа в систему, отправляя запрос на страницу входа, содержащую информацию о состоянии просмотра (как если бы запрос был сделан браузером).

Затем он улавливает cookie-файл, отправленный в ответ в CookieContainer.

Затем приложение отправляет несколько запросов на одну и ту же страницу (что требует авторизации).Страница выполняет некоторую работу и записывает файл на сервер.

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

Для входа в систему:

private static CookieContainer PerformLoginRequest()
{
    string loginURL = "http://www.myDomain.com/mySite/login.aspx";

    //Set up the request and give it a cookie container.
    CookieContainer cookieJar = new CookieContainer();
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(loginURL);
    request.CookieContainer = cookieJar;
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";

    //Grab the request body so we can put important information in it.
    Stream requestBody = request.GetRequestStream();
    string postData = "__VIEWSTATE=GIBBERISH&UserName=USERNAME&Password=PASSWORD%21&LoginButton.x=0&LoginButton.y=0";

    //Throw the string into the body.
    ASCIIEncoding encoding = new ASCIIEncoding();
    byte[] byte1 = encoding.GetBytes(postData);
    requestBody.Write(byte1, 0, byte1.Length);
    requestBody.Close();

    //Get the response to the login request.
    WebResponse response = request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream());
    string result = reader.ReadToEnd();
    reader.Close();

    return cookieJar;
}

Для запроса страницы:

private static long RequestPage(string url)
{
    //If we've already got a CookieContainer, then we've logged in already. Otherwise, log in.
    if (cookieJar == null)
    {
        try
        {
            cookieJar = PerformLoginRequest();
        }
        catch
        {
            throw;
        }
    }

    //Set up the request.
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.CookieContainer = cookieJar;
    request.Method = "GET";
    request.ContentType = "application/x-www-form-urlencoded";
    request.Timeout = timeout; //5 minutes.

    WebResponse response = request.GetResponse();

    return response.ContentLength;
}

Переменные cookieJar и timeoutявляются глобальными для приложения.

Есть идеи, что могло бы вызвать это?

Обновление (2010-01-17, 15:30 EST)

Когда я запускаю приложение с запущенным Fiddler, все проходит нормально.Все запросы работают, как я и ожидал.

Я проверил файлы журнала IIS.В них я вижу начальный запрос на вход в систему, перенаправление после входа в систему и запросы на первые две страницы.Но после этого ... ничего.Как будто запросы даже не поступают на веб-сервер.

Обновление (2010-01-18, 11:29 EST)

Я обновилкод наверх, чтобы отразить изменения, предложенные Крисом Б. Беренсом.Но безрезультатно.В случае, если это имеет значение, цикл, который вызывает вышеуказанные функции, выглядит следующим образом:

private static void RegenerateNecessaryForms(MyEntities context)
{
    var items = context.Items.Where(i => i.NeedsProcessing == true);

    var area = context.Areas;
    foreach (Item i in items)
    {
        bool success = true;
        foreach (Area area in areas)
        {
            try
            {
                string url = string.Format("http://{0}/mySite/process.aspx?item={1}&area={2}", targetDomain, i.ItemName, area.AreaName);
                long result = RequestPage(url, m);
            }
            catch
            {
                success = false;
            }
        }

        if (success)
        {
            i.NeedsProcessing = false;
        }
    }
}

Обновление (2010-01-18, 13:03 PM EST) Это, вероятно, наиболееполезную информацию, которую я смог предоставить до сих пор.

Я снова просматривал журналы IIS.Когда запрос входа в систему отправлен, я могу очистить журналы, и он сразу же появляется.Однако ни один из запросов к страницам не отображается, пока я не закрою консольное приложение.Вот соответствующий бит журнала:

2011-01-18 17:44:54 X.X.X.X POST /MySite/login.aspx - 80 - X.X.X.X - 302 0 0 148
2011-01-18 17:44:54 X.X.X.X GET /MySite/default.aspx - 80 AutomatedUser X.X.X.X - 200 0 0 48
2011-01-18 17:54:33 X.X.X.X GET /MySite/process.aspx model=ITEM_ONE&area=US 80 AutomatedUser X.X.X.X - 200 0 995 579100
2011-01-18 17:54:33 X.X.X.X GET /MySite/process.aspx model=ITEM_ONE&area=CANADA 80 AutomatedUser X.X.X.X - 200 0 995 553247
2011-01-18 17:54:33 X.X.X.X GET /MySite/process.aspx model=ITEM_TWO&area=US 80 AutomatedUser X.X.X.X - 200 0 995 532824

Каждый из запросов GET к process.aspx соответствует вызову метода RequestPage выше.Строка "request.GetResponse ();"Это займет около 10 секунд или около того, но похоже, что запрос не будет выполнен (по крайней мере, в соответствии с IIS), пока я не закрою приложение.(Если вы посмотрите на последнее число в каждой строке, это количество времени, которое потребовалось, чтобы обслужить страницу в миллисекундах, но я получил ответ в приложении за гораздо меньшее время.) Так что это возможно (вероятно, даже вероятно)) что IIS ограничивает количество подключений, которые он будет принимать с одного IP.

И это подводит меня к вопросу: что из-за запросов, которые я делаю, приводит к тому, что они остаются "открытыми" таким образом?

Запросы не возвращают страницу HTML(если это имеет значение) они возвращают PDF.

1 Ответ

0 голосов
/ 18 января 2011

Вы явно не закрываете свой запрос:

//Get the response to the login request.
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string result = reader.ReadToEnd();

reader.Close();

return cookieJar;

Посмотрите, поможет ли это.

...