Merge branch 'tratcher/session' into dev

This commit is contained in:
Chris R 2017-03-31 13:42:16 -07:00
Родитель f3a8d848b7 a6f39abf96
Коммит 2912742bab
2 изменённых файлов: 193 добавлений и 3 удалений

Просмотреть файл

@ -236,8 +236,10 @@ namespace Microsoft.Owin.Security.Cookies
}
else if (_shouldRenew)
{
model.Properties.IssuedUtc = _renewIssuedUtc;
model.Properties.ExpiresUtc = _renewExpiresUtc;
var properties = model.Properties;
properties.IssuedUtc = _renewIssuedUtc;
properties.ExpiresUtc = _renewExpiresUtc;
if (Options.SessionStore != null && _sessionKey != null)
{
@ -250,7 +252,8 @@ namespace Microsoft.Owin.Security.Cookies
string cookieValue = Options.TicketDataFormat.Protect(model);
if (model.Properties.IsPersistent)
// Check the non-SessionStore properties
if (properties.IsPersistent)
{
cookieOptions.Expires = _renewExpiresUtc.UtcDateTime;
}

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
@ -74,6 +75,14 @@ namespace Microsoft.Owin.Security.Tests
return Task.FromResult<object>(null);
}
private Task SignInAsAlicePersistent(IOwinContext context)
{
context.Authentication.SignIn(
new AuthenticationProperties() { IsPersistent = true },
new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")));
return Task.FromResult<object>(null);
}
[Fact]
public async Task SignInCausesDefaultCookieToBeCreated()
{
@ -300,27 +309,171 @@ namespace Microsoft.Owin.Security.Tests
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
transaction1.SetCookie.ShouldNotBe(null);
transaction1.SetCookie.ShouldNotContain("Expires");
Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction2.SetCookie.ShouldBe(null);
FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction3.SetCookie.ShouldBe(null);
FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
// transaction4 should arrive with a new SetCookie value
Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction4.SetCookie.ShouldNotBe(null);
transaction4.SetCookie.ShouldNotContain("Expires");
FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction5 = await SendAsync(server, "http://example.com/me/Cookies", transaction4.CookieNameValue);
transaction5.SetCookie.ShouldBe(null);
FindClaimValue(transaction5, ClaimTypes.Name).ShouldBe("Alice");
}
[Fact]
public async Task PersistentCookieIsRenewedWithSlidingExpiration()
{
var clock = new TestClock();
TestServer server = CreateServer(new CookieAuthenticationOptions
{
SystemClock = clock,
ExpireTimeSpan = TimeSpan.FromMinutes(10),
SlidingExpiration = true,
}, SignInAsAlicePersistent);
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
transaction1.SetCookie.ShouldNotBe(null);
transaction1.SetCookie.ShouldContain("Expires");
Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction2.SetCookie.ShouldBe(null);
FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction3.SetCookie.ShouldBe(null);
FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
// transaction4 should arrive with a new SetCookie value
Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction4.SetCookie.ShouldNotBe(null);
transaction4.SetCookie.ShouldContain("Expires");
FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction5 = await SendAsync(server, "http://example.com/me/Cookies", transaction4.CookieNameValue);
transaction5.SetCookie.ShouldBe(null);
FindClaimValue(transaction5, ClaimTypes.Name).ShouldBe("Alice");
}
[Fact]
public async Task SessionStoreCookieIsRenewedWithSlidingExpiration()
{
var clock = new TestClock();
TestServer server = CreateServer(new CookieAuthenticationOptions
{
SystemClock = clock,
ExpireTimeSpan = TimeSpan.FromMinutes(10),
SlidingExpiration = true,
SessionStore = new TestSessionStore()
}, SignInAsAlice);
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
transaction1.SetCookie.ShouldNotBe(null);
transaction1.SetCookie.ShouldNotContain("Expires");
Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction2.SetCookie.ShouldBe(null);
FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction3.SetCookie.ShouldBe(null);
FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
// transaction4 should arrive with a new SetCookie value
Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction4.SetCookie.ShouldNotBe(null);
transaction4.SetCookie.ShouldNotContain("Expires");
FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction5 = await SendAsync(server, "http://example.com/me/Cookies", transaction4.CookieNameValue);
transaction5.SetCookie.ShouldBe(null);
FindClaimValue(transaction5, ClaimTypes.Name).ShouldBe("Alice");
}
[Fact]
public async Task PersistentSessionStoreCookieIsRenewedWithSlidingExpiration()
{
var clock = new TestClock();
TestServer server = CreateServer(new CookieAuthenticationOptions
{
SystemClock = clock,
ExpireTimeSpan = TimeSpan.FromMinutes(10),
SlidingExpiration = true,
SessionStore = new TestSessionStore()
}, SignInAsAlicePersistent);
Transaction transaction1 = await SendAsync(server, "http://example.com/testpath");
transaction1.SetCookie.ShouldNotBe(null);
transaction1.SetCookie.ShouldContain("Expires");
Transaction transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction2.SetCookie.ShouldBe(null);
FindClaimValue(transaction2, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction3.SetCookie.ShouldBe(null);
FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
// transaction4 should arrive with a new SetCookie value
Transaction transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
transaction4.SetCookie.ShouldNotBe(null);
transaction4.SetCookie.ShouldContain("Expires");
FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe("Alice");
clock.Add(TimeSpan.FromMinutes(4));
Transaction transaction5 = await SendAsync(server, "http://example.com/me/Cookies", transaction4.CookieNameValue);
transaction5.SetCookie.ShouldBe(null);
FindClaimValue(transaction5, ClaimTypes.Name).ShouldBe("Alice");
}
@ -476,5 +629,39 @@ namespace Microsoft.Owin.Security.Tests
public string ResponseText { get; set; }
public XElement ResponseElement { get; set; }
}
private class TestSessionStore : IAuthenticationSessionStore
{
IDictionary<string, AuthenticationTicket> _store = new Dictionary<string, AuthenticationTicket>(StringComparer.Ordinal);
public Task RemoveAsync(string key)
{
_store.Remove(key);
return Task.FromResult(0);
}
public Task RenewAsync(string key, AuthenticationTicket ticket)
{
_store[key] = ticket;
return Task.FromResult(0);
}
public Task<AuthenticationTicket> RetrieveAsync(string key)
{
AuthenticationTicket ticket;
if (_store.TryGetValue(key, out ticket))
{
return Task.FromResult(ticket);
}
return Task.FromResult<AuthenticationTicket>(null);
}
public Task<string> StoreAsync(AuthenticationTicket ticket)
{
var key = Guid.NewGuid().ToString();
_store[key] = ticket;
return Task.FromResult(key);
}
}
}
}