来自控制台应用程序的 ASP.NET 授权暂停
不管怎样,我设法让控制台应用程序能够使用现有的 ASP.NET Web 应用程序进行自身身份验证。它只是通过向包含视图状态信息的登录页面发出发布请求来模仿登录页面(就像浏览器发出了请求一样)。
然后它会在 CookieContainer 中捕获作为响应发回的 cookie。
然后应用程序继续向同一页面发出多个请求(这需要授权)。该页面执行一些工作并在服务器上写出一个文件。
我遇到的问题是,在虚假登录后,前两个请求都可以顺利完成。第三个请求甚至从未收到响应。下面是我用来发出请求的代码:
登录:
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 和超时变量对于应用程序来说是全局的。
知道什么会导致这种情况吗?
更新(2010-01-17,美国东部时间下午 3:30)
当我在 Fiddler 运行的情况下启动应用程序时,一切顺利。所有请求都起作用,正如我所期望的那样。
我检查了 IIS 日志文件。在其中我可以看到初始登录请求、登录后的重定向以及前两个页面的请求。但在那之后……什么也没有了。就像请求甚至没有到达网络服务器一样。
更新(美国东部时间 2010 年 1 月 18 日上午 11:29)
我更新了顶部的代码以反映 Chris B. Behrens 建议的更改。但无济于事。如果重要的话,调用上述函数的循环如下所示:
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,美国东部时间下午 1:03) 这可能是迄今为止我能够提供的最有用的信息。
我再次查看 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
对 process.aspx 的每个 GET 请求都对应于对上面的 RequestPage 方法的调用。 “request.GetResponse();”行只需要大约 10 秒左右,但不知何故,在我关闭应用程序之前,该请求似乎永远不会完成(至少根据 IIS)。 (如果您查看每行的最后一个数字,这就是为页面提供服务所花费的时间(以毫秒为单位),但我在应用程序中得到响应的时间比这要短得多。)所以这是可能的(甚至可能) ) IIS 正在限制它从一个 IP 接受的连接数量。
这让我想到一个问题:我提出的请求是什么导致它们保持这样的“开放”状态?
这些请求不会返回 HTML 页面(如果重要的话),而是返回 PDF。
For what its worth, I managed to get a console application to authenticate itself with an existing ASP.NET web application. It just mimics the login page by making a post request to the login page containing the viewstate information (just as if a browser had made the request).
It then catches the cookie sent back in response in a CookieContainer.
The application then goes on to make multiple requests to the same page (which requires authorization). The page does some work and writes out a file on the server.
The problem I'm encountering is that after the phony login, the first two requests go through okay. The third request never even receives a response. Below is the code I'm using to make the requests:
To login:
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;
}
To request a page:
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;
}
The cookieJar and timeout variables are global to the application.
Any idea what would cause this?
Update (2010-01-17, 3:30 PM EST)
When I launch the application with Fiddler running, everything goes through fine. All the requests function, just as I would expect.
I inspected the IIS log files. In them I can see the intial login request, the redirect after login, and the requests for the first two pages. But after that...nothing. It's like the requests don't even make it to the web server.
Update (2010-01-18, 11:29 AM EST)
I updated the code up top to reflect the changes suggested by Chris B. Behrens. But to no avail. In case it matters, the loop that calls the above functions looks like this:
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;
}
}
}
Update (2010-01-18, 1:03 PM EST)
This is probably the most useful information I've been able to provide so far.
I was looking at the IIS logs again. When the login request is sent, I can flush the logs and it shows up immediately. However, none of the page requests show up until I close the console application. Here's the relevant bit of the log:
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
Each of the GET requests to process.aspx corresponds to a call to the RequestPage method above. The line "request.GetResponse();" only takes about 10 seconds or so, but it looks like somehow that request never gets completed (at least according to IIS) until I close the application. (If you look at the last number on each line, that's the amount of time it took to serve the page in milliseconds, but I got the response back in the application in much less time than that.) So it's possible (probably even likely) that IIS is restricting the amount of connections it will accept from one IP.
Which brings me to the question: What is it about the requests that I'm making that causes them to stay "open" like that?
The requests don't return an HTML page (if that matters) they return a PDF.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您没有明确关闭您的请求:
看看这是否有效。
You're not explicitly closing your request:
See if that does the trick.