I have a site that is using Asp.Net’s forms authentication, with sliding expiration. A user may log in and make some operations (requests), and after 30 minutes (for example) from her last action, she will be logged out.
However – what if I want to make a request that will not reset that timeout? For example, I may want to send an Ajax request for tracking the user, periodically check for notices, etc. How can I prevent that “system” request from extending the authentication cookie?
As it turns out, there is a simple way of doing that, once you understand exactly how sliding authentication works in asp.net.
I won’t go into too much detail, but the basic mechanism is:
- After authentication, an authentication cookie is sent to the user, with expiration time of 30 minutes (or whatever you defined).
- The authentication cookie contains an encrypted data, which is really the authentication ticket.
- The ticket contains information related to the authentication, and the expiration time. Note the browsers don’t send the cookies’ expiration times when making a request, so that data is included in the authentication ticket instead.
- For actions the user does in the first half of the expiration period (that is, the first 15 minutes), nothing happens. The authentication timeout does not reset.
- On requests that happen on the second half of the expiration period, the timeout is reset, and the expiration is extended by another 30 minutes.
So, there is a chance our response will contain a new auth cookie, with extended expiration time. If the user is inactive, and our periodical action is the only thing happening, one of the responses will contain a new cookie, and the user will be logged in indefinitely.
So, how an we prevent that? This is as simple as removing the cookie from the response:
///<summary>
/// Prevent the auth cookie from being reset for this action, allows you to
/// have requests that do not reset the login timeout.
/// </summary>
public class DoNotResetAuthCookieAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var response = filterContext.HttpContext.Response;
response.Cookies.Remove(FormsAuthentication.FormsCookieName);
}
}
Use of this action is pretty simple:
[DoNotResetAuthCookie]
public ActionResult SampleAction()
{
return Json(new {Request.IsAuthenticated, CookiesCount = Response.Cookies.Count});
}
Notes
See Also