Click here to Skip to main content
15,895,843 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.5K   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 
The paradigm of session state and forms authentication are not related and the cookies serve different purposes.

If we view this from the perspective of the most common session state store, in-proc, this may not give the desired results and in fact may result in subtle bugs that steal your beer.

If, for some reason, the appdomain cycles, the forms ticket will still be valid but the session id is not.

The desire to couple session state with the auth ticket is not new and is as not-such-a-great idea as it ever was. Wink | ;)

Nice presentation though.

Cheers,
Sky

EDIT: as I read your code again, I do realize that you are creating your own session Id, but unless the store is out of proc, an appdomain cycle will render the guid orphaned.

Can you describe to me a scenario in which coupling the session and auth would be beneficial? it might help me gain perspective on your intentions.
GeneralRe: a not so subtle problem with this idea.. Pin
Paulo Morgado15-Apr-10 15:38
professionalPaulo Morgado15-Apr-10 15:38 

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.