Recently I was looking for a way to test a web application when I stumbled upon a roadblock. Sometimes I have a specific train of thought that becomes interrupted with an impediment such as the one I found. After pursuing the solution to the roadblock, I forgot what I was initially trying to solve, then it hit me later.
The problem was I needed to be able to programmatically authenticate with an ASP.NET web application. Having dealt with this situation before, I decided to display my solution for two reasons. The first is so I may resort to this code when I need it again, and the second so anyone in search of something similar will have it as well.
One tool I do use for the tracking of my HTTP requests and responses is
Fiddler.
Fiddler allows for the inspection off all HTTP traffic, which provides a good understanding of what constitutes our headers and messages. In my solution, I use this to understand the requirements of my authentication request.
My approach to the solution is something like the following. We have two URL’s, the first is the authentication URL of our target, and the second is the protected content of our application. In my case, the first URL is something like /Login.aspx, and the second is /Default.aspx. In order to get access to the protected content, we must authenticate with the server, which requires we post our request containing our username, password, and whatever else our application requires. After looking at the request for authentication in
Fiddler as my model, I determine what the server requires, which is the ViewState of our application, as well as my username, password, et cetera.
I have dissected this solution into four phases. The first is the initial get of the /Login.aspx URL. After this, I manipulate the response stream to obtain the ViewState content in order to authenticate. The third piece is the authentication against the server, and the fourth is the request of the protected content. My end result is a string representing the protected page.
Microsoft provides a nice
sample application which demonstrates the usage of the
HttpWebRequest and
HttpWebResponse classes if one needs a working model.
// Create our variables
string signinUrl = "http://yourUrl.net/Login.aspx";
string contentUrl = "http://yourUrl.net/Default.aspx";
string responseHtml = null;
CookieContainer cookies = new CookieContainer();
// 1. Initialize our connection and retrieve the Viewstate.
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(signinUrl);
httpWebRequest.Method = "GET";
httpWebRequest.ContentType = "text/html; charset=utf-8";
StreamReader responseReader = new StreamReader( httpWebRequest.GetResponse().GetResponseStream() );
responseHtml = responseReader.ReadToEnd();
responseReader.Close();
// 2. Append to our Viewstate our authenitication requirements.
// Determine where in responseHtml VIEWSTATE is get just the value of it.
// 7 is the length of the string value="
int beginPosition = responseHtml.IndexOf( "value=\"", responseHtml.IndexOf("__VIEWSTATE") ) + 7;
int endPosition = responseHtml.IndexOf( "\"", beginPosition );
// Convert into a Unicode string for the HTTP stream.
string viewState = HttpUtility.UrlEncodeUnicode( responseHtml.Substring( beginPosition, endPosition - beginPosition ) );
// Create our new ViewState with our POST data
string post = String.Format("__VIEWSTATE={0}" +
"&tbxUserName={1}&tbxPassword={2}&tbxCompany={3}&btnLogin=Login",
viewState, "myUserName", "myPa$$word", "MyCompany");
// 3. Post our new request to the authentication page.
httpWebRequest = (HttpWebRequest)WebRequest.Create(signinUrl);
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
// Set any headers you may desire
httpWebRequest.Headers.Set("Pragma","no-cache");
httpWebRequest.CookieContainer = cookies;
// Add our modifications to our request stream
StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
requestWriter.Write(post);
requestWriter.Close();
// Close the RequestStream before the next
httpWebRequest.GetResponse().Close();
// 4. Send our final request for the protected page.
httpWebRequest = (HttpWebRequest)WebRequest.Create(contentUrl);
httpWebRequest.CookieContainer = cookies;
responseReader = new StreamReader(httpWebRequest.GetResponse().GetResponseStream());
responseHtml = responseReader.ReadToEnd();
responseReader.Close();
// At this point, we have a string representation of our protected HTML page.
// do something with responseHtml;