Branislav Abadjimarinov's technical blog

Renew User in the same Request in asp.net while using forms authentication with cookies

Posted in C#, ASP.NET by Branislav Abadjimarinov on 1/24/2010 3:52:00 AM - CST

In ASP.NET forms authentication the usual authentication flow goes like this:

  • a user submits his credentials;
  • they are  validated against database, web.config or other data source;
  • an authentication cookie is issued and added to the current response (which is not sent yet);
  • the cookie is sent along with the response;
  • on the next request from that user the cookie is decrypted and the current Security Principal is initialised with the data;

While this is good for most cases it has one flow - immediately after the authentication cookie is issued the current Security Principal for the request is outdated. You can check this with the following code:

if(Membership.ValidateUser(userName, password))
{
    FormsAuthentication.SetAuthCookie(userName, false);
    bool isAuthenticated = Request.IsAuthenticated; // isAuthenticated is false
}

This outcome is logical because of the authentication flow but some times it is confusing and can cause problems. A possible solution is to renew the information for the Current Security Principal for the request. This can be done with the following code:
public void RenewCurrentUser()
{
  System.Web.HttpCookie authCookie =
    System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
  if (authCookie != null)
  {
    FormsAuthenticationTicket authTicket = null;
    authTicket = FormsAuthentication.Decrypt(authCookie.Value);

    if (authTicket != null && !authTicket.Expired)
    {
      FormsAuthenticationTicket newAuthTicket = authTicket;

      if (FormsAuthentication.SlidingExpiration)
      {
        newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket);
      }
      string userData = newAuthTicket.UserData;
      string[] roles = userData.Split(',');

      System.Web.HttpContext.Current.User =
        new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles);
    }
  }
}

You can check if the solution works like this:

if(Membership.ValidateUser(userName, password))
{
    FormsAuthentication.SetAuthCookie(userName, false);
    bool isAuthenticated = Request.IsAuthenticated; // isAuthenticated is false
    RenewCurrentUser();
    isAuthenticated = Request.IsAuthenticated; // isAuthenticated is true
}
 

Comments

Trackback  on 3/17/2011 1:34:24 PM - CST

Add Comment

Please enter your name. Please enter a valid email. Please enter a valid website.
Please supply a comment.
© Copyright 2017 Powered by AtomSite 1.3.0.0