会话注销过早
Session logged out too soon
我将 ASP.NET Core 2.1 与 Microsoft Identity 一起使用,用户抱怨他们在大约 30 分钟的不活动后不断被重定向到登录屏幕。我在 ExpireTimeSpan 中设置了 60 分钟,但它永远不会持续那么久。有什么建议吗?
这是我在 Startup.cs 文件中的内容:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IRFDbRepository, RFDbRepository>();
var connection = _configuration.GetConnectionString("RFDbConnection");
services.Configure<ConnectionStrings>(_configuration.GetSection("ConnectionStrings"));
services.AddDbContext<IdentityDbContext>(options => options.UseSqlServer(connection));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddRazorPagesOptions(options =>
{
options.AllowAreas = true;
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.AddIdentity<User, UserRole>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<User>, UserStore>();
services.AddTransient<IRoleStore<UserRole>, RoleStore>();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Identity/Account/Login";
options.LogoutPath = "/Identity/Account/Logout";
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.SlidingExpiration = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IRFDbRepository rFDbRepository)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
loggerFactory.AddFile(_configuration.GetValue<string>("Logging:LogFile"));
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "ActionApi",
template: "api/{controller}/{action}/{id?}");
});
}
我终于找到了这个问题的根源。
ASP.NET Core 2.1 中的 Identity 存在问题,如果您实现了自己的 UserStore 版本而不是 IUserSecurityStampStore,则将跳过大多数与安全标记相关的功能。
当您调用 AddIdentity() 时,它会每 30 分钟对 securityStamp 进行一次验证检查。
这会导致令人困惑的行为,即用户在 30 分钟后注销,即使 cookie 没有过期。
显然 ASP.NET Core 2.2 中对此有一个修复,这里有更多详细信息
https://github.com/aspnet/Identity/issues/1880
与此同时,您可以让您的 UserStore 实现 IUserSecurityStampStore,或者按照我现在的快速修复方法,将其添加到您的 startup.cs 中,这样可以将失败间隔时间从 30 分钟增加到到 10 小时。
services.Configure(o => o.ValidationInterval = TimeSpan.FromHours(10));
之前的答案只是将问题从每 30 分钟发生一次更改为每 10 小时发生一次,这并不理想。
在我的例子中,我根本没有将这种类型的用户存储在数据库中,所以当然无法检查安全标记 - 所以在我的例子中,我只是像这样禁用了验证:
services.ConfigureApplicationCookie(opt =>
{
opt.Events.OnValidatePrincipal = (ctx) =>
{
// Do not validate principal (i.e. security stamp) for our custom users
// the default behavior will log them out every SecurityStampValidatorOptions.ValidationInterval
if (ctx.Principal.HasClaim(x => x.Type == CmsClaimTypes.ClaimType)) return Task.CompletedTask;
return SecurityStampValidator.ValidatePrincipalAsync(ctx);
};
});
我将 ASP.NET Core 2.1 与 Microsoft Identity 一起使用,用户抱怨他们在大约 30 分钟的不活动后不断被重定向到登录屏幕。我在 ExpireTimeSpan 中设置了 60 分钟,但它永远不会持续那么久。有什么建议吗?
这是我在 Startup.cs 文件中的内容:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IRFDbRepository, RFDbRepository>();
var connection = _configuration.GetConnectionString("RFDbConnection");
services.Configure<ConnectionStrings>(_configuration.GetSection("ConnectionStrings"));
services.AddDbContext<IdentityDbContext>(options => options.UseSqlServer(connection));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddRazorPagesOptions(options =>
{
options.AllowAreas = true;
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.AddIdentity<User, UserRole>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<User>, UserStore>();
services.AddTransient<IRoleStore<UserRole>, RoleStore>();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Identity/Account/Login";
options.LogoutPath = "/Identity/Account/Logout";
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.SlidingExpiration = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IRFDbRepository rFDbRepository)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
loggerFactory.AddFile(_configuration.GetValue<string>("Logging:LogFile"));
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "ActionApi",
template: "api/{controller}/{action}/{id?}");
});
}
我终于找到了这个问题的根源。
ASP.NET Core 2.1 中的 Identity 存在问题,如果您实现了自己的 UserStore 版本而不是 IUserSecurityStampStore,则将跳过大多数与安全标记相关的功能。
当您调用 AddIdentity() 时,它会每 30 分钟对 securityStamp 进行一次验证检查。
这会导致令人困惑的行为,即用户在 30 分钟后注销,即使 cookie 没有过期。
显然 ASP.NET Core 2.2 中对此有一个修复,这里有更多详细信息
https://github.com/aspnet/Identity/issues/1880
与此同时,您可以让您的 UserStore 实现 IUserSecurityStampStore,或者按照我现在的快速修复方法,将其添加到您的 startup.cs 中,这样可以将失败间隔时间从 30 分钟增加到到 10 小时。
services.Configure(o => o.ValidationInterval = TimeSpan.FromHours(10));
之前的答案只是将问题从每 30 分钟发生一次更改为每 10 小时发生一次,这并不理想。
在我的例子中,我根本没有将这种类型的用户存储在数据库中,所以当然无法检查安全标记 - 所以在我的例子中,我只是像这样禁用了验证:
services.ConfigureApplicationCookie(opt =>
{
opt.Events.OnValidatePrincipal = (ctx) =>
{
// Do not validate principal (i.e. security stamp) for our custom users
// the default behavior will log them out every SecurityStampValidatorOptions.ValidationInterval
if (ctx.Principal.HasClaim(x => x.Type == CmsClaimTypes.ClaimType)) return Task.CompletedTask;
return SecurityStampValidator.ValidatePrincipalAsync(ctx);
};
});