Мне удалось получить консольное приложение для аутентификации в существующем веб-приложении 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.