12

I'm trying to use identity with cookie authentication in an asp.netcore 2.0 MVC app. I want to set session timeout to something like 150 days, so users that log in don't need to log in again during a big period of time. I set options.ExpireTimeSpan = TimeSpan.FromDays(150); but sessions are closed after a few minutes, even if the user is actively using the app.

I'm following the official docs and I have this on my Startup.cs:

Within ConfigureServices method:

    services.AddIdentity<User, Role>()
            .AddDefaultTokenProviders();

    // Identity Services
    services.AddTransient<IUserStore<User>, UserService>();
    services.AddTransient<IRoleStore<Role>, RoleService>();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings
        options.Password.RequireDigit = false;
        options.Password.RequiredLength = 8;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireUppercase = false;
        options.Password.RequireLowercase = false;
        options.Password.RequiredUniqueChars = 3;

        // Lockout settings
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
        options.Lockout.MaxFailedAccessAttempts = 10;
        options.Lockout.AllowedForNewUsers = true;

        // User settings
        options.User.RequireUniqueEmail = true;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;                
        options.ExpireTimeSpan = TimeSpan.FromDays(150);
        options.LoginPath = "/User/Login"; 
        options.LogoutPath = "/User/Logout"; 
        options.AccessDeniedPath = "/User/AccessDenied";
        options.SlidingExpiration = true;
    });  

    services.AddMvc(config =>
    {
        var policy = new AuthorizationPolicyBuilder()
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(policy));
    });

In the Configure method I call app.UseAuthentication();

And to do the login, I do:

var result = await _signInManager.PasswordSignInAsync(email, password, isPersistent: true, lockoutOnFailure: false);

Am I missing any config? I theory I'm setting expiry time to 150 days.

Thanks in advance.

EDIT:* It looks like the problem is the ValidationInterval. I found this issue: https://github.com/aspnet/Identity/issues/1513

I tried setting the ValidationInterval to a large value and now sessions are not closed and users are not logged out unexpectedly. This is the code to set the interval:

services.Configure<SecurityStampValidatorOptions>(options => 
            options.ValidationInterval = TimeSpan.FromDays(150));

I guess I'll have to see how the security stamp validator works and define the validation interval properly, so sessions are not unexpectedly closed but also, a modification in a user's privileges is not ignored due to a stale cookie.

alesvi
  • 147
  • 1
  • 1
  • 9
  • The expiries you're setting only apply to the cookie (client-side), there's also a server-side component that must be persisted. That happens via `IDistributedCache`, which defaults to the `MemoryDistributedCache` implementation. In-memory persistence, in other words. In-memory is process-bound, so if the app is stopped and restarted, App Pool recycles in IIS, server restarts, etc. anything there goes away. Additionally, if you have multiple workers, each has it's own separate and distinct memory. Configure your distributed cache to use SQL Server or Redis. – Chris Pratt Apr 24 '18 at 16:56
  • Ok. Thanks for your answer! I will check the server side part. Thanks again. – alesvi Apr 24 '18 at 17:05
  • Just to clarify @ChrisPratt , I'm not persisting any data in the session. I'm only using Identity to manage authentication. I thought the authentication ticket stored in the cookie was enough to know if the ticket is expired or not. According to the docs, _ExpireTimeSpan Controls how much time the authentication ticket stored in the cookie remains valid from the point it's created._ So, why is server-side persistence needed? – alesvi Apr 25 '18 at 09:47
  • 1
    You're talking about authentication timeout, not Session, which is a different thing. There are separate cookies for "session" (which you're not using), and authentication, which you are. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-2.2#session-state – philw Jan 30 '19 at 10:48

0 Answers0