Showing posts with label Single Sign On. Show all posts
Showing posts with label Single Sign On. Show all posts

Tuesday, August 18, 2009

ASP.Net - Single Sign On & Session Handling

The part 1 of this post can be read here.

Problem Statement
So single sign on is all up and running and users are able to login once and access all the sub domains. Now, if you are saving any user data in session then you should remember that every time the user jumps to another sub domain, application reloads the session, which means that your application would be performing the tasks added to any session based event every time user changes the domain. This can become a performance nightmare depending on how much data you are storing and if you are making any db calls.

Another problem would be that you won't be able to share data across sub domains like some kind of flag etc., because session is getting initialized every time the sub domain changes.

Solution
The simplest solution is that you share the session across all sub domains. Here's what you need to do,

1. Make your custom session class by simply inheriting the

System.Web.SessionState.SessionIDManager, System.Web.SessionState.ISessionIDManager

and implement the ISessionIDManager interface's methods. Here's what the end result will be,

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public class MySession : System.Web.SessionState.SessionIDManager, System.Web.SessionState.ISessionIDManager

{

#region ISessionIDManager Members

string System.Web.SessionState.ISessionIDManager.CreateSessionID(HttpContext context)
{
return base.CreateSessionID(context);
}

string System.Web.SessionState.ISessionIDManager.GetSessionID(HttpContext context)
{
return base.GetSessionID(context);
}

void System.Web.SessionState.ISessionIDManager.Initialize()
{
base.Initialize();
}

bool System.Web.SessionState.ISessionIDManager.InitializeRequest(HttpContext context, bool suppressAutoDetectRedirect, out bool supportSessionIDReissue)
{
return base.InitializeRequest(context, suppressAutoDetectRedirect, out supportSessionIDReissue);
}

void System.Web.SessionState.ISessionIDManager.RemoveSessionID(HttpContext context)
{
base.RemoveSessionID(context);
}

void System.Web.SessionState.ISessionIDManager.SaveSessionID(HttpContext context, string id, out bool redirected, out bool cookieAdded)
{
base.SaveSessionID(context, id, out redirected, out cookieAdded);
HttpContext.Current.Response.Cookies["ARSessionCookie"].Domain = FormsAuthentication.CookieDomain;
}

bool System.Web.SessionState.ISessionIDManager.Validate(string id)
{
return base.Validate(id);
}

#endregion
}


2. Add the following to your web.config

[sessionState sessionIDManagerType="MySession" cookieName="MySessionCookie"][/sessionState>]

Note : Replace [ with <> .

You are done! Now user's session will be shared across all the sub domains (considering that it's the same server) .

Friday, June 19, 2009

ASP.Net - Single Sign On

Task : As soon as user logs into the website, he remains logged in even if he move across sub domains.

eg. if user logged in to the website using www.domain.com, now via a link, he moves to subdomain.domain.com then he should not be required to re login.

Solution :

In order to achieve this, you need to take two actions,

1. Make the following changes in web.config :

Within System.web element, add the following,

<authentication mode="Forms">
<forms path="/" name=".cookieName" cookieless="UseCookies" domain=".domainname.com"/>

</authentication>

If your site's domain address is "www.sitename.com" then domain will be set as ".sitename.com"

2. Add the following code piece to the code which runs on logout,

HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

if (cookie != null)

{

cookie.Domain = FormsAuthentication.CookieDomain;

cookie.Expires = DateTime.Now.AddDays(-360);

Response.Cookies.Add(cookie);

}

FormsAuthentication.SignOut();

If you use a single domain then it's not required that you explicitly expire the authentication cookie, a simple ForsmAuthentication.SignOut() should work fine, but once the cookie domain is set then you will need to expire the cookie explicitly, otherwise your user will remain logged in.

Once you have done both the actions, your job is done and your user's login should work for the main domain and all the sub domains.

Next Problem >> Though this solution will keep the user logged in but every time when he will move to a new sub domain, his session will renew, any information which you placed into the session at the time of logging in will be lost too. The informatino can be refilled but more than that it's a performance issue.

Let's discuss this in Part 2.