Click here to Skip to main content
16,016,306 members
Articles / Web Development / ASP.NET

Coupling ASP.NET Session State With Forms Authentication

Rate me:
Please Sign up or sign in to vote.
4.75/5 (4 votes)
15 Apr 2010CPOL 19.8K   11   2
Coupling ASP.NET Session State With Forms Authentication
free hit counters

Today I was talking with João about a way to couple the lifetime of the ASP.NET session state with the lifetime of Forms Authentication ticket.

My idea was to store the session ID in the UserData property of the forms authentication ticket upon logon and retrieve it with a custom session ID manager.

The login code would be something like this:

C#
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
    bool isPersistent = this.Login1.RememberMeSet;
    string username = this.Login1.UserName;
    var ticket = new FormsAuthenticationTicket(
        0,
        username,
        DateTime.Now,
        DateTime.Now.AddMinutes(2),
        isPersistent,
        Guid.NewGuid().ToString("N"));

    // Encrypt the ticket.
    var encryptedTicket = FormsAuthentication.Encrypt(ticket);

    // Create the cookie.
    this.Response.Cookies.Add(new HttpCookie
	(FormsAuthentication.FormsCookieName, encryptedTicket));

    // Redirect back to original URL.
    this.Response.Redirect(FormsAuthentication.GetRedirectUrl(username, isPersistent));
}

For the purpose of this test, I am using a Guid as the session ID.

The session ID manager will return this session ID when queried by the session state HTTP module:

C#
public class SessionIdManager : global::System.Web.SessionState.ISessionIDManager
{
    #region ISessionIDManager Members

    public string CreateSessionID(HttpContext context)
    {
        return GetDummySessionIdOrRedirectToLoginPage(context);
    }

    public string GetSessionID(HttpContext context)
    {
        return GetSessionIdFromFormsIdentity(context);
    }

    public void Initialize()
    {
    }

    public bool InitializeRequest(HttpContext context, 
	bool suppressAutoDetectRedirect, out bool supportSessionIDReissue)
    {
        supportSessionIDReissue = false;
        return GetSessionIdFromFormsIdentity(context) == null;
    }

    public void RemoveSessionID(HttpContext context)
    {
    }

    public void SaveSessionID(HttpContext context, string id, 
	out bool redirected, out bool cookieAdded)
    {
        redirected = false;
        cookieAdded = false;
    }

    public bool Validate(string id)
    {
        return true;
    }

    #endregion

    private static string GetSessionIdFromFormsIdentity(HttpContext context)
    {
        var identity = context.User != null ? 
		context.User.Identity as FormsIdentity : null;

        if ((identity == null) || (identity.Ticket == null) || 
		string.IsNullOrEmpty(identity.Ticket.UserData))
        {
            return GetDummySessionIdOrRedirectToLoginPage(context);
        }
        else
        {
            return identity.Ticket.UserData;
        }
    }

    private static string GetDummySessionIdOrRedirectToLoginPage(HttpContext context)
    {
        if (context.Request.CurrentExecutionFilePath.Equals
	(FormsAuthentication.DefaultUrl, StringComparison.OrdinalIgnoreCase)
           || context.Request.CurrentExecutionFilePath.Equals
		(FormsAuthentication.LoginUrl, StringComparison.OrdinalIgnoreCase))
        {
            return Guid.NewGuid().ToString("N");
        }
        else
        {
            FormsAuthentication.RedirectToLoginPage();
            return null;
        }
    }
}

NOTE: Although this might work, it’s just an intellectual exercise and wasn’t fully tested.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Paulo Morgado
Portugal Portugal

Comments and Discussions

 
Generala not so subtle problem with this idea.. Pin
Sky Sanders15-Apr-10 15:24
Sky Sanders15-Apr-10 15:24 
GeneralRe: a not so subtle problem with this idea.. Pin
Paulo Morgado15-Apr-10 15:38
professionalPaulo Morgado15-Apr-10 15:38 

Thanks, Sky


That's why:


<quote>NOTE: Although this might work, it’s just an intellectual exercise and wasn’t fully tested.<quote>

Although my experience is that no ASP.NET production application that uses session state uses InProc, it does have the shortcommings you mention


This post was kind of a reply to a question I was asked and it was specifically on how to tie the authentication cookie with the session.


Although this usually requires matching configurations and, sometimes, custom session state storage providers, I do find usefull to have just one session that holds authentication, authorization and state - loosing one means you loose it all.


Paulo Morgado
Portugal - Europe's West Coast

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.