Lukas Kubis
Lukas Kubis

Reputation: 929

ASP.NET Identity 2.0 prevent auth cookie expiration

I'm working on an application (ASP.NET MVC 5) where I want to prevent auth cookie expiration on a specific page (It's a huge form and it takes some time to fill in completely). What I have is:

ASP.NET Identity configuration in Startup.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, Guid>(
            validateInterval: TimeSpan.FromMinutes(15),
            regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
            getUserIdCallback: (id) => Guid.Parse(id.GetUserId()))
    },
    SlidingExpiration = true,
    ExpireTimeSpan = TimeSpan.FromMinutes(30)
});

SignIn method implementation in a Controller

AuthenticationManager.SignIn(new AuthenticationProperties()
{
    AllowRefresh = true,
    IsPersistent = isPersistent,
    ExpiresUtc = TimeSpan.FromMinutes(30)
}, identity);

jQuery method implementation on a specific page that makes post to a server each 10 minutes.

(function ($) {

    function keepSessionAlive() {
        $.post("/Resources/KeepSessionAlive");
    }

    // 10 minutes
    setInterval(keepSessionAlive, 60 * 1000 * 10);

})(jQuery);

KeepSessionAlive implementation in the Controller

//
// POST: /Resources/KeepSessionAlive/
[HttpPost]
public JsonResult KeepSessionAlive()
{
    if (HttpContext.Session != null)
        HttpContext.Session["KeepSessionAlive"] = DateTime.Now;
    return Json($"Last refresh {DateTime.Now.ToString("O")}");
}

Problem: When I navigate to the specific page, I can see the following post requests:

  1. /Resources/KeepSessionAlive - 200 OK
  2. /Resources/KeepSessionAlive - 200 OK
  3. /Resources/KeepSessionAlive - 401 Unauthorized

But after 30 minutes I get 401 unauthorized. What I'm doing wrong?

Btw. What is difference between CookieAuthenticationOptions.ExpireTimeSpan and AuthenticationProperties.ExpiresUtc. It must be same? How it behaves if I set them to different values? Thanks for clarification.

// EDIT:

I've found out that cookie expires after 15 minutes that is equal to validateInterval: TimeSpan.FromMinutes(15), but I thought it does not affect cookie expiration because this is a security feature which is used when you change a password or add an external login to your account.

Upvotes: 2

Views: 1759

Answers (1)

Lukas Kubis
Lukas Kubis

Reputation: 929

I don't understand it but when I've set up CookieAuthenticationOptions.ExpireTimeSpan and AuthenticationProperties.ExpiresUtc to the same value (30 minutes), it's started to work.

The final source code:

Startup.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    SlidingExpiration = true,
    ExpireTimeSpan = TimeSpan.FromMinutes(30),
    Provider = new CookieAuthenticationProvider
    {
        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, Guid>(
            validateInterval: TimeSpan.FromMinutes(30),
            regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
            getUserIdCallback: (id) => Guid.Parse(id.GetUserId()))
    }
});

SignIn

AuthenticationManager.SignIn(new AuthenticationProperties() { 
  IsPersistent = isPersistent }, identity);

jQuery

function keepSessionAlive() {
    $.ajax({
        type: "POST",
        cache: false,
        url: "/Resources/KeepSessionAlive",
        success: function (result) {
            console.debug("keepSessionAlive response [" + result + "]");
            window.setTimeout(keepSessionAlive, 60 * 1000 * 15); // 15 minutes
        }
    });
}
keepSessionAlive();

Upvotes: 3

Related Questions