I do not manage to keep users logged in for more than 30 minutes.
Lets take default Visual Studio example "ASP.NET Core Web Application" -> .NET Framework 4.6.1 + ASP.NET Core 2.0 + MVC + Individual User Accounts.
ConfigureServices:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Configure:
app.UseAuthentication();
Action Login:
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
If user logs in + remember me (isPersistent = true) user gets rejected after 30 minutes. You can navigate between pages or reopen browser during those 30 minutes and everything is ok. But after 30 minutes you are asked to login again.聽
Setting this does not solve the problem:
services.ConfigureApplicationCookie(options => {
聽 options.ExpireTimeSpan = TimeSpan.FromDays(1);
});
Can you check the security stamp column for your users? 30 minutes is the default timespan for the cookie to be rechecked against the security stamp for the user, i.e. if the user changes his password, that will expire all login cookies...
If there is something wrong with the security stamp storage for your users, this would cause what you are seeing
Thanks for reply. How should I identify a problem with security stamp?
In my database it looks like this:
Then I mention 30 minutes, nothing is done during this interval that could change password or any of user data. I just refresh the page.
Edit: Should I change the default ValidationInterval and how? if this is safe to change it
You can try nulling out the security stamp validator logic to see if that fixes the issue to start:
services.ConfigureApplicationCookie(o => o.Events = new CookieAuthenticationEvents())
ok. after setting this I got logged out in 2 minutes 30 seconds.
What does the cookie header actually look like?
By saying cookie header you mean this:
Is there a place somewhere to set options.SecurityStampValidationInterval in ASP.NET Core 2.0?
This option was previously available in services.AddIdentity<>(options =>...) in ASP.NET Core 1.1.
Is services.ConfigureApplicationCookie defined before or after the services.AddIdentity? If you define it before the services.AddIdentity, your custom values will be overwritten.
And this is how you can change the ValidationInterval interval:
services.Configure<SecurityStampValidatorOptions>(options =>
{
// enables immediate logout, after updating the user's stat.
options.ValidationInterval = TimeSpan.Zero;
});
Strange things happens... My current CofigureServices method looks like this:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<SecurityStampValidatorOptions>(options =>
{
// enables immediate logout, after updating the user's stat.
options.ValidationInterval = TimeSpan.Zero;
});
services.AddMvc();
and i can login. TimeSpan.Zero does not behave as you have written.
Thank you @VahidN and @HaoK . Setting ValidationInterval to more than 30 minutes, seems to solve the problem.
options.ValidationInterval = TimeSpan.FromHours(12);
However, options.ValidationInterval = TimeSpan.Zero; does not work as you have noted; user does not get logged out instantly.
Now if you would not mind, please explain me shortly how does this ValidationInterval work. Is it global for the whole webapplication? I mean that:
And since options.ValidationInterval is no longer under services.AddIdentity, I would expect to find this change mentioned in https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x
SecurityStampValidator will be called for every single request to the server, but it will decide based on the ValidationInterval value and cookie issue time to determine when it should check the validity of the cookie again. If you set the ValidationInterval to zero, it will check and call the ValidateSecurityStampAsync method every time. So it's not related to the ExpireTimeSpan value. It's about the SecurityStamp property value of the current user. This value (SecurityStamp) will be changed internally by the framework if you update the user's properties.
If you call services.ConfigureApplicationCookie after the services.AddIdentity, you can change the default value of the ExpireTimeSpan. Because the AddIdentity method sets the default cookie's settings too.
It seems there was a big gap in my understanding about how does this all work. I also found that I have lied a little. So to finish up for other as stupid as me.
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<SecurityStampValidatorOptions>(options => options.ValidationInterval = TimeSpan.FromSeconds(10));
services.AddAuthentication()
.Services.ConfigureApplicationCookie(options =>
{
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
});
According my understanding this works like this:
options.ValidationInterval = TimeSpan.FromSeconds(10)). options.ExpireTimeSpan = TimeSpan.FromMinutes(30);, but can be extended with options.SlidingExpiration = true; if page is refreshed or navigated._userManager.UpdateSecurityStampAsync(user); just after successful login. Because this updates security stamp and next options.ValidationInterval validation will fail.I had this problem as well when updating to 2.0, but the cause was that I using signInManager.SignInAsync with a non existent user (I'm handling the logins manually using an API, not a good idea).
I'm not using existent users and it works fine when setting the cookie opt ExpireTimeSpan to higher than 30 minutes.
@gtarsia
I had this problem when I am using Cookie authentication without identity setup. Does anyone know what is the maximum value for the ValidationInterval. I set it like 7 days, but it expires already in 30 minutes or redirected me to log in page.
` services.AddAntiforgery(options =>
{
options.Cookie.Expiration = TimeSpan.FromDays(1);
options.Cookie.Name = "M";
options.HeaderName = "VerificationTkn";
});
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
//options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(
CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.Cookie.Expiration = TimeSpan.FromDays(1);
options.ExpireTimeSpan = TimeSpan.FromDays(1);
options.LoginPath = "/Account/Index";
options.LogoutPath = "/Account/SignOut";
options.ReturnUrlParameter = "ReturnUrl";
//options.Events.OnRedirectToLogin = context =>
//{
// context.Response.Headers["Location"] = context.RedirectUri;
// context.Response.StatusCode = 401;
// return Task.CompletedTask;
//};
});
services.Configure<SecurityStampValidatorOptions>(options =>
{
// enables immediate logout, after updating the user's stat.
options.ValidationInterval = TimeSpan.FromDays(1);
});
services.AddMvc();`
In my AccountController.cs:
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
items, new AuthenticationProperties
{
AllowRefresh = true,
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddDays(1)
});
Hi,
I've struggled on this a bit too and I've found that for SecurityStampValidator can validate your security stamp:
Then you can set ValidationInterval to any value suitable to validate the security stamp.
Hope it will help someone like me wondering why the session does not keep more than 30 minutes 馃槂
Most helpful comment
Is
services.ConfigureApplicationCookiedefined before or after theservices.AddIdentity? If you define it before theservices.AddIdentity, your custom values will be overwritten.And this is how you can change the
ValidationIntervalinterval: