From cbbec15d37f85187d6d32252ed84887dde5b2798 Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Fri, 26 Aug 2016 11:46:29 -0700 Subject: [PATCH] Ignore null ExpiresUtc property in RequestRefresh Issue: https://github.com/aspnet/Security/issues/949 --- .../CookieAuthenticationHandler.cs | 16 ++++--- .../Cookies/CookieMiddlewareTests.cs | 45 +++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs index f11f69e1c9..7c583ed7e1 100644 --- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -57,11 +57,17 @@ namespace Microsoft.AspNetCore.Authentication.Cookies private void RequestRefresh(AuthenticationTicket ticket) { - _shouldRefresh = true; - var currentUtc = Options.SystemClock.UtcNow; - _refreshIssuedUtc = currentUtc; - var timeSpan = ticket.Properties.ExpiresUtc.Value.Subtract(ticket.Properties.IssuedUtc.Value); - _refreshExpiresUtc = currentUtc.Add(timeSpan); + var issuedUtc = ticket.Properties.IssuedUtc; + var expiresUtc = ticket.Properties.ExpiresUtc; + + if (issuedUtc != null && expiresUtc != null) + { + _shouldRefresh = true; + var currentUtc = Options.SystemClock.UtcNow; + _refreshIssuedUtc = currentUtc; + var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value); + _refreshExpiresUtc = currentUtc.Add(timeSpan); + } } private async Task ReadCookieTicket() diff --git a/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs index 942b1c4a5f..e6f881fefc 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -1214,6 +1214,51 @@ namespace Microsoft.AspNetCore.Authentication.Cookies Assert.Equal("Alice", FindClaimValue(transaction2, ClaimTypes.Name)); } + // Issue: https://github.com/aspnet/Security/issues/949 + [Fact] + public async Task NullExpiresUtcPropertyIsGuarded() + { + var builder = new WebHostBuilder() + .ConfigureServices(services => services.AddAuthentication()) + .Configure(app => + { + app.UseCookieAuthentication(new CookieAuthenticationOptions + { + Events = new CookieAuthenticationEvents + { + OnValidatePrincipal = context => + { + context.Properties.ExpiresUtc = null; + context.ShouldRenew = true; + return Task.FromResult(0); + } + } + }); + + app.Run(async context => + { + if (context.Request.Path == "/signin") + { + await context.Authentication.SignInAsync( + CookieAuthenticationDefaults.AuthenticationScheme, + new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))); + } + else + { + await context.Response.WriteAsync("ha+1"); + } + }); + }); + + var server = new TestServer(builder); + + var cookie = (await server.SendAsync("http://www.example.com/signin")).SetCookie.FirstOrDefault(); + Assert.NotNull(cookie); + + var transaction = await server.SendAsync("http://www.example.com/", cookie); + Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode); + } + private class NoOpDataProtector : IDataProtector { public IDataProtector CreateProtector(string purpose)