Cookie身份验证提前到期

时间:2018-04-18 20:35:08

标签: c# asp.net-mvc asp.net-core-2.0

问题

在我的ASP.NET MVC Core 2.0应用程序中,我已设置使用cookie身份验证方案而不使用Identity,因为我们拥有自己的后端身份验证存储和api。

每次验证和授权都能完美运行。

但是,无论登录/会话在大约30分钟后过期。您可以看到我们将身份验证cookie和会话cookie的超时设置为120分钟。

申请信息:

  • 平台:.Net 4.7.x(Windows)
  • 框架:Asp.Net Core 2.x
  • IIS用作代理服务器

欢迎任何有关如何解决此问题的帮助或意见

代码

更新:将services.AddMemoryCache()替换为services.AddDistributedRedisCache(..) - 测试以了解其工作原理

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDistributedRedisCache(options =>
        {
            options.Configuration = "localhost";
            options.InstanceName = "CoreTestInstance";
        });

    services.AddAuthentication("CookieAuthenticationScheme")
        .AddCookie("CookieAuthenticationScheme", options => 
        {
            options.Cookie.Name = authSettings.Name;
            options.Cookie.HttpOnly = false;
            options.Cookie.Expiration = TimeSpan.FromMinutes(120);
            options.ExpireTimeSpan = TimeSpan.FromMinutes(120);
            options.AccessDeniedPath = new PathString("/Errors/StatusCodeErrors/401");
            options.LoginPath = "/Account/Login";
        });
        // services.AddMemoryCache();
        services.AddSession(options =>
        {
            options.Cookie.Name = sessSettings.Name;
            options.Cookie.HttpOnly = false;
            options.IdleTimeout = TimeSpan.FromMinutes(120);
        });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Errors/Default");
    }
    app.UseStatusCodePagesWithRedirects("/Errors/StatusCodeErrors/{0}");
    app.UseStaticFiles();
    app.UseAuthentication();
    app.UseSession();
    app.UseMvc();
}

AccountController.cs

[HttpPost("Login")]
public async Task<IActionResult> Login(AccountModel model)
{
    var claims = new List<Claim>();
    claims.Add(new Claim(ClaimTypes.Name, model.UserName));
    claims.Add(new Claim(ClaimTypes.Role, "Administrator", ClaimValueTypes.String, model.UserName));

    var identity = new ClaimsIdentity(claims, "login");
    var principal = new ClaimsPrincipal(identity);
    await HttpContext.SignInAsync("CookieAuthenticationScheme", principal);
}

2 个答案:

答案 0 :(得分:2)

您正在使用与进程绑定的内存中会话。 IIS中的该过程是您的应用程序池。默认情况下,应用程序池会在一段时间后自动回收。当它回收时,需要你的会话。

使用persistent session store:SQL Server,Redis等(会话使用分布式缓存,因此设置持久会话的方式是设置持久性分布式缓存存储。)

答案 1 :(得分:0)

感谢Chris Pratt让我朝着正确的方向前进。迁移到Redis有助于提高性能,分布式缓存是正确的方法。

然而,Redis没有解决我的问题,不管我的设置如何,应用程序在90分钟后仍然超时。

由于我们使用IIS,我最终不得不更改 AppPool 中的设置,以最终使会话符合我的超时而不是AppPool。

  • 对于AppPool,单击“高级设置”并进行以下更改:
    • 部分:流程模型
      • 空闲超时(分钟)= 0(禁用超时,以便应用程序池永远不会因空闲而关闭)
      • 空闲超时操作=挂起(挂起的工作进程仍处于活动状态,但会被分页到磁盘,从而减少了它消耗的系统资源)
    • 部分:回收
      • 常规时间间隔(分钟)= 0(设置为0表示apppool不会回收)

注意:除非您在同一台服务器上运行了大量应用程序,否则上述设置不应影响其他应用程序。我建议您在使用之前详细研究设置,以确保它们适合您。

最后,我使用各种设置运行了几个测试(我们将它们存储在appsettings.json中),暂停时间为2分钟,10分钟,1小时,最后2个小时,所有设置均按要求工作。