C# Cookie身份验证提前到期 问题
在我的ASP.NET MVC Core 2.0应用程序中,我设置了使用cookie身份验证方案,而不使用Identity,因为我们有自己的后端身份验证存储和api 身份验证和授权每次都能完美地工作 但是,无论登录/会话在大约30分钟后过期。您可以看到,我们正在将身份验证cookie和会话cookie的超时设置为120分钟 应用程序信息: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 欢迎提供有关如何解决此问题的任何帮助或意见 代码
- 平台:.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,我将在我的开发框中尝试一下。