After searching around and reading through articles and answers I came up with this implementation for extending the cookie of Forms Authentication. But I am not 100% sure that I did not introduce any vulnerabilities and now I provided here for review.
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
//... other code
// old implementation
FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
string userData = "userdata";
var cookie = ExtendAuthCookie(FormsAuthentication.GetAuthCookie(model.Username, model.RememberMe), userData);
System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
//... other code
}
private HttpCookie ExtendAuthCookie(HttpCookie authCookie, string userData)
{
var originalTicket = GetOriginalTicket(authCookie);
System.Web.Security.FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
2,
originalTicket.Name,
originalTicket.IssueDate,
originalTicket.Expiration,
originalTicket.IsPersistent,
userData, // Extending with user data
originalTicket.CookiePath
);
String strTicket = FormsAuthentication.Encrypt(ticket);
if (string.IsNullOrEmpty(strTicket))
{
throw new HttpException("Unable to encrypt cookie ticket.");
}
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strTicket);
cookie.HttpOnly = true;
cookie.Secure = true;
return cookie;
}
private FormsAuthenticationTicket GetOriginalTicket(HttpCookie authCookie)
{
var cookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket == null)
{
throw new ArgumentNullException("ticket");
}
if (ticket.Expired)
{
throw new InvalidOperationException("ticket");
}
return ticket;
}