生产中随机 ASP.NET Core 身份注销

Dav*_*wek 1 asp.net-identity asp.net-core

我有一个 ASP.NET Core MVC Web 应用程序,它使用身份来处理用户帐户身份验证和授权。在我的本地 IIS Express 上运行该应用程序时,一切正常。将应用程序部署到共享网络服务器后,我开始注意到登录的用户帐户会以看似随机的间隔被注销。通过实验,我能够确定无论帐户处于活动状态还是空闲状态,都会发生注销。它们的发生没有重复的时间间隔,并且与我在 cookie 上设置的任何到期时间完全无关。Web 应用程序中的每个视图都会发生注销,因此我无法将问题固定到任何特定的控制器。此外,我对应用程序的已发布版本和本地测试版本使用相同的数据库,因此使用相同的用户帐户。我任何人都知道从哪里开始寻找解决方案,我将不胜感激。

Dav*_*wek 7

我发布这个问题是因为有一个很好的答案可以解决 90% 的问题,但是在过去几天我一直在搜索的多个论坛中,没有一个有公认的答案。我发布这个答案来解决这个问题。该问题的根本原因是 IIS 应用程序池正在重置或回收,并且在多个应用程序使用它的共享主机上,这种情况可能会相当频繁地发生。正如上面链接中所建议的,如果 IIS 应用程序池回收,则必须使用数据保护来保留密钥。这是原始答案中提供的代码。

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

此代码将添加到中,ConfigureServices因为Startup.cs 我的应用程序托管在共享服务器上,所以使用.PersistKeysToFileSystem不是一个选项,所以我使用 DbContext 保留密钥,如下所示:

            services.AddDataProtection().PersistKeysToDbContext<MyKeysContext>()
            .SetDefaultKeyLifetime(TimeSpan.FromDays(90));
Run Code Online (Sandbox Code Playgroud)

基于本文,我构建MyKeysContext如下。

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

然后在ConfigureServices中创建了一个类,名称如下:Startup.csMyKeysContext

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在我的主机上创建了数据库,这可能会有所不同,因此我省略了此步骤。然后我像这样将迁移应用到数据库。

Add-Migration AddDataProtectionKeys -Context MyKeysContext 
Update-Database -Context MyKeysContext
Run Code Online (Sandbox Code Playgroud)