Sample forms authentication test in C#

This sample test is doing the following:
1. Sending request to a page which requires forms authentication. This results in 302 to login page.
2. Send request to login page.
3. Parse response from 2 and create response entity containing username/password to be used in next post request to login page.
4. Do a POST to login page. If successful this should return a 302 with Set-Cookie and location header.
5. Send request to location pointed to in last response (this is original page we requested in 1) with request cookie as returned in 4. Expect 200.

using System;
using System.IO;
using System.Net;

namespace FormsAuthTest
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            StreamReader sr = null;

            String originalUri = "http://localhost/default.aspx";

            System.Diagnostics.ConsoleTraceListener trace =
                    new System.Diagnostics.ConsoleTraceListener();

            //
            // Request page protected by forms authentication.
            // This request will get a 302 to login page
            //
            trace.Write("Requesting : " + originalUri);
            request = (HttpWebRequest)WebRequest.Create(originalUri);
            request.AllowAutoRedirect = false;

            response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.Found)
            {
                trace.Write("Response: 302 ");
                trace.WriteLine(response.StatusCode);
            }
            else
            {
                trace.Fail("Response status is " + response.StatusCode + ". Expected was Found");
            }

           
//
            // Get the url of login page from location header
            //
            String locationHeader = response.GetResponseHeader("Location");
            trace.WriteLine("Location header is " + locationHeader);
            trace.WriteLine("");

           
//
            // Request login page
            //
            String loginPageUrl = "http://localhost" + locationHeader;
            Console.WriteLine("Requesting " + loginPageUrl);
            request = (HttpWebRequest)WebRequest.Create(loginPageUrl);
            request.AllowAutoRedirect = false;

            response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK)
            {
                trace.Write("Response: 200 ");
                trace.WriteLine(response.StatusCode);
            }
            else
            {
                trace.Fail("Response status is " + response.StatusCode + ". Expected was OK");
            }

            trace.WriteLine("Parsing login page to create post message");
            trace.WriteLine("");

            sr = new StreamReader(response.GetResponseStream());
            String loginResponse = sr.ReadToEnd();
            sr.Close();

           
String
eventTargetVar = "__EVENTTARGET=";
            String eventTargetValue = "";

           
String
eventArgumentVar = "__EVENTARGUMENT=";
            String eventArgumentValue = "";

           
String
viewStateVar = "__VIEWSTATE=";
            String viewStateSearchString = "name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=\"";
            int viewStateStartIndex = loginResponse.IndexOf(viewStateSearchString);
            loginResponse = loginResponse.Substring(viewStateStartIndex + viewStateSearchString.Length);
            String viewStateValue = Uri.EscapeDataString(
                                                           loginResponse.Substring(0, loginResponse.IndexOf("\" />"))
                                                       );
            loginResponse = loginResponse.Substring(loginResponse.IndexOf("\" />"));

           
String
 lcSearchStr = "input name=";
            int lcSearchIndex = 0;

            //
            // Look for logon control id
            // Use any valid username and password

            //
            lcSearchIndex = loginResponse.IndexOf(lcSearchStr);
            loginResponse = loginResponse.Substring(lcSearchIndex + lcSearchStr.Length + 1);
            String userNameVar = Uri.EscapeDataString(
                                                       loginResponse.Substring(0, loginResponse.IndexOf("\""))
                                                   ) + "=";
            String userNameValue = "Alice";

            lcSearchIndex = loginResponse.IndexOf(lcSearchStr);
            loginResponse = loginResponse.Substring(lcSearchIndex + lcSearchStr.Length + 1);
            String passwordVar = Uri.EscapeDataString(
                                                       loginResponse.Substring(0, loginResponse.IndexOf("\""))
                                                    ) + "=";
            String passwordValue = "alice123";

            lcSearchStr = "type=\"submit\" name=";
            lcSearchIndex = loginResponse.IndexOf(lcSearchStr);
            loginResponse = loginResponse.Substring(lcSearchIndex + lcSearchStr.Length + 1);
            String loginButtonVar = Uri.EscapeDataString(
                                                           loginResponse.Substring(0, loginResponse.IndexOf("\""))
                                                       ) + "=";
            String loginButtonValue = "Log+In";

           
String
eventValidationVar = "__EVENTVALIDATION=";
            String eventValSearchString =
                "name=\"__EVENTVALIDATION\" id=\"__EVENTVALIDATION\" value=\"";
            int eventValStartIndex = loginResponse.IndexOf(eventValSearchString);
            loginResponse = loginResponse.Substring(eventValStartIndex + eventValSearchString.Length);
            String eventValidationValue =
                Uri.EscapeDataString(
                    loginResponse.Substring(0, loginResponse.IndexOf("\" />"))
                );

            String postString = eventTargetVar + eventTargetValue;
            postString += "&" + eventArgumentVar + eventArgumentValue;
            postString += "&" + viewStateVar + viewStateValue;
            postString += "&" + userNameVar + userNameValue;
            postString += "&" + passwordVar + passwordValue;
            postString += "&" + loginButtonVar + loginButtonValue;
            postString += "&" + eventValidationVar + eventValidationValue;

           
//
            // Do a POST to login.aspx now
            // This should result in 302 with Set-Cookie header
            //
            Console.WriteLine("POST request to http://localhost" + locationHeader);
            request = (HttpWebRequest)WebRequest.Create("http://localhost" + locationHeader);
            request.AllowAutoRedirect = false;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            byte[] requestData = encoding.GetBytes(postString);
            request.ContentLength = requestData.Length;

           
Stream
requestStream = request.GetRequestStream();
            requestStream.Write(requestData, 0, requestData.Length);
            requestStream.Close();

            response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.Found)
            {
                trace.Write("Response: 302 ");
                trace.WriteLine(response.StatusCode);
            }
            else
            {
                trace.Fail("Response status is " + response.StatusCode + ". Expected was Found");
            }

            locationHeader = response.GetResponseHeader("Location");
            trace.WriteLine("Location header is " + locationHeader);
            String cookie = response.GetResponseHeader("Set-Cookie");
            trace.WriteLine("Set-Cookie header is " + cookie);
            trace.WriteLine("");

           
//
            // Send request to originalUri with the cookie
            // We should be able to see originalUri contents
            //
            trace.WriteLine("Requesting http://localhost" + locationHeader + " with cookie");
            request = (HttpWebRequest)WebRequest.Create("http://localhost" + locationHeader);
            request.AllowAutoRedirect = false;
            request.Headers.Add(HttpRequestHeader.Cookie, cookie);

            response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK)
            {
                trace.Write("Response: 200 ");
                trace.WriteLine(response.StatusCode);
            }
            else
            {
                trace.Fail("Response status is " + response.StatusCode + ". Expected was OK");
            }
            trace.WriteLine("");

            trace.WriteLine("Contents of " + originalUri);
            trace.WriteLine("");

            sr = new StreamReader(response.GetResponseStream());
            trace.WriteLine(sr.ReadToEnd());
            sr.Close();
        }
    }
}

Above sample is requesting aspx content. You can remove precondition from FormsAuthentication module on your server and use the same code to request non-aspx content as well.

Kanwal

7 thoughts on “Sample forms authentication test in C#

  1. Thor

     
    I have tried this, but get timeout on the last request.
     
    Have tried the cookies fix
                String cookie = response.GetResponseHeader("Set-Cookie");
                trace.WriteLine("Set-Cookie header is " + cookie);
                trace.WriteLine("");
                CookieCollection cookies = response.Cookies;
             
                request = (HttpWebRequest)WebRequest.Create(pageURL);
                request.AllowAutoRedirect = false;
                //request.Headers.Add(HttpRequestHeader.Cookie, cookie);
                request.CookieContainer = new CookieContainer();
                foreach (Cookie oneCookie in cookies)
                {
                    request.CookieContainer.Add(oneCookie);
                }
     
     
    But the cookies collection is empty :(
     
    What to try now?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>