Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Cookie身份验证提前到期 问题_C#_Asp.net Mvc_Asp.net Core 2.0 - Fatal编程技术网

C# Cookie身份验证提前到期 问题

C# Cookie身份验证提前到期 问题,c#,asp.net-mvc,asp.net-core-2.0,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.NETCore2.x 用作代理服务器的IIS 欢迎提供有关如何解决此问题的任何帮助或意见 代码

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

身份验证和授权每次都能完美地工作

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

应用程序信息:

  • 平台:.Net 4.7.x(Windows)
  • 框架:Asp.NETCore2.x
  • 用作代理服务器的IIS
欢迎提供有关如何解决此问题的任何帮助或意见 代码 更新:
服务.AddMemoryCache()
替换为
服务.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();
}
[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);
}
AccountController.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();
}
[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);
}
[HttpPost(“登录”)]
公共异步任务登录(AccountModel)
{
var索赔=新列表();
添加(新索赔(ClaimTypes.Name,model.UserName));
添加(新声明(ClaimTypes.Role,“Administrator”,ClaimValueTypes.String,model.UserName));
var标识=新的索赔实体(索赔,“登录”);
var principal=新的ClaimsPrincipal(身份);
等待HttpContext.SignInAsync(“CookieAuthenticationScheme”,主体);
}

您正在使用与进程相关的内存会话。IIS中的进程就是您的应用程序池。默认情况下,应用程序池在一段时间后自动回收。当它循环使用时,它会占用您的会话

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

多亏了正确启动我。迁移到Redis有助于提高性能和分布式缓存是正确的选择

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

由于我们使用IIS,我最终不得不更改应用程序池中的设置,以最终使会话遵守我的超时而不是应用程序池的超时

  • 对于AppPool,单击高级设置并进行以下更改:
    • 部分:过程模型
      • 空闲超时(分钟)=0(禁用超时,以便应用程序池永远不会因空闲而关闭)
      • Idle Time out Action=Suspend(挂起的工作进程保持活动状态,但被调出到磁盘,从而减少它所消耗的系统资源)
    • 部分:回收
      • 常规时间间隔(分钟)=0(设置为0意味着apppool将不会回收)
注意:以上设置不应影响其他应用程序,除非在同一服务器上运行大量应用程序。我建议您在使用这些设置之前仔细研究它们,以确保它们适合您。
最后,我使用各种设置(我们将它们存储在appsettings.json中)运行了几个测试,超时时间为2分钟、10分钟、1小时,最后是2小时,所有测试都按要求进行。

没错,但是应用程序池过期时间设置为300分钟,并且存在相同的行为。不过,我将研究持久会话,看看它是否适合我们。好吧,一般来说,在生产中,您不应该在内存中使用任何东西。无论它是否也解决了这个问题,您都应该使用持久存储。好的一点,通常我们在生产中使用sql server,我将在我的开发框中尝试一下。