diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs index e093e87b7..f41199752 100644 --- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -270,14 +270,14 @@ public async virtual Task SignInAsync(ClaimsPrincipal user, AuthenticationProper if (!signInContext.Properties.ExpiresUtc.HasValue) { - signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.Cookie.Expiration ?? default(TimeSpan)); + signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan); } await Events.SigningIn(signInContext); if (signInContext.Properties.IsPersistent) { - var expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.Cookie.Expiration ?? default(TimeSpan)); + var expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan); signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime(); } diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs index 4f8b201ad..ec67ecc18 100644 --- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs @@ -21,7 +21,6 @@ public class CookieAuthenticationOptions : AuthenticationSchemeOptions SameSite = SameSiteMode.Lax, HttpOnly = true, SecurePolicy = CookieSecurePolicy.SameAsRequest, - Expiration = TimeSpan.FromDays(14), }; /// @@ -29,6 +28,7 @@ public class CookieAuthenticationOptions : AuthenticationSchemeOptions /// public CookieAuthenticationOptions() { + ExpireTimeSpan = TimeSpan.FromDays(14); ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; SlidingExpiration = true; Events = new CookieAuthenticationEvents(); @@ -42,7 +42,6 @@ public CookieAuthenticationOptions() /// defaults to . /// defaults to true. /// defaults to . - /// defaults to 14 days. /// /// /// @@ -60,9 +59,7 @@ public CookieAuthenticationOptions() /// The default is true, which means the cookie will only be passed to http requests and is not made available to script on the page. /// /// - /// controls how much time the cookie will remain valid from the point it is created. The expiration - /// information is in the protected cookie ticket. Because of that an expired cookie will be ignored - /// even if it is passed to the server after the browser should have purged it + /// is currently ignored. Use to control lifetime of cookie authentication. /// /// public CookieBuilder Cookie @@ -140,6 +137,19 @@ public CookieBuilder Cookie /// public ITicketStore SessionStore { get; set; } + /// + /// + /// Controls how much time the authentication ticket stored in the cookie will remain valid from the point it is created + /// The expiration information is stored in the protected cookie ticket. Because of that an expired cookie will be ignored + /// even if it is passed to the server after the browser should have purged it. + /// + /// + /// This is separate from the value of , which specifies + /// how long the browser will keep the cookie. + /// + /// + public TimeSpan ExpireTimeSpan { get; set; } + #region Obsolete API /// /// @@ -201,23 +211,6 @@ public CookieBuilder Cookie /// [Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.SecurePolicy) + ".")] public CookieSecurePolicy CookieSecure { get => Cookie.SecurePolicy; set => Cookie.SecurePolicy = value; } - - /// - /// - /// This property is obsolete and will be removed in a future version. The recommended alternative is on . - /// - /// - /// Controls how much time the cookie will remain valid from the point it is created. The expiration - /// information is in the protected cookie ticket. Because of that an expired cookie will be ignored - /// even if it is passed to the server after the browser should have purged it - /// - /// - [Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.Expiration) + ".")] - public TimeSpan ExpireTimeSpan - { - get => Cookie.Expiration ?? default(TimeSpan); - set => Cookie.Expiration = value; - } #endregion } } diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj b/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj index fb20a55b9..712aa8177 100644 --- a/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj +++ b/src/Microsoft.AspNetCore.Authentication.Cookies/Microsoft.AspNetCore.Authentication.Cookies.csproj @@ -19,8 +19,4 @@ - - - - diff --git a/test/Microsoft.AspNetCore.Authentication.Test/CookieTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/CookieTests.cs index 1471caf44..c2d843bf1 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/CookieTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/CookieTests.cs @@ -143,6 +143,23 @@ public async Task SignInCausesDefaultCookieToBeCreated() Assert.DoesNotContain("; secure", setCookie); } + [Fact] + public async Task CookieExpirationOptionIsIgnored() + { + var server = CreateServerWithServices(s => s.AddAuthentication().AddCookie(o => + { + o.Cookie.Name = "TestCookie"; + // this is currently ignored. Users should set o.ExpireTimeSpan instead + o.Cookie.Expiration = TimeSpan.FromDays(10); + }), SignInAsAlice); + + var transaction = await SendAsync(server, "http://example.com/testpath"); + + var setCookie = transaction.SetCookie; + Assert.StartsWith("TestCookie=", setCookie); + Assert.DoesNotContain("; expires=", setCookie); + } + [Fact] public async Task SignInWrongAuthTypeThrows() { @@ -277,7 +294,7 @@ public async Task CookieStopsWorkingAfterExpiration() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = false; }, SignInAsAlice); @@ -306,7 +323,7 @@ public async Task CookieExpirationCanBeOverridenInSignin() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = false; }, context => @@ -339,7 +356,7 @@ public async Task ExpiredCookieWithValidatorStillExpired() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.Events = new CookieAuthenticationEvents { OnValidatePrincipal = ctx => @@ -367,7 +384,7 @@ public async Task CookieCanBeRejectedAndSignedOutByValidator() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = false; o.Events = new CookieAuthenticationEvents { @@ -395,7 +412,7 @@ public async Task CookieNotRenewedAfterSignOut() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = false; o.Events = new CookieAuthenticationEvents { @@ -431,7 +448,7 @@ public async Task CookieCanBeRenewedByValidator() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = false; o.Events = new CookieAuthenticationEvents { @@ -476,7 +493,7 @@ public async Task CookieCanBeRenewedByValidatorWithSlidingExpiry() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.Events = new CookieAuthenticationEvents { OnValidatePrincipal = ctx => @@ -520,7 +537,7 @@ public async Task CookieValidatorOnlyCalledOnce() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = false; o.Events = new CookieAuthenticationEvents { @@ -569,7 +586,7 @@ public async Task ShouldRenewUpdatesIssuedExpiredUtc(bool sliding) DateTimeOffset? lastExpiresDate = null; var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = sliding; o.Events = new CookieAuthenticationEvents { @@ -619,7 +636,7 @@ public async Task CookieExpirationCanBeOverridenInEvent() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = false; o.Events = new CookieAuthenticationEvents() { @@ -656,7 +673,7 @@ public async Task CookieIsRenewedWithSlidingExpiration() { var server = CreateServer(o => { - o.Cookie.Expiration = TimeSpan.FromMinutes(10); + o.ExpireTimeSpan = TimeSpan.FromMinutes(10); o.SlidingExpiration = true; }, SignInAsAlice);