Share via


How a session id is generated for an aspx page in .net framework 1.1

In this blog, I just wanted to write about the method within the .net framework which is responsible for generating the session id when a client requests an aspx page for the first time. This article doesn’t talk about the various scenarios under which the session id is created.

I was curious to know which class/method within the .net framework is used to generate the session id when a request for an aspx page comes in. I was looking at the SessionStateModule class under the System.Web.SessionState namespace using the .net reflector written by Lutz Roeder - https://www.aisto.com/roeder/dotnet/

Inside this class, there is a method with the following signature

private IAsyncResult BeginAcquireState(object source, EventArgs e, AsyncCallback cb, object extraData)
{

}

Within this method, there is an if else statement which checks if the private string rqId is null or not. This is the string which actually stores the session id.

if (this._rqId != null)

{

      sessionStateItem = this.GetSessionStateItem();

}

else

{

      this._rqId = SessionId.Create(ref this._randgen);

      if (!s_config._isCookieless)

      {

            HttpCookie cookie = CreateSessionCookie(this._rqId);

            if (!this._rqContext.Response.IsBuffered())

            {

                throw new HttpException(HttpRuntime.FormatResourceString("Cant_write_session_id_in_cookie_because_response_was_flushed"));

            }

            this._rqContext.Response.Cookies.Add(cookie);

            this._rqAddedCookie = true;

      }

      else

      {

            this._rqContext.Response.SetAppPathModifier(AppPathModifierFromSessionId(this._rqId));

            HttpRequest request = this._rqContext.Request;

            string url = request.Path;

            string queryStringText = request.QueryStringText;

            if ((queryStringText != null) && (queryStringText.Length > 0))

            {

                url = url + "?" + queryStringText;

            }

            this._rqContext.Response.Redirect(url, false);

            this._rqAr.Complete(true, null, null);

            IAsyncResult result = this._rqAr;

            application.CompleteRequest();

            return result;

      }

}

In the above code snippet, if the rqId string is null, then the Session.Create method is called.

Session is an internal class within the System.Web.SessionState namespace which has a static method Create with the following definition

internal static string Create(ref RandomNumberGenerator randgen)

{

    if (randgen == null)

    {

        randgen = new RNGCryptoServiceProvider();

    }

    byte[] data = new byte[15];

    randgen.GetBytes(data);

    return Encode(data);

}

Once the session id is generated, depending on how the cookieless attribute is set in the web.config (set to true or false) file; the session id is either added to the cookies collection or added to the URL. 

Scenario 1 : Cookieless attribute set to false

If the cookieless attribute is set to false, then the session id is added to the cookies collection by making a call to the CreateSessionCookie method

private static HttpCookie CreateSessionCookie(string id)

{

    HttpCookie cookie = new HttpCookie("ASP.NET_SessionId", id);

    cookie.Path = "/";

    return cookie;

}

After the cookie is created, it is added to the Response.Cookies collection. I was able to check the request and response headers using the fiddler tool (www.fiddlertool.com). 

HTTP Request Header :

GET /webapplication1/webform1.aspx HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: en-us
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727)
Host: win2k3-6114
Proxy-Connection: Keep-Alive

HTTP Response Header :

HTTP/1.1 200 OK
Date: Tue, 29 May 2007 07:44:27 GMT
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Set-Cookie: ASP.NET_SessionId=iddajxme35irfr45tcynode1; path=/
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 662

Notice the name of the cookie in the response header. You will also see this in the IIS log, once you enable the Cookie field for the specific web site and access the aspx page.  

IIS Log:

#Fields: date time s-sitename s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Cookie) sc-status sc-substatus sc-win32-status

2007-05-28 05:04:03 W3SVC1 65.52.76.126 GET /webapplication1/webform1.aspx - 80 - 65.52.76.126 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.2;+.NET+CLR+1.1.4322;+InfoPath.2;+.NET+CLR+2.0.50727) ASP.NET_SessionId=iddajxme35irfr45tcynode1 200 0 0

Scenario 2 - Cookieless attribute set to true

If the cookieless attribute is set to true, then the session id is added to the url. In this case, two trips are made to the server. First time, when the page is requested, the server responds with status code 302 (object moved) and in the next request, the server responds with status code 200 (OK. The client request has succeeded). This is because once the session id is added to the url, the Response.Redirect method is called. Notice the request and the response headers below. 

HTTP Request Header :  

GET /webapplication1/webform1.aspx HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: en-us
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727)
Host: win2k3-6114
Proxy-Connection: Keep-Alive

HTTP Response Header :

HTTP/1.1 302 Found
Date: Tue, 29 May 2007 08:06:19 GMT
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Location: /webapplication1/(n2xrh3452rylcuevsv103cep)/webform1.aspx
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 662

HTTP Request Header :  

GET /webapplication1/(n2xrh3452rylcuevsv103cep)/webform1.aspx HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Accept-Language: en-us
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727)
Host: win2k3-6114
Proxy-Connection: Keep-Alive

HTTP Response Header :

HTTP/1.1 200 OK
Date: Tue, 29 May 2007 08:06:19 GMT
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 662

You will not see the cookie being set in the response headers. 

If you check the URL, it will look something like this

https://<ServerName>/webapplication1/(n2xrh3452rylcuevsv103cep)/webform1.aspx 

In the IIS log, you will see two entries for webform1.aspx page, one with status code 302 and the next one with status code 200. However, the cookie value will be empty.  

IIS Log:  

#Fields: date time s-sitename s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Cookie) sc-status sc-substatus sc-win32-status

2007-05-29 08:06:19 W3SVC1 65.52.76.126 GET /webapplication1/webform1.aspx - 80 - 65.52.76.126 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.2;+.NET+CLR+1.1.4322;+InfoPath.2;+.NET+CLR+2.0.50727) - 302 0 0

2007-05-29 08:06:19 W3SVC1 65.52.76.126 GET /webapplication1/webform1.aspx - 80 - 65.52.76.126 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.2;+.NET+CLR+1.1.4322;+InfoPath.2;+.NET+CLR+2.0.50727) - 200 0 0 

I hope you enjoyed reading this article.