1

I have an ASP.NET Core MVC web application that uses Identity to handle user account Authentication and Authorization. When running the app on my local IIS express everything was working properly. After deploying the app to a shared web server I started to notice that the logged-in user accounts would get logged out at seemingly random intervals. Through experimentation, I was able to determine that the log-outs were occurring whether the account was active or idle. They were occuring at no recuring time interval and completely unrelated to any expiry time that I set on my cookies. The logouts were occuring on every view in the web app so I couldn't pin the issue to any particular controller. Also I use the same Database for the published and the local testing version of the app and therefore the same user accounts. I anyone has an idea where to start looking for a solution it would be greatly appreciated.

  • Please provide enough code so others can better understand or reproduce the problem. – Reza Heidari Apr 19 '22 at 01:16
  • The issue should be reproducible in a new ASP.Net core web app project if the option for single sign on user accounts is selected as that code wasn't altered. – Overfloater Apr 20 '22 at 02:53

2 Answers2

7

I posted this question because there is a great answer that 90% solves the issue Here however of the multiple forums that I have been scouring over the last few days there are none with an accepted answer. I am posting this answer to address this. The underlying cause of the issue is that IIS application pool is being reset or recyling and on a shared host with multiple applications using it this can be happening fairly frequently. As is suggested in the above link Data Protection has to be used to persist the keys if IIS application pool recycles. Here is the code offered in the original answer.

services.AddDataProtection()
            .PersistKeysToFileSystem(new System.IO.DirectoryInfo("SOME WHERE IN STORAGE"))
            //.ProtectKeysWithCertificate(new X509Certificate2());
            .SetDefaultKeyLifetime(TimeSpan.FromDays(90));

This code is to be added in ConfigureServices in Startup.cs As my application is being hosted on a shared server using .PersistKeysToFileSystem was not an option so instead I persisted the keys using DbContext like this:

            services.AddDataProtection().PersistKeysToDbContext<MyKeysContext>()
            .SetDefaultKeyLifetime(TimeSpan.FromDays(90));

Based on This article here I build MyKeysContext as follows.

    // Add a DbContext to store your Database Keys
services.AddDbContext<MyKeysContext>(options =>
    options.UseSqlServer(
        Configuration.GetConnectionString("MyKeysConnection")));

In ConfigureServices in Startup.cs and then created a class called MyKeysContext as follows:

using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;
namespace WebApp1
{
 public class MyKeysContext : DbContext, IDataProtectionKeyContext
 {
    // A recommended constructor overload when using EF Core 
    // with dependency injection.
        public MyKeysContext(DbContextOptions<MyKeysContext> options) 
        : base(options) { }

        // This maps to the table that stores keys.
     public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
    }
}

I created the database on my Host this will probably be different so I have omitted this step. then I applied the migrations to the database like this.

Add-Migration AddDataProtectionKeys -Context MyKeysContext 
Update-Database -Context MyKeysContext
0

I also faced this problem. When I run the application from Visual Studio, It works fine but when I published it to IIS Server, I wouldn't be able to keep logged in. When I log in, It logs me in but when I refresh the page or do something, It redirects me back to Login Page. So I then changed the application pool.

You can create a new application pool in IIS with .NET 4.0 as Framework dedicated for your ASP.NET Core Application.

IIS Configuration

IIS Configuration 2

If you use .NET 2.0 pool, the user sessions will not be persisted and when the website will be reloaded, The user will be logged out. Make sure that the Application Pool you are using should not have any other Applications running.