Add functional tests
+ cleanup Fixes https://github.com/aspnet/Identity/issues/395 Fixes https://github.com/aspnet/Identity/issues/231
This commit is contained in:
parent
99f5a9cfed
commit
2246a41978
|
|
@ -23,6 +23,11 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
return services.Configure<IdentityOptions>(config);
|
||||
}
|
||||
|
||||
public static IServiceCollection ConfigureIdentityApplicationCookie(this IServiceCollection services, Action<CookieAuthenticationOptions> configureOptions)
|
||||
{
|
||||
return services.Configure<CookieAuthenticationOptions>(configureOptions, IdentityOptions.ApplicationCookieAuthenticationScheme);
|
||||
}
|
||||
|
||||
public static IdentityBuilder AddIdentity(this IServiceCollection services)
|
||||
{
|
||||
return services.AddIdentity<IdentityUser, IdentityRole>(configureOptions: null);
|
||||
|
|
@ -72,7 +77,7 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
});
|
||||
|
||||
// Configure all of the cookie middlewares
|
||||
services.Configure<CookieAuthenticationOptions>(options =>
|
||||
services.ConfigureIdentityApplicationCookie(options =>
|
||||
{
|
||||
options.AuthenticationScheme = IdentityOptions.ApplicationCookieAuthenticationScheme;
|
||||
options.LoginPath = new PathString("/Account/Login");
|
||||
|
|
@ -80,7 +85,7 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
{
|
||||
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
|
||||
};
|
||||
}, IdentityOptions.ApplicationCookieAuthenticationScheme);
|
||||
});
|
||||
services.Configure<CookieAuthenticationOptions>(options =>
|
||||
{
|
||||
options.AuthenticationScheme = IdentityOptions.ExternalCookieAuthenticationScheme;
|
||||
|
|
|
|||
|
|
@ -18,14 +18,13 @@ namespace System.Security.Principal
|
|||
/// <param name="principal">The <see cref="IPrincipal"/> instance this method extends.</param>
|
||||
/// <returns>The Name claim value, or null if the claim is not present.</returns>
|
||||
/// <remarks>The name claim is identified by <see cref="ClaimsIdentity.DefaultNameClaimType"/>.</remarks>
|
||||
public static string GetUserName(this IPrincipal principal)
|
||||
public static string GetUserName(this ClaimsPrincipal principal)
|
||||
{
|
||||
if (principal == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(principal));
|
||||
}
|
||||
var cp = principal as ClaimsPrincipal;
|
||||
return cp != null ? cp.FindFirstValue(ClaimsIdentity.DefaultNameClaimType) : null;
|
||||
return principal.FindFirstValue(ClaimsIdentity.DefaultNameClaimType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -34,14 +33,13 @@ namespace System.Security.Principal
|
|||
/// <param name="principal">The <see cref="IPrincipal"/> instance this method extends.</param>
|
||||
/// <returns>The User ID claim value, or null if the claim is not present.</returns>
|
||||
/// <remarks>The name claim is identified by <see cref="ClaimTypes.NameIdentifier"/>.</remarks>
|
||||
public static string GetUserId(this IPrincipal principal)
|
||||
public static string GetUserId(this ClaimsPrincipal principal)
|
||||
{
|
||||
if (principal == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(principal));
|
||||
}
|
||||
var ci = principal as ClaimsPrincipal;
|
||||
return ci != null ? ci.FindFirstValue(ClaimTypes.NameIdentifier) : null;
|
||||
return principal.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -49,15 +47,14 @@ namespace System.Security.Principal
|
|||
/// </summary>
|
||||
/// <param name="principal">The <see cref="IPrincipal"/> instance this method extends.</param>
|
||||
/// <returns>True if the user is logged in with identity.</returns>
|
||||
public static bool IsSignedIn(this IPrincipal principal)
|
||||
public static bool IsSignedIn(this ClaimsPrincipal principal)
|
||||
{
|
||||
if (principal == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(principal));
|
||||
}
|
||||
var p = principal as ClaimsPrincipal;
|
||||
return p?.Identities != null &&
|
||||
p.Identities.Any(i => i.AuthenticationType == IdentityOptions.ApplicationCookieAuthenticationType);
|
||||
return principal.Identities != null &&
|
||||
principal.Identities.Any(i => i.AuthenticationType == IdentityOptions.ApplicationCookieAuthenticationType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,130 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30408.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.net45", "..\src\Microsoft.AspNet.Identity\Microsoft.AspNet.Identity.net45.csproj", "{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{31019886-9CDA-4072-B3D9-E513122CECD0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Entity.net45", "..\src\Microsoft.AspNet.Identity.Entity\Microsoft.AspNet.Identity.Entity.net45.csproj", "{B00CB809-C040-42A4-8AB2-4CFB924DD038}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.InMemory.net45", "..\src\Microsoft.AspNet.Identity.InMemory\Microsoft.AspNet.Identity.InMemory.net45.csproj", "{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Security.net45", "..\src\Microsoft.AspNet.Identity.Security\Microsoft.AspNet.Identity.Security.net45.csproj", "{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{394C0E59-7E24-453E-993C-7B914C62110A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Test.net45", "..\test\Microsoft.AspNet.Identity.Test\Microsoft.AspNet.Identity.Test.net45.csproj", "{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Security.Test.net45", "..\test\Microsoft.AspNet.Identity.Security.Test\Microsoft.AspNet.Identity.Security.Test.net45.csproj", "{13883A27-8710-421A-86CE-298E34CE82DD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.InMemory.Test.net45", "..\test\Microsoft.AspNet.Identity.InMemory.Test\Microsoft.AspNet.Identity.InMemory.Test.net45.csproj", "{47F00656-3F63-45CD-BBE5-1505CE7938D3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Entity.Test.net45", "..\test\Microsoft.AspNet.Identity.Entity.Test\Microsoft.AspNet.Identity.Entity.Test.net45.csproj", "{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{91C0C8AC-F889-4EB9-B4C7-1EB951FC428A} = {31019886-9CDA-4072-B3D9-E513122CECD0}
|
||||
{B00CB809-C040-42A4-8AB2-4CFB924DD038} = {31019886-9CDA-4072-B3D9-E513122CECD0}
|
||||
{13A0C423-FD34-41B7-AB46-2BB16CF5DC1F} = {31019886-9CDA-4072-B3D9-E513122CECD0}
|
||||
{ADE2B479-1D29-4D63-9B8B-D5E05943C4A8} = {31019886-9CDA-4072-B3D9-E513122CECD0}
|
||||
{CD364B81-5435-4EF7-ADE7-B6E02E0B4486} = {394C0E59-7E24-453E-993C-7B914C62110A}
|
||||
{13883A27-8710-421A-86CE-298E34CE82DD} = {394C0E59-7E24-453E-993C-7B914C62110A}
|
||||
{47F00656-3F63-45CD-BBE5-1505CE7938D3} = {394C0E59-7E24-453E-993C-7B914C62110A}
|
||||
{9CDAEF16-DD10-4307-9186-EC70BF8A5AD8} = {394C0E59-7E24-453E-993C-7B914C62110A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.AspNet.Authentication.Cookies;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.InMemory
|
||||
{
|
||||
public class FunctionalTest
|
||||
{
|
||||
const string TestPassword = "1qaz!QAZ";
|
||||
|
||||
[Fact]
|
||||
public async Task CanCreateMeLoginAndCookieStopsWorkingAfterExpiration()
|
||||
{
|
||||
var clock = new TestClock();
|
||||
TestServer server = CreateServer(appCookieOptions =>
|
||||
{
|
||||
appCookieOptions.SystemClock = clock;
|
||||
appCookieOptions.ExpireTimeSpan = TimeSpan.FromMinutes(10);
|
||||
appCookieOptions.SlidingExpiration = false;
|
||||
});
|
||||
|
||||
Transaction transaction1 = await SendAsync(server, "http://example.com/createMe");
|
||||
transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
Assert.Null(transaction1.SetCookie);
|
||||
|
||||
Transaction transaction2 = await SendAsync(server, "http://example.com/pwdLogin/false");
|
||||
transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
Assert.NotNull(transaction2.SetCookie);
|
||||
transaction2.SetCookie.ShouldNotContain("; expires=");
|
||||
|
||||
Transaction transaction3 = await SendAsync(server, "http://example.com/me", transaction2.CookieNameValue);
|
||||
FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("hao");
|
||||
Assert.Null(transaction3.SetCookie);
|
||||
|
||||
clock.Add(TimeSpan.FromMinutes(7));
|
||||
|
||||
Transaction transaction4 = await SendAsync(server, "http://example.com/me", transaction2.CookieNameValue);
|
||||
FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe("hao");
|
||||
Assert.Null(transaction4.SetCookie);
|
||||
|
||||
clock.Add(TimeSpan.FromMinutes(7));
|
||||
|
||||
Transaction transaction5 = await SendAsync(server, "http://example.com/me", transaction2.CookieNameValue);
|
||||
FindClaimValue(transaction5, ClaimTypes.Name).ShouldBe(null);
|
||||
Assert.Null(transaction5.SetCookie);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task CanCreateMeLoginAndSecurityStampExtendsExpiration(bool rememberMe)
|
||||
{
|
||||
var clock = new TestClock();
|
||||
TestServer server = CreateServer(appCookieOptions =>
|
||||
{
|
||||
appCookieOptions.SystemClock = clock;
|
||||
});
|
||||
|
||||
Transaction transaction1 = await SendAsync(server, "http://example.com/createMe");
|
||||
transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
Assert.Null(transaction1.SetCookie);
|
||||
|
||||
Transaction transaction2 = await SendAsync(server, "http://example.com/pwdLogin/" + rememberMe);
|
||||
transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
Assert.NotNull(transaction2.SetCookie);
|
||||
if (rememberMe)
|
||||
{
|
||||
transaction2.SetCookie.ShouldContain("; expires=");
|
||||
}
|
||||
else
|
||||
{
|
||||
transaction2.SetCookie.ShouldNotContain("; expires=");
|
||||
}
|
||||
|
||||
Transaction transaction3 = await SendAsync(server, "http://example.com/me", transaction2.CookieNameValue);
|
||||
FindClaimValue(transaction3, ClaimTypes.Name).ShouldBe("hao");
|
||||
Assert.Null(transaction3.SetCookie);
|
||||
|
||||
// Make sure we don't get a new cookie yet
|
||||
clock.Add(TimeSpan.FromMinutes(10));
|
||||
Transaction transaction4 = await SendAsync(server, "http://example.com/me", transaction2.CookieNameValue);
|
||||
FindClaimValue(transaction4, ClaimTypes.Name).ShouldBe("hao");
|
||||
Assert.Null(transaction4.SetCookie);
|
||||
|
||||
// Go past SecurityStampValidation interval and ensure we get a new cookie
|
||||
clock.Add(TimeSpan.FromMinutes(21));
|
||||
|
||||
Transaction transaction5 = await SendAsync(server, "http://example.com/me", transaction2.CookieNameValue);
|
||||
Assert.NotNull(transaction5.SetCookie);
|
||||
FindClaimValue(transaction5, ClaimTypes.Name).ShouldBe("hao");
|
||||
|
||||
// Make sure new cookie is valid
|
||||
Transaction transaction6 = await SendAsync(server, "http://example.com/me", transaction5.CookieNameValue);
|
||||
FindClaimValue(transaction6, ClaimTypes.Name).ShouldBe("hao");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TwoFactorRememberCookieVerification()
|
||||
{
|
||||
TestServer server = CreateServer(appCookieOptions => { });
|
||||
|
||||
Transaction transaction1 = await SendAsync(server, "http://example.com/createMe");
|
||||
transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
Assert.Null(transaction1.SetCookie);
|
||||
|
||||
Transaction transaction2 = await SendAsync(server, "http://example.com/twofactorRememeber");
|
||||
transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
||||
string setCookie = transaction2.SetCookie;
|
||||
setCookie.ShouldContain(IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme+"=");
|
||||
setCookie.ShouldContain("; expires=");
|
||||
|
||||
Transaction transaction3 = await SendAsync(server, "http://example.com/isTwoFactorRememebered", transaction2.CookieNameValue);
|
||||
transaction3.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
private static string FindClaimValue(Transaction transaction, string claimType)
|
||||
{
|
||||
XElement claim = transaction.ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType);
|
||||
if (claim == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return claim.Attribute("value").Value;
|
||||
}
|
||||
|
||||
private static async Task<XElement> GetAuthData(TestServer server, string url, string cookie)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
request.Headers.Add("Cookie", cookie);
|
||||
|
||||
HttpResponseMessage response2 = await server.CreateClient().SendAsync(request);
|
||||
string text = await response2.Content.ReadAsStringAsync();
|
||||
XElement me = XElement.Parse(text);
|
||||
return me;
|
||||
}
|
||||
|
||||
private static TestServer CreateServer(Action<CookieAuthenticationOptions> configureAppCookie, Func<HttpContext, Task> testpath = null, Uri baseAddress = null)
|
||||
{
|
||||
var server = TestServer.Create(app =>
|
||||
{
|
||||
app.UseServices(services =>
|
||||
{
|
||||
services.AddIdentity<InMemoryUser, IdentityRole>();
|
||||
services.AddSingleton<IUserStore<InMemoryUser>, InMemoryUserStore<InMemoryUser>>();
|
||||
services.AddSingleton<IRoleStore<IdentityRole>, InMemoryRoleStore<IdentityRole>>();
|
||||
services.ConfigureIdentityApplicationCookie(configureAppCookie);
|
||||
});
|
||||
app.UseIdentity();
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
var req = context.Request;
|
||||
var res = context.Response;
|
||||
var userManager = context.RequestServices.GetRequiredService<UserManager<InMemoryUser>>();
|
||||
var signInManager = context.RequestServices.GetRequiredService<SignInManager<InMemoryUser>>();
|
||||
PathString remainder;
|
||||
if (req.Path == new PathString("/normal"))
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
}
|
||||
else if (req.Path == new PathString("/createMe"))
|
||||
{
|
||||
var result = await userManager.CreateAsync(new InMemoryUser("hao"), TestPassword);
|
||||
res.StatusCode = result.Succeeded ? 200 : 500;
|
||||
}
|
||||
else if (req.Path == new PathString("/protected"))
|
||||
{
|
||||
res.StatusCode = 401;
|
||||
}
|
||||
else if (req.Path.StartsWithSegments(new PathString("/pwdLogin"), out remainder))
|
||||
{
|
||||
var isPersistent = bool.Parse(remainder.Value.Substring(1));
|
||||
var result = await signInManager.PasswordSignInAsync("hao", TestPassword, isPersistent, false);
|
||||
res.StatusCode = result.Succeeded ? 200 : 500;
|
||||
}
|
||||
else if (req.Path == new PathString("/twofactorRememeber"))
|
||||
{
|
||||
var user = await userManager.FindByNameAsync("hao");
|
||||
await signInManager.RememberTwoFactorClientAsync(user);
|
||||
res.StatusCode = 200;
|
||||
}
|
||||
else if (req.Path == new PathString("/isTwoFactorRememebered"))
|
||||
{
|
||||
var user = await userManager.FindByNameAsync("hao");
|
||||
var result = await signInManager.IsTwoFactorClientRememberedAsync(user);
|
||||
res.StatusCode = result ? 200 : 500;
|
||||
}
|
||||
else if (req.Path == new PathString("/twofactorSignIn"))
|
||||
{
|
||||
}
|
||||
else if (req.Path == new PathString("/me"))
|
||||
{
|
||||
Describe(res, new AuthenticationResult(context.User, new AuthenticationProperties(), new AuthenticationDescription()));
|
||||
}
|
||||
else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder))
|
||||
{
|
||||
var result = await context.AuthenticateAsync(remainder.Value.Substring(1));
|
||||
Describe(res, result);
|
||||
}
|
||||
else if (req.Path == new PathString("/testpath") && testpath != null)
|
||||
{
|
||||
await testpath(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
await next();
|
||||
}
|
||||
});
|
||||
});
|
||||
server.BaseAddress = baseAddress;
|
||||
return server;
|
||||
}
|
||||
|
||||
private static void Describe(HttpResponse res, AuthenticationResult result)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
var xml = new XElement("xml");
|
||||
if (result != null && result.Principal != null)
|
||||
{
|
||||
xml.Add(result.Principal.Claims.Select(claim => new XElement("claim", new XAttribute("type", claim.Type), new XAttribute("value", claim.Value))));
|
||||
}
|
||||
if (result != null && result.Properties != null)
|
||||
{
|
||||
xml.Add(result.Properties.Dictionary.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value))));
|
||||
}
|
||||
using (var memory = new MemoryStream())
|
||||
{
|
||||
using (var writer = new XmlTextWriter(memory, Encoding.UTF8))
|
||||
{
|
||||
xml.WriteTo(writer);
|
||||
}
|
||||
res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<Transaction> SendAsync(TestServer server, string uri, string cookieHeader = null, bool ajaxRequest = false)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, uri);
|
||||
if (!string.IsNullOrEmpty(cookieHeader))
|
||||
{
|
||||
request.Headers.Add("Cookie", cookieHeader);
|
||||
}
|
||||
if (ajaxRequest)
|
||||
{
|
||||
request.Headers.Add("X-Requested-With", "XMLHttpRequest");
|
||||
}
|
||||
var transaction = new Transaction
|
||||
{
|
||||
Request = request,
|
||||
Response = await server.CreateClient().SendAsync(request),
|
||||
};
|
||||
if (transaction.Response.Headers.Contains("Set-Cookie"))
|
||||
{
|
||||
transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").SingleOrDefault();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(transaction.SetCookie))
|
||||
{
|
||||
transaction.CookieNameValue = transaction.SetCookie.Split(new[] { ';' }, 2).First();
|
||||
}
|
||||
transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync();
|
||||
|
||||
if (transaction.Response.Content != null &&
|
||||
transaction.Response.Content.Headers.ContentType != null &&
|
||||
transaction.Response.Content.Headers.ContentType.MediaType == "text/xml")
|
||||
{
|
||||
transaction.ResponseElement = XElement.Parse(transaction.ResponseText);
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
private class Transaction
|
||||
{
|
||||
public HttpRequestMessage Request { get; set; }
|
||||
public HttpResponseMessage Response { get; set; }
|
||||
|
||||
public string SetCookie { get; set; }
|
||||
public string CookieNameValue { get; set; }
|
||||
|
||||
public string ResponseText { get; set; }
|
||||
public XElement ResponseElement { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.InMemory
|
||||
{
|
||||
public class TestClock : ISystemClock
|
||||
{
|
||||
public TestClock()
|
||||
{
|
||||
UtcNow = new DateTimeOffset(2013, 6, 11, 12, 34, 56, 789, TimeSpan.Zero);
|
||||
}
|
||||
|
||||
public DateTimeOffset UtcNow { get; set; }
|
||||
|
||||
public void Add(TimeSpan timeSpan)
|
||||
{
|
||||
UtcNow = UtcNow + timeSpan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,24 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Authentication" : "1.0.0-*",
|
||||
"Microsoft.AspNet.Authentication.Cookies" : "1.0.0-*",
|
||||
"Microsoft.AspNet.Hosting": "1.0.0-*",
|
||||
"Microsoft.AspNet.Http" : "1.0.0-*",
|
||||
"Microsoft.AspNet.Identity" : "3.0.0-*",
|
||||
"Microsoft.AspNet.RequestContainer" : "1.0.0-*",
|
||||
"Microsoft.AspNet.Authentication" : "1.0.0-*",
|
||||
"Microsoft.AspNet.Authentication.Cookies" : "1.0.0-*",
|
||||
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
||||
"Microsoft.AspNet.Testing" : "1.0.0-*",
|
||||
"Microsoft.Framework.ConfigurationModel": "1.0.0-*",
|
||||
"Microsoft.Framework.DependencyInjection" : "1.0.0-*",
|
||||
"Microsoft.Framework.OptionsModel" : "1.0.0-*",
|
||||
"Moq": "4.2.1312.1622",
|
||||
"xunit.runner.kre": "1.0.0-*"
|
||||
},
|
||||
"code": "**\\*.cs;..\\Shared\\*.cs",
|
||||
"frameworks": {
|
||||
"dnx451": {
|
||||
"dependencies": {
|
||||
"Moq" : "4.2.1312.1622"
|
||||
"Shouldly": "1.1.1.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Microsoft.AspNet.Identity.Test
|
||||
{
|
||||
internal interface IHttpContextAccessor<T>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -15,21 +15,12 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
[Fact]
|
||||
public void IdentityNullCheckTest()
|
||||
{
|
||||
IPrincipal p = null;
|
||||
Assert.Throws<ArgumentNullException>("principal", () => p.GetUserId());
|
||||
Assert.Throws<ArgumentNullException>("principal", () => p.GetUserName());
|
||||
ClaimsPrincipal cp = null;
|
||||
Assert.Throws<ArgumentNullException>("principal", () => cp.GetUserId());
|
||||
Assert.Throws<ArgumentNullException>("principal", () => cp.GetUserName());
|
||||
Assert.Throws<ArgumentNullException>("principal", () => cp.FindFirstValue(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IdentityNullIfNotClaimsIdentityTest()
|
||||
{
|
||||
IPrincipal identity = new TestPrincipal();
|
||||
Assert.Null(identity.GetUserId());
|
||||
Assert.Null(identity.GetUserName());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UserNameAndIdTest()
|
||||
{
|
||||
|
|
@ -82,39 +73,5 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
},
|
||||
ExternalAuthenticationScheme));
|
||||
}
|
||||
|
||||
private class TestPrincipal : IPrincipal
|
||||
{
|
||||
public IIdentity Identity
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInRole(string role)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private class TestIdentity : IIdentity
|
||||
{
|
||||
public string AuthenticationType
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public bool IsAuthenticated
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue