1
Vote

SystemWebCookieManager issue

description

There is a documentation page System.Web response cookie integration issues that proposes to use SystemWebCookieManager as a workaround. However, SystemWebCookieManager has a major issue.

How to reproduce the issue:
  1. On dev machine setup any timezone between UTC +1 and +12
  2. Setup cookie authentication and specify ExpireTimeSpan for the CookieAuthenticationOptions to 10 minutes
  3. Try to sign in with persistent cookie
Actual result: server makes a response with already expired authentication cookie.

For example, if you are in UTC +2 timezone and it's 12:00 on your machine, then you will receive .AspNet.Cookie cookie with Expires equal to 8:10, instead of 10:10

Why it happens:
In the CookieAuthenticationHandler.ApplyResponseGrantAsync method there is the following code:
if (signInContext.Properties.IsPersistent)
{
  DateTimeOffset expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan);
  signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime;
}
Even though, expiresUtc is a UTC time, the result of expiresUtc.ToUniversalTime().DateTime returns DateTime with Kind equals to DateTimeKind.Unspecified. That's why Expires is converted to UTC twice.

In order fix it, SystemWebCookieManager need to be updated. Instead of
cookie.Expires = options.Expires.Value;
there must be
cookie.Expires = DateTime.SpecifyKind(options.Expires.Value, DateTimeKind.Utc);

comments