0

I am new to AspNetCore, its middleware and Identity. I'm building a very simple website where the user logs in and is allowed to check the usual Remember Me checkbox and stay logged in. The Remember Me isn't working and after about 10 to 15 minutes I'm redirected to the login page again. I see the cookie in the browser and its expiration date is indeed what I set it to: 30 days in the future. My code is below. I feel I'm missing something but I don't know what.

My Startup.cs class:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }

    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}").RequireAuthorization();

        endpoints.MapRazorPages();
    });
}

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

    services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();

    services.ConfigureApplicationCookie(options =>
    {
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromDays(30);
        options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
        options.SlidingExpiration = true;
        options.LoginPath = "/account/login";
        options.LogoutPath = "/account/logout";
        options.AccessDeniedPath = "/account/accessdenied";
    });

    services.AddControllersWithViews();

    services.AddRazorPages();
}

My AccountController login method:

[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginModel model)
{
    if (ModelState.IsValid)
    {
        var result = await _signInManager.PasswordSignInAsync(model.EmailAddress, model.Password, 
                                                              model.RememberMe, false);

        if (result.Succeeded)
            return RedirectToAction("index", "links");

        ModelState.AddModelError(string.Empty, "Invalid login");
    }

        return View(model);
}

My cookies in the browser enter image description here

Community
  • 1
  • 1
Keith
  • 922
  • 2
  • 10
  • 12

1 Answers1

0

After a couple weeks of googling I finally found the fix in this post. You have to configure data protection in order for the logins to persist. This solution also keeps users logged in after deployments and IIS restarts.

I added a machine key to the web.config as suggested in this post and then added data protection to the ConfigureServices method...

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
            // This helps surviving a restart: a same app will find back its keys. Just ensure to create the folder.
            .PersistKeysToFileSystem(new DirectoryInfo("\\MyFolder\\keys\\"))
            // This helps surviving a site update: each app has its own store, building the site creates a new app
            .SetApplicationName("MyWebsite")
            .SetDefaultKeyLifetime(TimeSpan.FromDays(90));
}

Read more here

Keith
  • 922
  • 2
  • 10
  • 12