diff --git a/.gitignore b/.gitignore
index 4266ce8..ad72bc4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
[Oo]bj/
[Bb]in/
-packages/
\ No newline at end of file
+packages/
+.vs
diff --git a/Microsoft.AspNet.Identity.sln b/Microsoft.AspNet.Identity.sln
index b869386..5a2df97 100644
--- a/Microsoft.AspNet.Identity.sln
+++ b/Microsoft.AspNet.Identity.sln
@@ -1,57 +1,27 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.30408.0
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34616.47
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Core", "src\Microsoft.AspNet.Identity.Core\Microsoft.AspNet.Identity.Core.csproj", "{D2F24972-0F56-4C18-BD65-C26A320A0C68}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.Core", "src\Microsoft.AspNet.Identity.Core\Microsoft.AspNet.Identity.Core.csproj", "{D2F24972-0F56-4C18-BD65-C26A320A0C68}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0C1D4BD7-0771-4899-AF55-43D8791660A0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.EntityFramework", "src\Microsoft.AspNet.Identity.EntityFramework\Microsoft.AspNet.Identity.EntityFramework.csproj", "{D7298DAD-AB04-4502-9567-0461D0AD059E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.EntityFramework", "src\Microsoft.AspNet.Identity.EntityFramework\Microsoft.AspNet.Identity.EntityFramework.csproj", "{D7298DAD-AB04-4502-9567-0461D0AD059E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FD5D1AFD-204F-4504-B8F3-74C2E1EEC848}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8883A4C2-A8DF-4F24-ADF7-DAEBFBEFD21B}"
ProjectSection(SolutionItems) = preProject
License.txt = License.txt
- unittest.testsettings = unittest.testsettings
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Owin", "src\Microsoft.AspNet.Identity.Owin\Microsoft.AspNet.Identity.Owin.csproj", "{943170EB-F4E7-4A6D-989E-2CF6C681DD89}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{A7082BDD-985B-47B9-915B-7FA4CF541B5E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{A7082BDD-985B-47B9-915B-7FA4CF541B5E}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Owin", "src\Microsoft.AspNet.Identity.Owin\Microsoft.AspNet.Identity.Owin.csproj", "{943170EB-F4E7-4A6D-989E-2CF6C681DD89}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{99DB175F-B1B4-4C9B-9D4A-C21F1ED2FB86}"
- ProjectSection(SolutionItems) = preProject
- .nuget\NuGet.Config = .nuget\NuGet.Config
- .nuget\NuGet.exe = .nuget\NuGet.exe
- .nuget\NuGet.targets = .nuget\NuGet.targets
- .nuget\packages.config = .nuget\packages.config
- EndProjectSection
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.AspNetCore", "src\Microsoft.AspNet.Identity.AspNetCore\Microsoft.AspNet.Identity.AspNetCore.csproj", "{5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}"
EndProject
Global
- GlobalSection(TeamFoundationVersionControl) = preSolution
- SccNumberOfProjects = 5
- SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs18
- SccLocalPath0 = .
- SccProjectUniqueName1 = src\\Microsoft.AspNet.Identity.Core\\Microsoft.AspNet.Identity.Core.csproj
- SccProjectTopLevelParentUniqueName1 = Microsoft.AspNet.Identity.sln
- SccProjectName1 = src/Microsoft.AspNet.Identity.Core
- SccLocalPath1 = src\\Microsoft.AspNet.Identity.Core
- SccProjectUniqueName2 = src\\Microsoft.AspNet.Identity.EntityFramework\\Microsoft.AspNet.Identity.EntityFramework.csproj
- SccProjectTopLevelParentUniqueName2 = Microsoft.AspNet.Identity.sln
- SccProjectName2 = src/Microsoft.AspNet.Identity.EntityFramework
- SccLocalPath2 = src\\Microsoft.AspNet.Identity.EntityFramework
- SccProjectUniqueName3 = src\\Microsoft.AspNet.Identity.Owin\\Microsoft.AspNet.Identity.Owin.csproj
- SccProjectTopLevelParentUniqueName3 = Microsoft.AspNet.Identity.sln
- SccProjectName3 = src/Microsoft.AspNet.Identity.Owin
- SccLocalPath3 = src\\Microsoft.AspNet.Identity.Owin
- SccProjectUniqueName4 = test\\Identity.Test\\Identity.Test.csproj
- SccProjectTopLevelParentUniqueName4 = Microsoft.AspNet.Identity.sln
- SccProjectName4 = test/Identity.Test
- SccLocalPath4 = test\\Identity.Test
- EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
@@ -65,14 +35,18 @@ Global
{D7298DAD-AB04-4502-9567-0461D0AD059E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7298DAD-AB04-4502-9567-0461D0AD059E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7298DAD-AB04-4502-9567-0461D0AD059E}.Release|Any CPU.Build.0 = Release|Any CPU
- {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.Build.0 = Release|Any CPU
{A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -80,8 +54,12 @@ Global
GlobalSection(NestedProjects) = preSolution
{D2F24972-0F56-4C18-BD65-C26A320A0C68} = {0C1D4BD7-0771-4899-AF55-43D8791660A0}
{D7298DAD-AB04-4502-9567-0461D0AD059E} = {0C1D4BD7-0771-4899-AF55-43D8791660A0}
- {943170EB-F4E7-4A6D-989E-2CF6C681DD89} = {0C1D4BD7-0771-4899-AF55-43D8791660A0}
{A7082BDD-985B-47B9-915B-7FA4CF541B5E} = {FD5D1AFD-204F-4504-B8F3-74C2E1EEC848}
+ {943170EB-F4E7-4A6D-989E-2CF6C681DD89} = {0C1D4BD7-0771-4899-AF55-43D8791660A0}
+ {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F} = {0C1D4BD7-0771-4899-AF55-43D8791660A0}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {18A616DC-B136-4FD9-B3BC-DCE7D07D0693}
EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Microsoft.AspNet.Identity.vsmdi
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/35MSSharedLib1024.snk b/src/Microsoft.AspNet.Identity.AspNetCore/35MSSharedLib1024.snk
new file mode 100644
index 0000000..695f1b3
Binary files /dev/null and b/src/Microsoft.AspNet.Identity.AspNetCore/35MSSharedLib1024.snk differ
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/DataProtectorTokenProvider.cs b/src/Microsoft.AspNet.Identity.AspNetCore/DataProtectorTokenProvider.cs
new file mode 100644
index 0000000..d80fc7c
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/DataProtectorTokenProvider.cs
@@ -0,0 +1,192 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.DataProtection;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Token provider that uses an IDataProtector to generate encrypted tokens based off of the security stamp
+ ///
+ public class DataProtectorTokenProvider : DataProtectorTokenProvider
+ where TUser : class, IUser
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ public DataProtectorTokenProvider(IDataProtector protector) : base(protector)
+ {
+ }
+ }
+
+ ///
+ /// Token provider that uses an IDataProtector to generate encrypted tokens based off of the security stamp
+ ///
+ public class DataProtectorTokenProvider : IUserTokenProvider
+ where TUser : class, IUser where TKey : IEquatable
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ public DataProtectorTokenProvider(IDataProtector protector)
+ {
+ if (protector == null)
+ {
+ throw new ArgumentNullException("protector");
+ }
+ Protector = protector;
+ TokenLifespan = TimeSpan.FromDays(1);
+ }
+
+ ///
+ /// IDataProtector for the token
+ ///
+ public IDataProtector Protector { get; private set; }
+
+ ///
+ /// Lifespan after which the token is considered expired
+ ///
+ public TimeSpan TokenLifespan { get; set; }
+
+ ///
+ /// Generate a protected string for a user
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task GenerateAsync(string purpose, UserManager manager, TUser user)
+ {
+ if (user == null)
+ {
+ throw new ArgumentNullException("user");
+ }
+ var ms = new MemoryStream();
+ using (var writer = ms.CreateWriter())
+ {
+ writer.Write(DateTimeOffset.UtcNow);
+ writer.Write(Convert.ToString(user.Id, CultureInfo.InvariantCulture));
+ writer.Write(purpose ?? "");
+ string stamp = null;
+ if (manager.SupportsUserSecurityStamp)
+ {
+ stamp = await manager.GetSecurityStampAsync(user.Id).WithCurrentCulture();
+ }
+ writer.Write(stamp ?? "");
+ }
+ var protectedBytes = Protector.Protect(ms.ToArray());
+ return Convert.ToBase64String(protectedBytes);
+ }
+
+ ///
+ /// Return false if the token is not valid
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user)
+ {
+ try
+ {
+ var unprotectedData = Protector.Unprotect(Convert.FromBase64String(token));
+ var ms = new MemoryStream(unprotectedData);
+ using (var reader = ms.CreateReader())
+ {
+ var creationTime = reader.ReadDateTimeOffset();
+ var expirationTime = creationTime + TokenLifespan;
+ if (expirationTime < DateTimeOffset.UtcNow)
+ {
+ return false;
+ }
+
+ var userId = reader.ReadString();
+ if (!String.Equals(userId, Convert.ToString(user.Id, CultureInfo.InvariantCulture)))
+ {
+ return false;
+ }
+ var purp = reader.ReadString();
+ if (!String.Equals(purp, purpose))
+ {
+ return false;
+ }
+ var stamp = reader.ReadString();
+ if (reader.PeekChar() != -1)
+ {
+ return false;
+ }
+
+ if (manager.SupportsUserSecurityStamp)
+ {
+ var expectedStamp = await manager.GetSecurityStampAsync(user.Id).WithCurrentCulture();
+ return stamp == expectedStamp;
+ }
+ return stamp == "";
+ }
+ }
+ // ReSharper disable once EmptyGeneralCatchClause
+ catch
+ {
+ // Do not leak exception
+ }
+ return false;
+ }
+
+ ///
+ /// Returns true if the provider can be used to generate tokens for this user
+ ///
+ ///
+ ///
+ ///
+ public Task IsValidProviderForUserAsync(UserManager manager, TUser user)
+ {
+ return Task.FromResult(true);
+ }
+
+ ///
+ /// This provider no-ops by default when asked to notify a user
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Task NotifyAsync(string token, UserManager manager, TUser user)
+ {
+ return Task.FromResult(0);
+ }
+ }
+
+ // Based on Levi's authentication sample
+ internal static class StreamExtensions
+ {
+ internal static readonly Encoding DefaultEncoding = new UTF8Encoding(false, true);
+
+ public static BinaryReader CreateReader(this Stream stream)
+ {
+ return new BinaryReader(stream, DefaultEncoding, true);
+ }
+
+ public static BinaryWriter CreateWriter(this Stream stream)
+ {
+ return new BinaryWriter(stream, DefaultEncoding, true);
+ }
+
+ public static DateTimeOffset ReadDateTimeOffset(this BinaryReader reader)
+ {
+ return new DateTimeOffset(reader.ReadInt64(), TimeSpan.Zero);
+ }
+
+ public static void Write(this BinaryWriter writer, DateTimeOffset value)
+ {
+ writer.Write(value.UtcTicks);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/AuthenticationManagerExtensions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/AuthenticationManagerExtensions.cs
new file mode 100644
index 0000000..c2ea1f3
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/AuthenticationManagerExtensions.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Identity;
+using Microsoft.AspNet.Identity.AspNetCore;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNetCore
+{
+ ///
+ /// Extensions methods on IAuthenticationManager that add methods for using the default Application and External
+ /// authentication type constants
+ ///
+ internal static class AuthenticationManagerExtensions
+ {
+ ///
+ /// Returns true if there is a TwoFactorRememberBrowser cookie for a user
+ ///
+ ///
+ ///
+ ///
+ internal static async Task TwoFactorBrowserRememberedAsync(this HttpContext manager,
+ string userId)
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ var result =
+ await manager.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie).WithCurrentCulture();
+ return (result?.Principal?.Identity is ClaimsIdentity claimsIdentity && claimsIdentity.GetUserId() == userId);
+ }
+
+ ///
+ /// Creates a TwoFactorRememberBrowser cookie for a user
+ ///
+ ///
+ ///
+ ///
+ internal static ClaimsIdentity CreateTwoFactorRememberBrowserIdentity(this HttpContext manager,
+ string userId)
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ var rememberBrowserIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
+ rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId));
+ return rememberBrowserIdentity;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/OwinContextExtensions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/OwinContextExtensions.cs
new file mode 100644
index 0000000..af58e3f
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/OwinContextExtensions.cs
@@ -0,0 +1,62 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Extension methods for OwinContext/>
+ ///
+ internal static class HttpContextExtensions
+ {
+ ///
+ /// Stores an object in the OwinContext using a key based on the AssemblyQualified type name
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static HttpContext Set(this HttpContext context, T value)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException("context");
+ }
+
+ context.Items[typeof(T)] = value;
+ return context;
+ }
+
+ ///
+ /// Retrieves an object from the OwinContext using a key based on the AssemblyQualified type name
+ ///
+ ///
+ ///
+ ///
+ internal static T Get(this HttpContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException("context");
+ }
+ return (T)context.Items[typeof(T)];
+ }
+
+ ///
+ /// Get the user manager from the context
+ ///
+ ///
+ ///
+ ///
+ internal static TManager GetUserManager(this HttpContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException("context");
+ }
+ return context.Get();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/SignInManagerExtensions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/SignInManagerExtensions.cs
new file mode 100644
index 0000000..8024afa
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/SignInManagerExtensions.cs
@@ -0,0 +1,158 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Security.Claims;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Extension methods for SignInManager/>
+ ///
+ public static class SignInManagerExtensions
+ {
+ ///
+ /// Called to generate the ClaimsIdentity for the user, override to add additional claims before SignIn
+ ///
+ ///
+ ///
+ ///
+ public static ClaimsIdentity CreateUserIdentity(this SignInManager manager, TUser user)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ return AsyncHelper.RunSync(() => manager.CreateUserIdentityAsync(user));
+ }
+
+ ///
+ /// Creates a user identity and then signs the identity using the AuthenticationManager
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void SignIn(this SignInManager manager, TUser user, bool isPersistent, bool rememberBrowser)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ AsyncHelper.RunSync(() => manager.SignInAsync(user, isPersistent, rememberBrowser));
+ }
+
+ ///
+ /// Send a two factor code to a user
+ ///
+ ///
+ ///
+ ///
+ public static bool SendTwoFactorCode(this SignInManager manager, string provider)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ return AsyncHelper.RunSync(() => manager.SendTwoFactorCodeAsync(provider));
+ }
+
+ ///
+ /// Get the user id that has been verified already or null.
+ ///
+ ///
+ ///
+ public static TKey GetVerifiedUserId(this SignInManager manager)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ return AsyncHelper.RunSync(() => manager.GetVerifiedUserIdAsync());
+ }
+
+ ///
+ /// Has the user been verified (ie either via password or external login)
+ ///
+ ///
+ ///
+ public static bool HasBeenVerified(this SignInManager manager)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ return AsyncHelper.RunSync(() => manager.HasBeenVerifiedAsync());
+ }
+
+ ///
+ /// Two factor verification step
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static SignInStatus TwoFactorSignIn(this SignInManager manager, string provider, string code, bool isPersistent, bool rememberBrowser)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ return AsyncHelper.RunSync(() => manager.TwoFactorSignInAsync(provider, code, isPersistent, rememberBrowser));
+ }
+
+ ///
+ /// Sign the user in using an associated external login
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static SignInStatus ExternalSignIn(this SignInManager manager, ExternalLoginInfo loginInfo, bool isPersistent)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ return AsyncHelper.RunSync(() => manager.ExternalSignInAsync(loginInfo, isPersistent));
+ }
+
+
+ ///
+ /// Sign in the user in using the user name and password
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static SignInStatus PasswordSignIn(this SignInManager manager, string userName, string password, bool isPersistent, bool shouldLockout)
+ where TKey : IEquatable
+ where TUser : class, IUser
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException("manager");
+ }
+ return AsyncHelper.RunSync(() => manager.PasswordSignInAsync(userName, password, isPersistent, shouldLockout));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/ExternalLoginInfo.cs b/src/Microsoft.AspNet.Identity.AspNetCore/ExternalLoginInfo.cs
new file mode 100644
index 0000000..0a67358
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/ExternalLoginInfo.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Security.Claims;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Used to return information needed to associate an external login
+ ///
+ public class ExternalLoginInfo
+ {
+ ///
+ /// Associated login data
+ ///
+ public UserLoginInfo Login { get; set; }
+
+ ///
+ /// Suggested user name for a user
+ ///
+ public string DefaultUserName { get; set; }
+
+ ///
+ /// Email claim from the external identity
+ ///
+ public string Email { get; set; }
+
+ ///
+ /// The external identity
+ ///
+ public ClaimsIdentity ExternalIdentity { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IIdentityFactoryProvider.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IIdentityFactoryProvider.cs
new file mode 100644
index 0000000..87db6ec
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/IIdentityFactoryProvider.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Interface used to create objects per request
+ ///
+ ///
+ public interface IIdentityFactoryProvider where T : IDisposable
+ {
+ ///
+ /// Called once per request to create an object
+ ///
+ ///
+ ///
+ ///
+ T Create(IdentityFactoryOptions options, HttpContext context);
+
+ ///
+ /// Called at the end of the request to dispose the object created
+ ///
+ ///
+ ///
+ void Dispose(IdentityFactoryOptions options, T instance);
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryMiddleware.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryMiddleware.cs
new file mode 100644
index 0000000..af6ecea
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryMiddleware.cs
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// OwinMiddleware that initializes an object for use in the OwinContext via the Get/Set generic extensions method
+ ///
+ ///
+ ///
+ public class IdentityFactoryMiddleware : IMiddleware
+ where TResult : IDisposable
+ where TOptions : IdentityFactoryOptions
+ {
+ ///
+ /// Constructor
+ ///
+ /// Configuration options for the middleware
+ public IdentityFactoryMiddleware(TOptions options)
+ {
+ if (options == null)
+ {
+ throw new ArgumentNullException("options");
+ }
+ if (options.Provider == null)
+ {
+ throw new ArgumentNullException("options.Provider");
+ }
+ Options = options;
+ }
+
+ ///
+ /// Configuration options
+ ///
+ public TOptions Options { get; private set; }
+
+ ///
+ /// Create an object using the Options.Provider, storing it in the OwinContext and then disposes the object when finished
+ ///
+ ///
+ ///
+ public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ {
+ var instance = Options.Provider.Create(Options, context);
+ try
+ {
+ context.Set(instance);
+ if (next != null)
+ {
+ await next.Invoke(context);
+ }
+ }
+ finally
+ {
+ Options.Provider.Dispose(Options, instance);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryOptions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryOptions.cs
new file mode 100644
index 0000000..480d589
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryOptions.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.DataProtection;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Configuration options for a IdentityFactoryMiddleware
+ ///
+ ///
+ public class IdentityFactoryOptions where T : IDisposable
+ {
+ ///
+ /// Used to configure the data protection provider
+ ///
+ public IDataProtectionProvider DataProtectionProvider { get; set; }
+
+ ///
+ /// Provider used to Create and Dispose objects
+ ///
+ public IIdentityFactoryProvider Provider { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryProvider.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryProvider.cs
new file mode 100644
index 0000000..12fc5cc
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryProvider.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Used to configure how the IdentityFactoryMiddleware will create an instance of the specified type for each OwinContext
+ ///
+ ///
+ public class IdentityFactoryProvider : IIdentityFactoryProvider where T : class, IDisposable
+ {
+ ///
+ /// Constructor
+ ///
+ public IdentityFactoryProvider()
+ {
+ OnDispose = (options, instance) => { };
+ OnCreate = (options, context) => null;
+ }
+
+ ///
+ /// A delegate assigned to this property will be invoked when the related method is called
+ ///
+ public Func, HttpContext, T> OnCreate { get; set; }
+
+ ///
+ /// A delegate assigned to this property will be invoked when the related method is called
+ ///
+ public Action, T> OnDispose { get; set; }
+
+ ///
+ /// Calls the OnCreate Delegate
+ ///
+ ///
+ ///
+ ///
+ public virtual T Create(IdentityFactoryOptions options, HttpContext context)
+ {
+ return OnCreate(options, context);
+ }
+
+ ///
+ /// Calls the OnDispose delegate
+ ///
+ ///
+ ///
+ public virtual void Dispose(IdentityFactoryOptions options, T instance)
+ {
+ OnDispose(options, instance);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj b/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj
new file mode 100644
index 0000000..9f0b24a
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net6.0
+ enable
+ enable
+ 35MSSharedLib1024.snk
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ea6dae6
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+using System.Runtime.CompilerServices;
+
+[assembly:
+ InternalsVisibleTo(
+ "Identity.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9"
+ )]
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/SecurityStampValidator.cs b/src/Microsoft.AspNet.Identity.AspNetCore/SecurityStampValidator.cs
new file mode 100644
index 0000000..b3f01bb
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/SecurityStampValidator.cs
@@ -0,0 +1,121 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Static helper class used to configure a CookieAuthenticationProvider to validate a cookie against a user's security
+ /// stamp
+ ///
+ public static class SecurityStampValidator
+ {
+ ///
+ /// Can be used as the ValidateIdentity method for a CookieAuthenticationProvider which will check a user's security
+ /// stamp after validateInterval
+ /// Rejects the identity if the stamp changes, and otherwise will call regenerateIdentity to sign in a new
+ /// ClaimsIdentity
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Func OnValidateIdentity(
+ TimeSpan validateInterval, Func> regenerateIdentity)
+ where TManager : UserManager
+ where TUser : class, IUser
+ {
+ return OnValidateIdentity(validateInterval, regenerateIdentity, id => id.GetUserId());
+ }
+
+ ///
+ /// Can be used as the ValidateIdentity method for a CookieAuthenticationProvider which will check a user's security
+ /// stamp after validateInterval
+ /// Rejects the identity if the stamp changes, and otherwise will call regenerateIdentity to sign in a new
+ /// ClaimsIdentity
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Func OnValidateIdentity(
+ TimeSpan validateInterval, Func> regenerateIdentityCallback,
+ Func getUserIdCallback)
+ where TManager : UserManager
+ where TUser : class, IUser
+ where TKey : IEquatable
+ {
+ if (getUserIdCallback == null)
+ {
+ throw new ArgumentNullException("getUserIdCallback");
+ }
+ return async context =>
+ {
+ var currentUtc = DateTimeOffset.UtcNow;
+ //if (context.Options != null && context.Options.SystemClock != null)
+ //{
+ // currentUtc = context.Options.SystemClock.UtcNow;
+ //}
+ var issuedUtc = context.Properties.IssuedUtc;
+
+ // Only validate if enough time has elapsed
+ var validate = (issuedUtc == null);
+ if (issuedUtc != null)
+ {
+ var timeElapsed = currentUtc.Subtract(issuedUtc.Value);
+ validate = timeElapsed > validateInterval;
+ }
+ if (validate && context.Principal?.Identity is ClaimsIdentity claimsIdentity)
+ {
+ var manager = context.HttpContext.GetUserManager();
+ var userId = getUserIdCallback(claimsIdentity);
+ if (manager != null && userId != null)
+ {
+ var user = await manager.FindByIdAsync(userId).WithCurrentCulture();
+ var reject = true;
+ // Refresh the identity if the stamp matches, otherwise reject
+ if (user != null && manager.SupportsUserSecurityStamp)
+ {
+ var securityStamp =
+ claimsIdentity.FindFirstValue(Constants.DefaultSecurityStampClaimType);
+ if (securityStamp == await manager.GetSecurityStampAsync(userId).WithCurrentCulture())
+ {
+ reject = false;
+ // Regenerate fresh claims if possible and resign in
+ if (regenerateIdentityCallback != null)
+ {
+ var identity = await regenerateIdentityCallback.Invoke(manager, user).WithCurrentCulture();
+ if (identity != null)
+ {
+ // Fix for regression where this value is not updated
+ // Setting it to null so that it is refreshed by the cookie middleware
+ await context.HttpContext.SignInAsync(new ClaimsPrincipal(identity), context.Properties);
+
+ // moved after SignIn so the test passes
+ context.Properties.IssuedUtc = null;
+ context.Properties.ExpiresUtc = null;
+ }
+ }
+ }
+ }
+ if (reject)
+ {
+ context.RejectPrincipal();
+ await context.HttpContext.SignOutAsync();
+ }
+ }
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/SignInManager.cs b/src/Microsoft.AspNet.Identity.AspNetCore/SignInManager.cs
new file mode 100644
index 0000000..341340c
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/SignInManager.cs
@@ -0,0 +1,299 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Globalization;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Http;
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Manages Sign In operations for users
+ ///
+ ///
+ ///
+ public class SignInManager : IDisposable
+ where TUser : class, IUser
+ where TKey : IEquatable
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ ///
+ public SignInManager(UserManager userManager, HttpContext authenticationManager)
+ {
+ if (userManager == null)
+ {
+ throw new ArgumentNullException("userManager");
+ }
+ if (authenticationManager == null)
+ {
+ throw new ArgumentNullException("authenticationManager");
+ }
+ UserManager = userManager;
+ AuthenticationManager = authenticationManager;
+ }
+
+ private string _authType;
+ ///
+ /// AuthenticationType that will be used by sign in, defaults to DefaultAuthenticationTypes.ApplicationCookie
+ ///
+ public string AuthenticationType
+ {
+ get { return _authType ?? DefaultAuthenticationTypes.ApplicationCookie; }
+ set { _authType = value; }
+ }
+
+ ///
+ /// Used to operate on users
+ ///
+ public UserManager UserManager { get; set; }
+
+ ///
+ /// Used to sign in identities
+ ///
+ public HttpContext AuthenticationManager { get; set; }
+
+ ///
+ /// Called to generate the ClaimsIdentity for the user, override to add additional claims before SignIn
+ ///
+ ///
+ ///
+ public virtual Task CreateUserIdentityAsync(TUser user)
+ {
+ return UserManager.CreateIdentityAsync(user, AuthenticationType);
+ }
+
+ ///
+ /// Convert a TKey userId to a string, by default this just calls ToString()
+ ///
+ ///
+ ///
+ public virtual string ConvertIdToString(TKey id)
+ {
+ return Convert.ToString(id, CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Convert a string id to the proper TKey using Convert.ChangeType
+ ///
+ ///
+ ///
+ public virtual TKey ConvertIdFromString(string id)
+ {
+ if (id == null)
+ {
+ return default(TKey);
+ }
+ return (TKey)Convert.ChangeType(id, typeof(TKey), CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Creates a user identity and then signs the identity using the AuthenticationManager
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task SignInAsync(TUser user, bool isPersistent, bool rememberBrowser)
+ {
+ var userIdentity = await CreateUserIdentityAsync(user).WithCurrentCulture();
+ // Clear any partial cookies from external or two factor partial sign ins
+ await AuthenticationManager.SignOutAsync(DefaultAuthenticationTypes.ExternalCookie);
+ await AuthenticationManager.SignOutAsync(DefaultAuthenticationTypes.TwoFactorCookie);
+ if (rememberBrowser)
+ {
+ var rememberBrowserIdentity = AuthenticationManager.CreateTwoFactorRememberBrowserIdentity(ConvertIdToString(user.Id));
+ await AuthenticationManager.SignInAsync(new ClaimsPrincipal(new[] { userIdentity, rememberBrowserIdentity }), new AuthenticationProperties { IsPersistent = isPersistent });
+ }
+ else
+ {
+ await AuthenticationManager.SignInAsync(new ClaimsPrincipal(userIdentity), new AuthenticationProperties { IsPersistent = isPersistent });
+ }
+ }
+
+ ///
+ /// Send a two factor code to a user
+ ///
+ ///
+ ///
+ public virtual async Task SendTwoFactorCodeAsync(string provider)
+ {
+ var userId = await GetVerifiedUserIdAsync().WithCurrentCulture();
+ if (userId == null)
+ {
+ return false;
+ }
+
+ var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider).WithCurrentCulture();
+ // See IdentityConfig.cs to plug in Email/SMS services to actually send the code
+ await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token).WithCurrentCulture();
+ return true;
+ }
+
+ ///
+ /// Get the user id that has been verified already or null.
+ ///
+ ///
+ public async Task GetVerifiedUserIdAsync()
+ {
+ var result = await AuthenticationManager.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorCookie).WithCurrentCulture();
+ if (result?.Principal?.Identity is ClaimsIdentity claimsIdentity && !String.IsNullOrEmpty(claimsIdentity.GetUserId()))
+ {
+ return ConvertIdFromString(claimsIdentity.GetUserId());
+ }
+ return default(TKey);
+ }
+
+ ///
+ /// Has the user been verified (ie either via password or external login)
+ ///
+ ///
+ public async Task HasBeenVerifiedAsync()
+ {
+ return await GetVerifiedUserIdAsync().WithCurrentCulture() != null;
+ }
+
+ ///
+ /// Two factor verification step
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberBrowser)
+ {
+ var userId = await GetVerifiedUserIdAsync().WithCurrentCulture();
+ if (userId == null)
+ {
+ return SignInStatus.Failure;
+ }
+ var user = await UserManager.FindByIdAsync(userId).WithCurrentCulture();
+ if (user == null)
+ {
+ return SignInStatus.Failure;
+ }
+ if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
+ {
+ return SignInStatus.LockedOut;
+ }
+ if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, provider, code).WithCurrentCulture())
+ {
+ // When token is verified correctly, clear the access failed count used for lockout
+ await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture();
+ await SignInAsync(user, isPersistent, rememberBrowser).WithCurrentCulture();
+ return SignInStatus.Success;
+ }
+ // If the token is incorrect, record the failure which also may cause the user to be locked out
+ await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture();
+ return SignInStatus.Failure;
+ }
+
+ ///
+ /// Sign the user in using an associated external login
+ ///
+ ///
+ ///
+ ///
+ public async Task ExternalSignInAsync(ExternalLoginInfo loginInfo, bool isPersistent)
+ {
+ var user = await UserManager.FindAsync(loginInfo.Login).WithCurrentCulture();
+ if (user == null)
+ {
+ return SignInStatus.Failure;
+ }
+ if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
+ {
+ return SignInStatus.LockedOut;
+ }
+ return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture();
+ }
+
+ private async Task IsTwoFactorEnabled(TUser user)
+ {
+ return await UserManager.GetTwoFactorEnabledAsync(user.Id).WithCurrentCulture()
+ && (await UserManager.GetValidTwoFactorProvidersAsync(user.Id).WithCurrentCulture()).Count > 0;
+ }
+
+ private async Task SignInOrTwoFactor(TUser user, bool isPersistent)
+ {
+ var id = Convert.ToString(user.Id);
+ if (await IsTwoFactorEnabled(user) && !await AuthenticationManager.TwoFactorBrowserRememberedAsync(id).WithCurrentCulture())
+ {
+ var identity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorCookie);
+ identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id));
+ await AuthenticationManager.SignInAsync(new ClaimsPrincipal(identity));
+ return SignInStatus.RequiresVerification;
+ }
+ await SignInAsync(user, isPersistent, false).WithCurrentCulture();
+ return SignInStatus.Success;
+ }
+
+ ///
+ /// Sign in the user in using the user name and password
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual async Task PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
+ {
+ if (UserManager == null)
+ {
+ return SignInStatus.Failure;
+ }
+ var user = await UserManager.FindByNameAsync(userName).WithCurrentCulture();
+ if (user == null)
+ {
+ return SignInStatus.Failure;
+ }
+ if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
+ {
+ return SignInStatus.LockedOut;
+ }
+ if (await UserManager.CheckPasswordAsync(user, password).WithCurrentCulture())
+ {
+ if (!await IsTwoFactorEnabled(user))
+ {
+ await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture();
+ }
+ return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture();
+ }
+ if (shouldLockout)
+ {
+ // If lockout is requested, increment access failed count which might lock out the user
+ await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture();
+ if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
+ {
+ return SignInStatus.LockedOut;
+ }
+ }
+ return SignInStatus.Failure;
+ }
+
+
+ ///
+ /// Dispose
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// If disposing, calls dispose on the Context. Always nulls out the Context
+ ///
+ ///
+ protected virtual void Dispose(bool disposing)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/SignInStatus.cs b/src/Microsoft.AspNet.Identity.AspNetCore/SignInStatus.cs
new file mode 100644
index 0000000..d78402a
--- /dev/null
+++ b/src/Microsoft.AspNet.Identity.AspNetCore/SignInStatus.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
+// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNet.Identity.AspNetCore
+{
+ ///
+ /// Possible results from a sign in attempt
+ ///
+ public enum SignInStatus
+ {
+ ///
+ /// Sign in was successful
+ ///
+ Success,
+
+ ///
+ /// User is locked out
+ ///
+ LockedOut,
+
+ ///
+ /// Sign in requires addition verification (i.e. two factor)
+ ///
+ RequiresVerification,
+
+ ///
+ /// Sign in failed
+ ///
+ Failure
+ }
+
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core.csproj b/src/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core.csproj
index abb0548..ceaefe2 100644
--- a/src/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core.csproj
+++ b/src/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core.csproj
@@ -1,126 +1,30 @@
-
-
-
+
- Debug
- AnyCPU
- {D2F24972-0F56-4C18-BD65-C26A320A0C68}
+ netstandard2.1;net45
Library
- Properties
Microsoft.AspNet.Identity
- Microsoft.AspNet.Identity.Core
- v4.5
- 512
- SAK
- SAK
- SAK
- SAK
-
- bin\$(Configuration)
-
-
- true
- full
- false
- DEBUG;TRACE
- prompt
- 4
- false
- bin\Debug\Microsoft.AspNet.Identity.Core.XML
- true
- Sdl6.1.ruleset
-
-
- pdbonly
- true
- TRACE
- prompt
- 4
- false
- bin\Release\Microsoft.AspNet.Identity.Core.XML
-
-
+ false
+ Microsoft.AspNet.Identity.Core
+ Microsoft
+ Microsoft.AspNet.Identity.Core
+ Copyright © Microsoft 2012
+ 2.0.0.0
+ 2.1.0.0
+ 35MSSharedLib1024.snk
true
-
-
true
-
- 35MSSharedLib1024.snk
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
True
True
Resources.resx
-
-
-
-
-
-
-
-
-
-
-
-
+
ResXFileCodeGenerator
Resources.Designer.cs
-
-
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs
index ac3397a..1f673ae 100644
--- a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs
+++ b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs
@@ -5,17 +5,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-
-[assembly: AssemblyTitle("Microsoft.AspNet.Identity.Core")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("Microsoft.AspNet.Identity.Core")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: CLSCompliant(true)]
@@ -29,25 +18,15 @@
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e318dfc7-3a02-42a5-bb45-16c143f61c30")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-
-[assembly: AssemblyVersion("2.0.0.0")]
-[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly:
InternalsVisibleTo(
"Microsoft.AspNet.Identity.Owin, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9"
- )]
+ )]
+[assembly:
+ InternalsVisibleTo(
+ "Microsoft.AspNet.Identity.AspNetCore, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9"
+ )]
[assembly:
InternalsVisibleTo(
"Microsoft.AspNet.Identity.EntityFramework, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9"
diff --git a/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs b/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs
index 26b1e45..764da92 100644
--- a/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.34011
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Identity {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/App.config b/src/Microsoft.AspNet.Identity.EntityFramework/App.config
deleted file mode 100644
index 03207fa..0000000
--- a/src/Microsoft.AspNet.Identity.EntityFramework/App.config
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs b/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs
index feff65b..943d01c 100644
--- a/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs
+++ b/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.34003
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -9,6 +9,9 @@
//------------------------------------------------------------------------------
namespace Microsoft.AspNet.Identity.EntityFramework {
+ using System;
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -16,7 +19,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class IdentityResources {
diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj b/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj
index 86aa2d8..f8659da 100644
--- a/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj
+++ b/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj
@@ -1,114 +1,37 @@
-
-
-
+
- Debug
- AnyCPU
- {D7298DAD-AB04-4502-9567-0461D0AD059E}
+ netstandard2.1;net45
Library
- bin\$(Configuration)
- Properties
- Microsoft.AspNet.Identity.EntityFramework
- Microsoft.AspNet.Identity.EntityFramework
- v4.5
- 512
- SAK
- SAK
- SAK
- SAK
- ..\..\
- true
-
-
- true
- full
- false
- DEBUG;TRACE
- prompt
- 4
- bin\Debug\Microsoft.AspNet.Identity.EntityFramework.XML
- true
- Sdl6.1.ruleset
-
-
- pdbonly
- true
- TRACE
- prompt
- 4
- bin\Release\Microsoft.AspNet.Identity.EntityFramework.XML
-
-
+ false
+ Microsoft.AspNet.Identity.EntityFramework
+ Microsoft
+ Microsoft.AspNet.Identity.EntityFramework
+ Copyright © Microsoft 2013
+ 2.0.0.0
+ 2.1.0.0
+ 35MSSharedLib1024.snk
true
-
-
true
-
- 35MSSharedLib1024.snk
-
-
-
- False
- ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll
-
-
- False
- ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
True
True
IdentityResources.resx
-
-
-
-
-
-
- {d2f24972-0f56-4c18-bd65-c26a320a0c68}
- Microsoft.AspNet.Identity.Core
-
+
-
-
-
-
-
-
+
ResXFileCodeGenerator
IdentityResources.Designer.cs
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs
index 888e2f5..d57e3f3 100644
--- a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs
+++ b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs
@@ -5,17 +5,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-
-[assembly: AssemblyTitle("Microsoft.AspNet.Identity.EntityFramework")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Microsoft")]
-[assembly: AssemblyProduct("Microsoft.AspNet.Identity.EntityFramework")]
-[assembly: AssemblyCopyright("Copyright © Microsoft 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -29,20 +18,6 @@
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("17d56636-0d8d-401e-9484-da7965dcf45a")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-
-[assembly: AssemblyVersion("2.0.0.0")]
-[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly:
InternalsVisibleTo(
diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/packages.config b/src/Microsoft.AspNet.Identity.EntityFramework/packages.config
deleted file mode 100644
index 04b3bca..0000000
--- a/src/Microsoft.AspNet.Identity.EntityFramework/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj b/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj
index 13cce96..3993e0d 100644
--- a/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj
+++ b/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj
@@ -1,118 +1,26 @@
-
-
-
+
- Debug
- AnyCPU
- {943170EB-F4E7-4A6D-989E-2CF6C681DD89}
+ net45
Library
bin\$(Configuration)
- Properties
- Microsoft.AspNet.Identity.Owin
- Microsoft.AspNet.Identity.Owin
- v4.5
- 512
- SAK
- SAK
- SAK
- SAK
..\..\
true
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- Sdl6.1.ruleset
- true
- bin\Debug\Microsoft.AspNet.Identity.Owin.XML
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- bin\Release\Microsoft.AspNet.Identity.Owin.XML
-
-
+ false
+ 35MSSharedLib1024.snk
true
-
-
true
-
- 35MSSharedLib1024.snk
-
-
-
- ..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
-
-
- ..\..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll
-
-
- ..\..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll
-
-
- ..\..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll
-
-
- False
- ..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
-
-
- False
- ..\..\packages\Owin.1.0\lib\net40\Owin.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {d2f24972-0f56-4c18-bd65-c26a320a0c68}
- Microsoft.AspNet.Identity.Core
-
+
-
-
-
+
+
+
+
+
+
+
+
-
-
-
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.Owin/app.config b/src/Microsoft.AspNet.Identity.Owin/app.config
deleted file mode 100644
index bf90bf8..0000000
--- a/src/Microsoft.AspNet.Identity.Owin/app.config
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Identity.Owin/packages.config b/src/Microsoft.AspNet.Identity.Owin/packages.config
deleted file mode 100644
index b803355..0000000
--- a/src/Microsoft.AspNet.Identity.Owin/packages.config
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/Identity.Test/App.config b/test/Identity.Test/App.config
deleted file mode 100644
index f9b0fef..0000000
--- a/test/Identity.Test/App.config
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/Identity.Test/ApplicationUserTest.cs b/test/Identity.Test/ApplicationUserTest.cs
index a2ba0ed..04ec87a 100644
--- a/test/Identity.Test/ApplicationUserTest.cs
+++ b/test/Identity.Test/ApplicationUserTest.cs
@@ -7,15 +7,24 @@
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
+
+#if NETFRAMEWORK
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.DataProtection;
+#else
+using Microsoft.AspNet.Identity.AspNetCore;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.DataProtection;
+#endif
+
using Xunit;
namespace Identity.Test
{
public class ApplicationUserTest
{
+#if NETFRAMEWORK
private async Task CreateManager(OwinContext context)
{
var options = new IdentityFactoryOptions
@@ -41,6 +50,33 @@ private async Task CreateManager(OwinContext context)
});
await dbMiddle.Invoke(context);
}
+#else
+ private async Task CreateManager(HttpContext context)
+ {
+ var options = new IdentityFactoryOptions
+ {
+ DataProtectionProvider = new EphemeralDataProtectionProvider(),
+ Provider = new IdentityFactoryProvider
+ {
+ OnCreate = (o, c) => ApplicationUserManager.Create(o, c)
+ }
+ };
+ var middleware =
+ new IdentityFactoryMiddleware>(
+ options);
+ var dbMiddle =
+ new IdentityFactoryMiddleware>(
+ new IdentityFactoryOptions
+ {
+ Provider = new IdentityFactoryProvider
+ {
+ OnCreate = (o, c) => CreateDb()
+ }
+ });
+ await dbMiddle.InvokeAsync(context, c => middleware.InvokeAsync(c, null));
+ }
+#endif
+
[Fact]
public void EnsureDefaultSchemaWithApplicationUser()
@@ -51,9 +87,9 @@ public void EnsureDefaultSchemaWithApplicationUser()
[Fact]
public async Task ApplicationUserCreateTest()
{
- var owinContext = new OwinContext();
- await CreateManager(owinContext);
- var manager = owinContext.GetUserManager();
+ var context = GlobalHelpers.CreateContext();
+ await CreateManager(context);
+ var manager = context.GetUserManager();
ApplicationUser[] users =
{
new ApplicationUser {UserName = "test", Email = "test@test.com"},
@@ -168,7 +204,12 @@ public ApplicationUserManager(IUserStore store)
}
public static ApplicationUserManager Create(IdentityFactoryOptions options,
- IOwinContext context)
+#if NETFRAMEWORK
+ IOwinContext context
+#else
+ HttpContext context
+#endif
+ )
{
var manager =
new ApplicationUserManager(new UserStore(context.Get()));
diff --git a/test/Identity.Test/AuthenticationManagerExtensionsTest.cs b/test/Identity.Test/AuthenticationManagerExtensionsTest.cs
index f0d3712..7c7cfa1 100644
--- a/test/Identity.Test/AuthenticationManagerExtensionsTest.cs
+++ b/test/Identity.Test/AuthenticationManagerExtensionsTest.cs
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+#if NETFRAMEWORK
using System.Security.Claims;
using System.Threading.Tasks;
@@ -37,11 +38,11 @@ public async Task GetExternalLoginReturnsNullIfNoNameIdentifierTest()
var manager = new Mock();
manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"),
- new AuthenticationProperties(), new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"),
+ new AuthenticationProperties())));
Assert.Null(await manager.Object.GetExternalLoginInfoAsync());
}
-
+
[Fact]
public async Task GetExternalLoginDoesNotBlowUpWithNullName()
{
@@ -50,8 +51,8 @@ public async Task GetExternalLoginDoesNotBlowUpWithNullName()
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "foo"));
manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(identity,
- new AuthenticationProperties(), new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(identity,
+ new AuthenticationProperties())));
var externalInfo = await manager.Object.GetExternalLoginInfoAsync();
Assert.NotNull(externalInfo);
}
@@ -71,8 +72,8 @@ public async Task GetExternalLoginWithXsrfReturnsNullIfNoNameIdentifierTest()
var manager = new Mock();
manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"),
- new AuthenticationProperties(), new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"),
+ new AuthenticationProperties())));
Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo"));
}
@@ -82,8 +83,7 @@ public async Task GetExternalLoginWithXsrfReturnsNullIfNoClaimsIdentityTest()
var manager = new Mock();
manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(null, new AuthenticationProperties(),
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(null, new AuthenticationProperties())));
Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo"));
}
@@ -99,7 +99,7 @@ public async Task GetExternalLoginTest()
};
var identity = CreateIdentity(loginInfo);
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
- .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription())));
+ .Returns(Task.FromResult(GlobalHelpers.CreateAuthenticateResult(identity, props)));
var manager = mockManager.Object;
var externalInfo = await manager.GetExternalLoginInfoAsync();
Assert.NotNull(externalInfo);
@@ -121,8 +121,7 @@ public void GetExternalLoginSyncTest()
};
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props,
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props)));
var manager = mockManager.Object;
var externalInfo = manager.GetExternalLoginInfo();
Assert.NotNull(externalInfo);
@@ -136,7 +135,7 @@ public async Task GetExternalLoginWithXsrfTest()
{
var mockManager = new Mock();
var props = new AuthenticationProperties();
- props.Dictionary["xsrfKey"] = "Hao";
+ props.GetPropertiesDictionary()["xsrfKey"] = "Hao";
var loginInfo = new ExternalLoginInfo
{
Login = new UserLoginInfo("loginProvider", "key"),
@@ -144,8 +143,7 @@ public async Task GetExternalLoginWithXsrfTest()
};
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props,
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props)));
var manager = mockManager.Object;
var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "Hao");
Assert.NotNull(externalInfo);
@@ -159,7 +157,7 @@ public void GetExternalLoginWithXsrfSyncTest()
{
var mockManager = new Mock();
var props = new AuthenticationProperties();
- props.Dictionary["xsrfKey"] = "Hao";
+ props.GetPropertiesDictionary()["xsrfKey"] = "Hao";
var loginInfo = new ExternalLoginInfo
{
Login = new UserLoginInfo("loginProvider", "key"),
@@ -167,8 +165,7 @@ public void GetExternalLoginWithXsrfSyncTest()
};
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props,
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props)));
var manager = mockManager.Object;
var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "Hao");
Assert.NotNull(externalInfo);
@@ -182,7 +179,7 @@ public async Task GetExternalLoginNullIfXsrfFailsTest()
{
var mockManager = new Mock();
var props = new AuthenticationProperties();
- props.Dictionary["xsrfKey"] = "Hao";
+ props.GetPropertiesDictionary()["xsrfKey"] = "Hao";
var loginInfo = new ExternalLoginInfo
{
Login = new UserLoginInfo("loginProvider", "key"),
@@ -190,8 +187,7 @@ public async Task GetExternalLoginNullIfXsrfFailsTest()
};
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props,
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props)));
var manager = mockManager.Object;
var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "NotHao");
Assert.Null(externalInfo);
@@ -202,7 +198,7 @@ public void GetExternalLoginNullIfXsrfFailsSyncTest()
{
var mockManager = new Mock();
var props = new AuthenticationProperties();
- props.Dictionary["xsrfKey"] = "Hao";
+ props.GetPropertiesDictionary()["xsrfKey"] = "Hao";
var loginInfo = new ExternalLoginInfo
{
Login = new UserLoginInfo("loginProvider", "key"),
@@ -210,8 +206,7 @@ public void GetExternalLoginNullIfXsrfFailsSyncTest()
};
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props,
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props)));
var manager = mockManager.Object;
var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "NotHao");
Assert.Null(externalInfo);
@@ -223,8 +218,8 @@ public async Task GetExternalIdentityReturnsNullIfNoNameIdentifierTest()
var manager = new Mock();
manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"),
- new AuthenticationProperties(), new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"),
+ new AuthenticationProperties())));
Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie));
}
@@ -234,8 +229,8 @@ public async Task GetExternalIdentityReturnsNullIfNullNameTest()
var manager = new Mock();
manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateNoClaimIdentity("authtype"),
- new AuthenticationProperties(), new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoClaimIdentity("authtype"),
+ new AuthenticationProperties())));
Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie));
}
@@ -251,8 +246,7 @@ public async Task GetExternalIdentityTest()
};
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props,
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props)));
var manager = mockManager.Object;
var id = await manager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
Assert.NotNull(id);
@@ -282,7 +276,7 @@ public async Task BrowserRemeberedTest()
var props = new AuthenticationProperties();
var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId");
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie))
- .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription())));
+ .Returns(Task.FromResult(GlobalHelpers.CreateAuthenticateResult(identity, props)));
Assert.True(await manager.TwoFactorBrowserRememberedAsync("userId"));
Assert.False(await manager.TwoFactorBrowserRememberedAsync("userNotId"));
}
@@ -294,7 +288,7 @@ public async Task BrowserRemeberedFailWithNoIdentityTest()
var manager = mockManager.Object;
var props = new AuthenticationProperties();
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie))
- .Returns(Task.FromResult(new AuthenticateResult(null, props, new AuthenticationDescription())));
+ .Returns(Task.FromResult(GlobalHelpers.CreateAuthenticateResult(null, props)));
Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId"));
}
@@ -306,8 +300,7 @@ public async Task BrowserRemeberedFailWithWrongIdentityTest()
var props = new AuthenticationProperties();
mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie))
.Returns(
- Task.FromResult(new AuthenticateResult(new ClaimsIdentity("whatever"), props,
- new AuthenticationDescription())));
+ Task.FromResult(GlobalHelpers.CreateAuthenticateResult(new ClaimsIdentity("whatever"), props)));
Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId"));
}
@@ -325,7 +318,7 @@ public static ClaimsIdentity CreateNoNameIdentifierIdentity(string name, string
public static ClaimsIdentity CreateNoClaimIdentity(string authenticationType)
{
return new ClaimsIdentity(
- new Claim[] {},
+ new Claim[] { },
authenticationType);
}
@@ -340,4 +333,5 @@ public static ClaimsIdentity CreateIdentity(ExternalLoginInfo info)
info.Login.LoginProvider);
}
}
-}
\ No newline at end of file
+}
+#endif
diff --git a/test/Identity.Test/CustomGuidKeyTest.cs b/test/Identity.Test/CustomGuidKeyTest.cs
index 023f500..d35d9e1 100644
--- a/test/Identity.Test/CustomGuidKeyTest.cs
+++ b/test/Identity.Test/CustomGuidKeyTest.cs
@@ -8,11 +8,21 @@
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
+
+#if NETFRAMEWORK
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.DataProtection;
+#else
+using Microsoft.AspNet.Identity.AspNetCore;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.DataProtection;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+#endif
+
using Xunit;
namespace Identity.Test
@@ -85,7 +95,7 @@ public async Task CustomGuidGetRolesForUserTest()
[Fact]
public async Task CustomGuidConfirmEmailTest()
{
- var owinContext = new OwinContext();
+ var owinContext = GlobalHelpers.CreateContext();
await CreateManager(owinContext);
var manager = owinContext.GetUserManager>();
var user = new GuidUser("test");
@@ -94,15 +104,15 @@ public async Task CustomGuidConfirmEmailTest()
var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id);
Assert.NotNull(token);
UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token));
- Assert.True(await manager.IsEmailConfirmedAsync(user.Id));
+ Assert.True((bool)await manager.IsEmailConfirmedAsync(user.Id));
UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null));
- Assert.False(await manager.IsEmailConfirmedAsync(user.Id));
+ Assert.False((bool)await manager.IsEmailConfirmedAsync(user.Id));
}
[Fact]
public async Task CustomGuidEmailTokenFactorWithFormatTest()
{
- var owinContext = new OwinContext();
+ var owinContext = GlobalHelpers.CreateContext();
await CreateManager(owinContext);
var manager = owinContext.GetUserManager>();
var messageService = new TestMessageService();
@@ -126,25 +136,26 @@ public async Task CustomGuidEmailTokenFactorWithFormatTest()
Assert.NotNull(messageService.Message);
Assert.Equal("Security Code", messageService.Message.Subject);
Assert.Equal("Your code is: " + token, messageService.Message.Body);
- Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token));
+ Assert.True((bool)await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token));
}
[Fact]
public async Task OnValidateIdentityWithGuidTest()
{
- var owinContext = new OwinContext();
+ var owinContext = GlobalHelpers.CreateContext();
await CreateManager(owinContext);
var manager = owinContext.GetUserManager>();
- var user = new GuidUser {UserName = "test"};
+ var user = new GuidUser { UserName = "test" };
UnitTestHelper.IsSuccess(await manager.CreateAsync(user));
var id = await SignIn(manager, user);
- var ticket = new AuthenticationTicket(id, new AuthenticationProperties {IssuedUtc = DateTimeOffset.UtcNow});
- var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions());
+ var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow });
+ var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions());
await
SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero,
SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context);
- Assert.NotNull(context.Identity);
+ var claimsIdentity = context.ExtractClaimsIdentity();
+ Assert.NotNull(claimsIdentity);
Assert.Equal(user.Id.ToString(), id.GetUserId());
// change stamp and make sure it fails
@@ -152,7 +163,8 @@ public async Task OnValidateIdentityWithGuidTest()
await
SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero,
SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context);
- Assert.Null(context.Identity);
+ claimsIdentity = context.ExtractClaimsIdentity();
+ Assert.Null(claimsIdentity);
}
private Task SignIn(UserManager manager, GuidUser user)
@@ -160,6 +172,7 @@ private Task SignIn(UserManager manager, GuidUse
return manager.ClaimsIdentityFactory.CreateAsync(manager, user, DefaultAuthenticationTypes.ApplicationCookie);
}
+#if NETFRAMEWORK
private async Task CreateManager(OwinContext context)
{
var options = new IdentityFactoryOptions>
@@ -180,6 +193,28 @@ private async Task CreateManager(OwinContext context)
});
await dbMiddle.Invoke(context);
}
+#else
+ private async Task CreateManager(HttpContext context)
+ {
+ var options = new IdentityFactoryOptions>
+ {
+ Provider = new TestProvider(),
+ DataProtectionProvider = new EphemeralDataProtectionProvider()
+ };
+ var middleware =
+ new IdentityFactoryMiddleware
+ , IdentityFactoryOptions>>(options);
+ var dbMiddle = new IdentityFactoryMiddleware>(
+ new IdentityFactoryOptions
+ {
+ Provider = new IdentityFactoryProvider
+ {
+ OnCreate = (o, c) => GuidUserContext.Create(),
+ }
+ });
+ await dbMiddle.InvokeAsync(context, c => middleware.InvokeAsync(c, null));
+ }
+#endif
public class GuidRole : IdentityRole
{
diff --git a/test/Identity.Test/CustomIntKeyTest.cs b/test/Identity.Test/CustomIntKeyTest.cs
index 7c6622a..703f5ae 100644
--- a/test/Identity.Test/CustomIntKeyTest.cs
+++ b/test/Identity.Test/CustomIntKeyTest.cs
@@ -6,9 +6,16 @@
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
+
+#if NETFRAMEWORK
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.DataProtection;
+#else
+using Microsoft.AspNet.Identity.AspNetCore;
+using Microsoft.AspNetCore.DataProtection;
+#endif
+
using Xunit;
namespace Identity.Test
@@ -109,9 +116,9 @@ private UserManager CreateManager()
var options = new IdentityFactoryOptions>
{
Provider = new TestProvider(),
- DataProtectionProvider = new DpapiDataProtectionProvider()
+ DataProtectionProvider = GlobalHelpers.CreateDataProtectionProvider()
};
- return options.Provider.Create(options, new OwinContext());
+ return options.Provider.Create(options, GlobalHelpers.CreateContext());
}
public class CustomRole : IdentityRole
diff --git a/test/Identity.Test/ExceptionHelper.cs b/test/Identity.Test/ExceptionHelper.cs
index b8627bc..a9e3194 100644
--- a/test/Identity.Test/ExceptionHelper.cs
+++ b/test/Identity.Test/ExceptionHelper.cs
@@ -8,7 +8,7 @@ namespace Identity.Test
{
public static class ExceptionHelper
{
- public static TException ThrowsWithError(Assert.ThrowsDelegate act, string error)
+ public static TException ThrowsWithError(Action act, string error)
where TException : Exception
{
var e = Assert.Throws(act);
@@ -19,7 +19,7 @@ public static TException ThrowsWithError(Assert.ThrowsDelegate act,
return e;
}
- public static ArgumentException ThrowsArgumentException(Assert.ThrowsDelegate del, string exceptionMessage,
+ public static ArgumentException ThrowsArgumentException(Action del, string exceptionMessage,
string paramName)
{
var e = Assert.Throws(del);
@@ -33,13 +33,18 @@ public static ArgumentException ThrowsArgumentException(Assert.ThrowsDelegate de
return e;
}
- public static ArgumentException ThrowsArgumentNullOrEmpty(Assert.ThrowsDelegate del, string paramName)
+ public static ArgumentException ThrowsArgumentNullOrEmpty(Action del, string paramName)
{
+#if NETFRAMEWORK
return ThrowsArgumentException(del, "Value cannot be null or empty.\r\nParameter name: " + paramName,
paramName);
+#else
+ return ThrowsArgumentException(del, "Value cannot be null or empty. (Parameter '" + paramName + "')",
+ paramName);
+#endif
}
- public static ArgumentNullException ThrowsArgumentNull(Assert.ThrowsDelegate del, string paramName)
+ public static ArgumentNullException ThrowsArgumentNull(Action del, string paramName)
{
var e = Assert.Throws(del);
Assert.Equal(paramName, e.ParamName);
diff --git a/test/Identity.Test/GlobalHelpers.cs b/test/Identity.Test/GlobalHelpers.cs
new file mode 100644
index 0000000..06e8e12
--- /dev/null
+++ b/test/Identity.Test/GlobalHelpers.cs
@@ -0,0 +1,110 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+
+#if NETFRAMEWORK
+using Microsoft.Owin;
+using Microsoft.Owin.Security;
+using Microsoft.Owin.Security.Cookies;
+using Microsoft.Owin.Security.DataProtection;
+#else
+using Microsoft.AspNet.Identity;
+using Microsoft.AspNet.Identity.AspNetCore;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.DataProtection;
+using Microsoft.Extensions.DependencyInjection;
+#endif
+
+namespace Identity.Test
+{
+ public static class GlobalHelpers
+ {
+#if NETFRAMEWORK
+ public static OwinContext CreateContext()
+ {
+ return new OwinContext();
+ }
+
+ public static CookieValidateIdentityContext CreateCookieValidateIdentityContext(IOwinContext owinContext, AuthenticationTicket ticket, CookieAuthenticationOptions cookieAuthenticationOptions)
+ {
+ return new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions());
+ }
+
+ public static AuthenticationTicket CreateAuthenticationTicket(ClaimsIdentity id, AuthenticationProperties authenticationProperties)
+ {
+ return new AuthenticationTicket(id, authenticationProperties);
+ }
+
+ public static AuthenticateResult CreateAuthenticateResult(ClaimsIdentity identity, AuthenticationProperties properties)
+ {
+ return new AuthenticateResult(identity, properties, new AuthenticationDescription());
+ }
+
+ public static IDictionary GetPropertiesDictionary(this AuthenticationProperties props)
+ {
+ return props.Dictionary;
+ }
+
+ public static ClaimsIdentity ExtractClaimsIdentity(this CookieValidateIdentityContext context)
+ {
+ return context.Identity;
+ }
+
+ public static IDataProtectionProvider CreateDataProtectionProvider()
+ {
+ return new DpapiDataProtectionProvider();
+ }
+#else
+ public static DefaultHttpContext CreateContext()
+ {
+ var services = new ServiceCollection();
+ services.AddAuthentication(DefaultAuthenticationTypes.ExternalCookie)
+ .AddCookie(DefaultAuthenticationTypes.ExternalCookie)
+ .AddCookie(DefaultAuthenticationTypes.TwoFactorCookie);
+ services.AddLogging();
+
+ return new DefaultHttpContext()
+ {
+ RequestServices = services.BuildServiceProvider()
+ };
+ }
+
+ public static CookieValidatePrincipalContext CreateCookieValidateIdentityContext(DefaultHttpContext owinContext, AuthenticationTicket ticket, CookieAuthenticationOptions cookieAuthenticationOptions)
+ {
+ return new CookieValidatePrincipalContext(owinContext, new AuthenticationScheme(ticket.AuthenticationScheme, null, typeof(CookieAuthenticationHandler)), new CookieAuthenticationOptions(), ticket);
+ }
+
+ public static AuthenticationTicket CreateAuthenticationTicket(ClaimsIdentity id, AuthenticationProperties authenticationProperties)
+ {
+ return new AuthenticationTicket(new ClaimsPrincipal(id), authenticationProperties, id.AuthenticationType);
+ }
+
+ public static AuthenticateResult CreateAuthenticateResult(ClaimsIdentity identity, AuthenticationProperties properties)
+ {
+ return AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(identity), properties, identity.AuthenticationType));
+ }
+
+ public static IDictionary GetPropertiesDictionary(this AuthenticationProperties props)
+ {
+ return props.Parameters;
+ }
+
+ public static ClaimsIdentity? ExtractClaimsIdentity(this CookieValidatePrincipalContext context)
+ {
+ return context.Principal?.Identity as ClaimsIdentity;
+ }
+
+ public static IDataProtector Create(this IDataProtectionProvider provider, string purpose, params string[] subPurpose)
+ {
+ return provider.CreateProtector(purpose, subPurpose);
+ }
+
+ public static IDataProtectionProvider CreateDataProtectionProvider()
+ {
+ return new EphemeralDataProtectionProvider();
+ }
+#endif
+ }
+}
\ No newline at end of file
diff --git a/test/Identity.Test/Identity.Test.csproj b/test/Identity.Test/Identity.Test.csproj
index 9e2b927..ed6f030 100644
--- a/test/Identity.Test/Identity.Test.csproj
+++ b/test/Identity.Test/Identity.Test.csproj
@@ -1,177 +1,42 @@
-
-
-
- Debug
- AnyCPU
- {A7082BDD-985B-47B9-915B-7FA4CF541B5E}
- Library
- bin\$(Configuration)
- Properties
- Identity.Test
- Identity.Test
- v4.5
- 512
- {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
- $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
- False
- UnitTest
- SAK
- SAK
- SAK
- SAK
- ..\..\
- true
-
-
- true
- full
- false
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- TRACE
- prompt
- 4
-
+
+ net6.0;net462
+ false
+ true
+ false
+ Identity.SystemWeb.Test
+ Microsoft
+ Identity.SystemWeb.Test
+ Copyright © Microsoft 2013
+ 1.0.0.0
+ 1.0.0.0
+ 35MSSharedLib1024.snk
true
-
-
true
-
- 35MSSharedLib1024.snk
-
-
- False
- ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll
-
-
- False
- ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll
-
-
- ..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
-
-
- ..\..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll
-
-
- ..\..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll
-
-
- ..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll
-
-
-
-
-
-
-
-
-
-
-
- False
- ..\..\packages\xunit.1.9.2\lib\net20\xunit.dll
-
-
- ..\..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Code
-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
-
- {d2f24972-0f56-4c18-bd65-c26a320a0c68}
- Microsoft.AspNet.Identity.Core
-
-
- {d7298dad-ab04-4502-9567-0461d0ad059e}
- Microsoft.AspNet.Identity.EntityFramework
-
-
- {943170eb-f4e7-4a6d-989e-2cf6c681dd89}
- Microsoft.AspNet.Identity.Owin
-
+
+ PreserveNewest
+
-
-
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/Identity.Test/OwinContextExtensionsTest.cs b/test/Identity.Test/OwinContextExtensionsTest.cs
index dda09fe..7ef4c70 100644
--- a/test/Identity.Test/OwinContextExtensionsTest.cs
+++ b/test/Identity.Test/OwinContextExtensionsTest.cs
@@ -1,8 +1,13 @@
// Copyright (c) Microsoft Corporation, Inc. All rights reserved.
// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information.
+#if NETFRAMEWORK
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
+#else
+using Microsoft.AspNet.Identity.AspNetCore;
+using Microsoft.AspNetCore.Http;
+#endif
using Xunit;
namespace Identity.Test
@@ -12,7 +17,11 @@ public class OwinContextExtensionsTest
[Fact]
public void MiddlewareExtensionsNullCheckTest()
{
+#if NETFRAMEWORK
IOwinContext context = null;
+#else
+ HttpContext context = null;
+#endif
ExceptionHelper.ThrowsArgumentNull(() => context.Get