Because of the requirements of my project, I'm wanting to provide custom authenticate for my MVC controller actions. Therefore, I will not be using SetAuthCookie().
Intially I set a cookie as follows;
string userData = EncDec.MakeString(user.Email + "|" + user.UserId);
//the Cookie and FormsAuthenticationTicket expiration date/time is the same
DateTime cookieExpiry = DateTime.Now.AddMinutes(AccountPage.MvcApplication.COOKIE_EXPIRY_MINUTES);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // ticket version
user.UserName, // authenticated username
DateTime.Now, // issueDate
cookieExpiry, // expiryDate
false, // true to persist across browser sessions
userData, // can be used to store additional user data
FormsAuthentication.FormsCookiePath); // the path for the cookie
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
//create the cookie
HttpCookie cookie = new HttpCookie("ADV_" + Extensions.ControllerExtensionMethods.GetGuid(this), encryptedTicket);
cookie.Secure = true;
cookie.HttpOnly = true;
cookie.Expires = cookieExpiry;
Response.Cookies.Add(cookie);
The HttpCookie is being saved in the client browser with a encrypted FormsAuthenticationTicket.
Then within my controller actions, whenever I need to check and verify that the user is authenticated I call this method;
public static FormsAuthenticationTicket IsAuthenticated(string guid)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies["ADV_" + guid];
if (cookie != null)
{
string encryptedTicket = cookie.Value;
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket);
if (!ticket.Expired)
{
//if the user is authenticated and the cookie hasn't expired we increase the expiry of the cookie - keep alive
DateTime cookieExpiry = DateTime.Now.AddMinutes(AccountPage.MvcApplication.COOKIE_EXPIRY_MINUTES);
//create a new ticket based on the existing one
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(
ticket.Version, // ticket version
ticket.Name, // authenticated username
ticket.IssueDate, // issueDate
cookieExpiry, // expiryDate, changed to keep alive if user is navigating around site
false, // true to persist across browser sessions
ticket.UserData, // can be used to store additional user data
ticket.CookiePath); // the path for the cookie
string newEncryptedTicket = FormsAuthentication.Encrypt(newTicket);
//keep alive
HttpCookie newCookie = new HttpCookie("ADV_" + guid, newEncryptedTicket);
newCookie.Secure = true;
newCookie.HttpOnly = true;
newCookie.Expires = cookieExpiry;
HttpContext.Current.Response.Cookies.Set(newCookie);
return newTicket;
}
}
return null;
}
Every time the user is re-authenticated, I am increasing the time out of when the cookie will expire, so that the login is keep alive.
Everything seems to work fine, and the users are correctly authenticated, and if they aren't authenticated I redirect them to a login page, and they can't access methods if they aren't authenticated either.
My questions are:
- Is this way of dealing with the authentication secure.
- Is there anything I should be aware of, in terms of a security risk.
Thanks.
SetAuthCookie().This takes care of things automatically such as sliding expiration, which your code is showing you did not do right. For example, if you are extending the timeout by 10 minutes each time and I hit 10 pages on your site in under a minute, you are going to add 100 minutes to my cookie expiration time. If someone spends a few hours on your site, their cookie might not expire for years.