Fix cookie regression (#1811)

This commit is contained in:
Hao Kung 2018-07-11 13:14:51 -07:00 committed by GitHub
parent 26fbad0614
commit d2a8d3a61c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 5 deletions

View File

@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
}
}
private void RequestRefresh(AuthenticationTicket ticket)
private void RequestRefresh(AuthenticationTicket ticket, ClaimsPrincipal replacedPrincipal = null)
{
var issuedUtc = ticket.Properties.IssuedUtc;
var expiresUtc = ticket.Properties.ExpiresUtc;
@ -97,14 +97,15 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
_refreshIssuedUtc = currentUtc;
var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
_refreshExpiresUtc = currentUtc.Add(timeSpan);
_refreshTicket = CloneTicket(ticket);
_refreshTicket = CloneTicket(ticket, replacedPrincipal);
}
}
private AuthenticationTicket CloneTicket(AuthenticationTicket ticket)
private AuthenticationTicket CloneTicket(AuthenticationTicket ticket, ClaimsPrincipal replacedPrincipal)
{
var principal = replacedPrincipal ?? ticket.Principal;
var newPrincipal = new ClaimsPrincipal();
foreach (var identity in ticket.Principal.Identities)
foreach (var identity in principal.Identities)
{
newPrincipal.AddIdentity(identity.Clone());
}
@ -183,7 +184,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
if (context.ShouldRenew)
{
RequestRefresh(result.Ticket);
RequestRefresh(result.Ticket, context.Principal);
}
return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));

View File

@ -900,6 +900,80 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
Assert.Null(FindClaimValue(transaction5, ClaimTypes.Name));
}
[Fact]
public async Task CookieCanBeReplacedByValidator()
{
var server = CreateServer(o =>
{
o.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = ctx =>
{
ctx.ShouldRenew = true;
ctx.ReplacePrincipal(new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice2", "Cookies2"))));
return Task.FromResult(0);
}
};
},
context =>
context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
Assert.NotNull(transaction2.SetCookie);
Assert.Equal("Alice2", FindClaimValue(transaction2, ClaimTypes.Name));
}
[Fact]
public async Task CookieCanBeUpdatedByValidatorDuringRefresh()
{
var replace = false;
var server = CreateServer(o =>
{
o.ExpireTimeSpan = TimeSpan.FromMinutes(10);
o.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = ctx =>
{
if (replace)
{
ctx.ShouldRenew = true;
ctx.ReplacePrincipal(new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice2", "Cookies2"))));
ctx.Properties.Items["updated"] = "yes";
}
return Task.FromResult(0);
}
};
},
context =>
context.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
Assert.Equal("Alice", FindClaimValue(transaction2, ClaimTypes.Name));
var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
Assert.Equal("Alice", FindClaimValue(transaction2, ClaimTypes.Name));
Assert.Null(FindPropertiesValue(transaction3, "updated"));
replace = true;
var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
Assert.NotNull(transaction4.SetCookie);
Assert.Equal("Alice2", FindClaimValue(transaction4, ClaimTypes.Name));
Assert.Equal("yes", FindPropertiesValue(transaction4, "updated"));
replace = false;
var transaction5 = await SendAsync(server, "http://example.com/me/Cookies", transaction4.CookieNameValue);
Assert.Equal("Alice2", FindClaimValue(transaction5, ClaimTypes.Name));
Assert.Equal("yes", FindPropertiesValue(transaction4, "updated"));
}
[Fact]
public async Task CookieCanBeRenewedByValidatorWithSlidingExpiry()
{
@ -1730,6 +1804,16 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
return claim.Attribute("value").Value;
}
private static string FindPropertiesValue(Transaction transaction, string key)
{
var property = transaction.ResponseElement.Elements("extra").SingleOrDefault(elt => elt.Attribute("type").Value == key);
if (property == null)
{
return null;
}
return property.Attribute("value").Value;
}
private static async Task<XElement> GetAuthData(TestServer server, string url, string cookie)
{
var request = new HttpRequestMessage(HttpMethod.Get, url);