Merge pull request #1812 from aspnet/haok/mg2.1
Merge release/2.1 -> release/2.2
This commit is contained in:
commit
e4b4bd3884
|
|
@ -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 issuedUtc = ticket.Properties.IssuedUtc;
|
||||||
var expiresUtc = ticket.Properties.ExpiresUtc;
|
var expiresUtc = ticket.Properties.ExpiresUtc;
|
||||||
|
|
@ -97,14 +97,15 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
_refreshIssuedUtc = currentUtc;
|
_refreshIssuedUtc = currentUtc;
|
||||||
var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
|
var timeSpan = expiresUtc.Value.Subtract(issuedUtc.Value);
|
||||||
_refreshExpiresUtc = currentUtc.Add(timeSpan);
|
_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();
|
var newPrincipal = new ClaimsPrincipal();
|
||||||
foreach (var identity in ticket.Principal.Identities)
|
foreach (var identity in principal.Identities)
|
||||||
{
|
{
|
||||||
newPrincipal.AddIdentity(identity.Clone());
|
newPrincipal.AddIdentity(identity.Clone());
|
||||||
}
|
}
|
||||||
|
|
@ -183,7 +184,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
|
|
||||||
if (context.ShouldRenew)
|
if (context.ShouldRenew)
|
||||||
{
|
{
|
||||||
RequestRefresh(result.Ticket);
|
RequestRefresh(result.Ticket, context.Principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
|
return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));
|
||||||
|
|
|
||||||
|
|
@ -900,6 +900,80 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
Assert.Null(FindClaimValue(transaction5, ClaimTypes.Name));
|
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]
|
[Fact]
|
||||||
public async Task CookieCanBeRenewedByValidatorWithSlidingExpiry()
|
public async Task CookieCanBeRenewedByValidatorWithSlidingExpiry()
|
||||||
{
|
{
|
||||||
|
|
@ -1730,6 +1804,16 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
return claim.Attribute("value").Value;
|
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)
|
private static async Task<XElement> GetAuthData(TestServer server, string url, string cookie)
|
||||||
{
|
{
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue