18

Few days ago I have decided to upgrade my web app from asp.net core 1.1 to core 2.0. Everything seems to work fine after minor changes, except authentication does not persist longer than 20-30 minutes.

We can take the default example from Visual Studio because I experience the same problem in my own webapp and in "ASP.NET Core Web Application" -> .NET Framework 4.6.1 + ASP.NET Core 2.0 + MVC + Individual User Accounts.

Configuration is default and should be users logged in for 14 days:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();
...
    services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
    app.UseAuthentication();
...
}

The PROBLEM is that user only stays logged in for 20-30 minutes. When user logs in ("Remember me" is selected) you can navigate through pages, and even reopen the browser, user stays logged in. Thus it seems authentication cookie is working. However, after 20-30 minutes user is logged out automatically, or should I say cookie expires (I do not know what happens). You can login again, and the game starts all over again.

I have tried setting Application cookie expiration, but this does not solve the problem:

services.ConfigureApplicationCookie(options => {
    options.ExpireTimeSpan = TimeSpan.FromDays(1); // Just shortens cookie expiration time, but still logs out users after 20-30 minutes.
});

Since it takes 20-30 minutes, it looks like default session timeout:

services.AddSession(options =>
{
    options.Cookie.Expiration = TimeSpan.FromDays(1); // This throws an error "Expiration cannot be set for the cookie defined by SessionOptions"
    options.IdleTimeout = TimeSpan.FromDays(1); // This changes session sliding expiration time... 
});

The same implementation worked fine in ASP.NET Core 1.1.

halfer
  • 19,824
  • 17
  • 99
  • 186
Shaltukaz
  • 311
  • 1
  • 2
  • 6

5 Answers5

13

Ok then I have spammed different forums regarding this :) And here are my discoveries. Original https://github.com/aspnet/Identity/issues/1389

It seems there was a big gap in my understanding about how does this all work. I also found that I have lied a little. So to finish up for other as stupid as me.

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();
services.Configure<SecurityStampValidatorOptions>(options => options.ValidationInterval = TimeSpan.FromSeconds(10));
services.AddAuthentication()
    .Services.ConfigureApplicationCookie(options =>
    {
        options.SlidingExpiration = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    });

According my understanding this works like this:

  • the check if user is logged happens ~every 10 seconds, depending on requests ratio. Server checks security stamps upon every request to the server options.ValidationInterval = TimeSpan.FromSeconds(10)).

  • cookie is valid at minimum for 30 minutes options.ExpireTimeSpan = TimeSpan.FromMinutes(30);, but can be extended with options.SlidingExpiration = true; if page is refreshed or navigated.

  • important! do not be too "smart" like me and do no run _userManager.UpdateSecurityStampAsync(user); just after successful login. Because this updates security stamp and next validation validation will fail.

Shaltukaz
  • 311
  • 1
  • 2
  • 6
  • I found the above code not working. My time span was never set. Instead doing `services.AddAuthentication().AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => { options.ExpireTimeSpan = System.TimeSpan.FromMinutes(authenticationTimeOut); });` does the trick. – Jari Turkia Jan 17 '19 at 11:50
1

The server retains a session for a limited time after the last request. You can either set the session timeout or use the default value of 20 minutes.

To change the default value edit the ConfigureServices method.

public void ConfigureServices(IServiceCollection services)
    {
        ....
        services.AddSession(options => { 
                options.IdleTimeout = TimeSpan.FromMinutes(30); 
                options.CookieName = ".MyApplication";
            });
    }
Chris Hawkes
  • 11,923
  • 6
  • 58
  • 68
  • yes i understand this, but it worked earlier in core 1.1 or 1.0. did they removed this feature? I was able to keep using by website after few days. – Shaltukaz Aug 22 '17 at 19:46
  • Unfortunately, I'm not sure when or if they changed it. – Chris Hawkes Aug 22 '17 at 19:49
  • Thank you for the example. I have tried to set idletimeout to 60 minutes. But after 20 minutes - log out. So either i cannot change session timeout here, or authentication process does not depend on session. – Shaltukaz Aug 22 '17 at 20:25
1

I'm not an expert, and I'm sure this post will reveal that, but I've had this problem before running older versions of ASP.NET (Web Forms) on IIS.

The problem was that IIS has its own settings for session timeout which are set on the server itself, and AFAIK they cannot be in any way overridden by anything you configure on your site before deployment.

This makes sense especially for shared servers serving ASP.NET Web Forms-- they don't want their clients' users accumulating who-knows-how-much session data and having to keep it available indefinitely.

Using AJAX calls to keep the session alive should work, I think.

Bennyboy1973
  • 3,413
  • 2
  • 11
  • 16
  • Topic isn't Webforms. There are approaches for timeout in .NET Core which address the timeout problems. See [this link](https://stackoverflow.com/a/45838230/1659999) for example in this thread. – Fawad Raza Nov 05 '19 at 08:44
  • @FawadRaza Would I be able to use a database for the session data instead? I have a feeling this is what is happening to me as I'll stay logged in on my localhost for a long time, but once I deploy to my shared server, it logs out the user in 10-20 minutes. – Scott Uphus Jul 26 '22 at 13:25
0

Please see this topic it help to you make session live for long time.

Keep Session Live

Nripendra Ojha
  • 379
  • 2
  • 14
0

It's possible to set the cookie lifetime with the cookie policy:

services.AddCookiePolicy(opts => {
    opts.CheckConsentNeeded = ctx => false;
    opts.OnAppendCookie = ctx => {
        ctx.CookieOptions.Expires = DateTimeOffset.UtcNow.AddDays(14);
    };
});

Source

perryflynn
  • 301
  • 1
  • 8