Cookieless Session
Introduction
There are various reasons to adopt cookieless session. Recently,
I implemented cookieless session and in that process, I went through many
articles on the internet, but none of them have gone in depth to bring it all
together.
To implement cookieless sessions, you don't have to modify your
programming model—a simple change in the web.config file does the trick. But with that
can come uncovered scenario and you would end up spending considerable time
fixing it up just like I did. So let's get started with what and how it has to
be changed to make cookieless work for you with no issues.
Now let us go through the steps one by one:
Step
1: Adjust the web.config file
Interestingly enough, you don't have to change anything in your
ASP.NET application to enable cookieless sessions, except the following
configuration setting.
<sessionState cookieless="true" />
<authentication mode="Forms">
<forms loginUrl="Login.aspx" protection="All" timeout="30" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="default.aspx" cookieless="UseUri" enableCrossAppRedirects="true"/>
</authentication>
Step
2: Adjust all of the URL navigations in aspx files
Be careful, the following code breaks the session:
<a runat="server" href="/test/page.aspx">Click</a>
To use absolute URLs, resort to a little trick that uses the
ApplyAppPathModifier
method on the HttpResponse
class. The ApplyAppPathModifier
method takes a string
representing a URL and returns an absolute URL that embeds
session information.<a runat="server" href="<% =Response.ApplyAppPathModifier("page.aspx")%>" >Click</a>
Step
3: Adjust all of the URL navigations in aspx.cs files
If the URL is set in the code, you need to do it in the
following way:
this.Tab2.Url = Response.ApplyAppPathModifier("Page.aspx");
Step
4: Create HttpModule to rewrite your incoming URL for enabling cross domain
posts
using System;
using System.Collections.Specialized;
using System.Web;
using System.Web.SessionState;
using System.IO;
using System.Text;
namespace CustomModule
{
public sealed class CookielessPostFixModule : IHttpModule
{
public void Init (HttpApplication application)
{
application.EndRequest += new
EventHandler(this.Application_EndRequest);
}
private string ConstructPostRedirection(HttpRequest req,
HttpResponse res)
{
StringBuilder build = new StringBuilder();
build.Append(
"<html>\n<body>\n<form name='Redirect' method='post' action='");
build.Append(res.ApplyAppPathModifier(req.Url.PathAndQuery));
build.Append("' id='Redirect' >");
foreach (object obj in req.Form)
{
build.Append(string.Format(
"\n<input type='hidden' name='{0}' value = '{1}'>",
(string)obj,req.Form[(string)obj]));
}
build.Append(
"\n<noscript><h2>Object moved <input type='submit'
value='here'></h2>
</noscript>");
build.Append(@"</form>
<script language='javascript'>
<!--
document.Redirect.submit();
// -->
</script>
");
build.Append("</body></html>");
return build.ToString();
}
private bool IsSessionAcquired
{
get
{
return (HttpContext.Current.Items["AspCookielessSession"]!=null &&
HttpContext.Current.Items["AspCookielessSession"].ToString().Length>0);
}
}
private string ConstructPathAndQuery(string[] segments)
{
StringBuilder build = new StringBuilder();
for (int i=0;i<segments.Length;i++)
{
if (!segments[i].StartsWith("(")
&& !segments[i].EndsWith(")"))
build.Append(segments[i]);
}
return build.ToString();
}
private bool IsCallingSelf(Uri referer,Uri newpage)
{
if(referer==null || newpage==null)
return false;
string refpathandquery = ConstructPathAndQuery(
referer.Segments);
return refpathandquery == newpage.PathAndQuery;
}
private bool ShouldRedirect
{
get
{
HttpRequest req = HttpContext.Current.Request;
return (!IsSessionAcquired
&& req.RequestType.ToUpper() == "POST"
&& !IsCallingSelf(req.UrlReferrer,req.Url));
}
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpRequest req = HttpContext.Current.Request;
HttpResponse res = HttpContext.Current.Response;
if (!ShouldRedirect) return;
res.ClearContent();
res.ClearHeaders();
res.Output.Flush();
char[] chr = ConstructPostRedirection(req,res).ToCharArray();
res.Write(chr,0,chr.Length);
}
public void Dispose()
{}
}
}
For the above to be effective, make the below change to your web
config:
<httpModules>
<add type="CookielessPostFixModule, OurModule"
name="CookielessPostFixModule" />
</httpModules>
Comments
Post a Comment