ASP.NET 核心 Web 应用被迫频繁登录
ASP.NET Core Web App forced to login frequently
我有一个 ASP.NET Core 3.1 Web 应用程序,它使用 ASP.NET Identity 进行身份验证。当我在本地 运行 时,一切正常,但是当我部署到托管服务提供商时,我发现用户被要求非常频繁地登录(仅在几分钟不活动后)。我此时的猜测是时机与应用程序池回收有关,因为我可以通过手动回收应用程序池来强制登录。不幸的是,我无法控制服务器上的应用程序池设置 - 空闲超时设置为 5 分钟。
如果我理解 ASP.NET 身份(这可能有点牵强),身份验证令牌存储在 cookie 中并随每个请求一起传输。我看不出应用程序池回收会对验证该 cookie 产生什么影响。如果它以会话状态存储在服务器上,我可以看到发生这种情况,但我认为这不会发生。
我的 ConfigureServices
方法非常常用,除此之外我还向标准用户和角色对象添加了一些字段。
public void ConfigureServices(IServiceCollection services) {
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection"))
);
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options => {
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 8;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
options.SignIn.RequireConfirmedEmail = true;
options.SignIn.RequireConfirmedPhoneNumber = false;
options.User.RequireUniqueEmail = false;
});
services.ConfigureApplicationCookie(options => {
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.Lax;
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.LoginPath = "/Identity/Account/Login";
options.ExpireTimeSpan = TimeSpan.FromDays(30);
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
services.AddScoped<IUserClaimsPrincipalFactory<User>, ApplicationUserClaimsPrincipalFactory>();
services.AddSingleton<IEmailService, EmailService>();
services.AddTransient<DatabaseInitializationHelper>();
services.AddControllersWithViews();
services.AddRazorPages();
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddOptions<CaptchaSettings>().Bind(Configuration.GetSection("Captcha"));
services.AddTransient<CaptchaVerificationService>();
}
Configure
方法也很标准。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if (env.IsDevelopment() || env.EnvironmentName == "Dev") {
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else {
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
//app.UseSession();
app.UseEndpoints(endpoints => {
endpoints.MapControllerRoute(
name: "Default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "MembersArea",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "api",
pattern: "_api/{controller}/{id?}");
endpoints.MapRazorPages();
});
}
这是否与应用程序池回收有关?如果是这样,有什么办法可以在不访问应用程序池设置的情况下解决这个问题?如果不是,还有什么可能导致它?
原来这与数据保护有关,我可以使用 解决它。显然,我的托管服务提供商限制了最终阻止访问通常存储此类信息的位置的权限。
我有一个 ASP.NET Core 3.1 Web 应用程序,它使用 ASP.NET Identity 进行身份验证。当我在本地 运行 时,一切正常,但是当我部署到托管服务提供商时,我发现用户被要求非常频繁地登录(仅在几分钟不活动后)。我此时的猜测是时机与应用程序池回收有关,因为我可以通过手动回收应用程序池来强制登录。不幸的是,我无法控制服务器上的应用程序池设置 - 空闲超时设置为 5 分钟。
如果我理解 ASP.NET 身份(这可能有点牵强),身份验证令牌存储在 cookie 中并随每个请求一起传输。我看不出应用程序池回收会对验证该 cookie 产生什么影响。如果它以会话状态存储在服务器上,我可以看到发生这种情况,但我认为这不会发生。
我的 ConfigureServices
方法非常常用,除此之外我还向标准用户和角色对象添加了一些字段。
public void ConfigureServices(IServiceCollection services) {
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection"))
);
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options => {
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 8;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
options.SignIn.RequireConfirmedEmail = true;
options.SignIn.RequireConfirmedPhoneNumber = false;
options.User.RequireUniqueEmail = false;
});
services.ConfigureApplicationCookie(options => {
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.Lax;
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.LoginPath = "/Identity/Account/Login";
options.ExpireTimeSpan = TimeSpan.FromDays(30);
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
services.AddScoped<IUserClaimsPrincipalFactory<User>, ApplicationUserClaimsPrincipalFactory>();
services.AddSingleton<IEmailService, EmailService>();
services.AddTransient<DatabaseInitializationHelper>();
services.AddControllersWithViews();
services.AddRazorPages();
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddOptions<CaptchaSettings>().Bind(Configuration.GetSection("Captcha"));
services.AddTransient<CaptchaVerificationService>();
}
Configure
方法也很标准。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if (env.IsDevelopment() || env.EnvironmentName == "Dev") {
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else {
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
//app.UseSession();
app.UseEndpoints(endpoints => {
endpoints.MapControllerRoute(
name: "Default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "MembersArea",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "api",
pattern: "_api/{controller}/{id?}");
endpoints.MapRazorPages();
});
}
这是否与应用程序池回收有关?如果是这样,有什么办法可以在不访问应用程序池设置的情况下解决这个问题?如果不是,还有什么可能导致它?
原来这与数据保护有关,我可以使用