.NET Core 2 CookieAuthentication ignores expiration time span
Solution 1
Use IsPersistent = true
Example
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, client.Id),
new Claim(ClaimTypes.Role, client.Role)
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(identity),
new AuthenticationProperties
{
ExpiresUtc = DateTime.UtcNow.AddYears(1),
IsPersistent = true
});
Solution 2
The expiration date in Chrome represents the lifetime of the cookie in the browser not the timeout of the token. When using Identity Server 4 with ASP.NET Identity it is the cookie timeout of the Identity Server that comes into play here. After the client token expires the user is re-authenticated against Identity Server and since that token has not expired the client token is renewed. To set the expiration time on the Identity Server you must add the ConfigureApplicationCookiemiddleware in the Identity Server Startup.cs as follows:
services.AddAuthentication();
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Expiration = TimeSpan.FromDays(14);
options.ExpireTimeSpan = TimeSpan.FromDays(14);
options.SlidingExpiration = false;
});
services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);
Update for .net core 3.1 (cooke.expiration no longer required as a separate option):
services.AddAuthentication();
services.ConfigureApplicationCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(14);
options.SlidingExpiration = false;
});
services.AddMvc();
Solution 3
From Use cookie authentication without ASP.NET Core Identity, bolded for emphasis.
The TimeSpan after which the authentication ticket stored inside the cookie expires. ExpireTimeSpan is added to the current time to create the expiration time for the ticket. The ExpiredTimeSpan value always goes into the encrypted AuthTicket verified by the server. It may also go into the Set-Cookie header, but only if IsPersistent is set. To set IsPersistent to true, configure the AuthenticationProperties passed to SignInAsync. The default value of ExpireTimeSpan is 14 days.
Solution 4
Identity has dedicated cookie configuration options CookieAuthenticationOptions and cookie Expiration value has been decided to be ignored, some clarifications could be found here: Github issue Test reference
Related videos on Youtube
d03090
Updated on October 15, 2022Comments
-
d03090 about 1 year
I'm working on a .NET Core 2.1 Web application with
CookieAuthentication
. For some reason setting theExpireTimeSpan
andCookie.Expiration
on theCookieAuthenticationOptions
object doesn't have an effect on the Cookie lifetime. Chrome always displays the same expiration date of1969-12-31T23:59:59.000Z
. So after closing the browser window the cookie is gone.Startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddDistributedMemoryCache(); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = new PathString("/Account/Login/"); options.AccessDeniedPath = new PathString("/Account/Login/"); options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; options.Cookie.Expiration = TimeSpan.FromDays(14); options.ExpireTimeSpan = TimeSpan.FromDays(14); }); services.AddMvc(options => { options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); }); services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN"); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } var provider = new FileExtensionContentTypeProvider(); provider.Mappings[".tag"] = "riot/tag"; app.UseStaticFiles(new StaticFileOptions() { ContentTypeProvider = provider }); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
On SignIn I'm using this code
ClaimsPrincipal user = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, userId.Value.ToString()) }, CookieAuthenticationDefaults.AuthenticationScheme)); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);
I've tried putting
services.AddMvc
beforeservices.AddAuthentication
but it doesn't make a difference. I've also triedservices.ConfigureApplicationCookie
afterservices.AddAuthentication
like in this answer Cookie expiry in ASP.NET Core 2.0 with IdentityWhat am I missing?
-
momo over 5 yearsI would also recommend to add MinimumSameSitePolicy = SameSiteMode.Lax if you want to disable third-party usage for the cookie and to prevent CSRF attacks
-
Simon over 3 yearsSeem to be the wron answer. I get an error: Cookie.Expiration is ignored, use ExpireTimeSpan instead