diff --git a/.gitmodules b/.gitmodules
index 38efb95128..f6f9db6892 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,10 +2,6 @@
path = modules/EntityFrameworkCore
url = https://github.com/aspnet/EntityFrameworkCore.git
branch = release/2.1
-[submodule "modules/Identity"]
- path = modules/Identity
- url = https://github.com/aspnet/Identity.git
- branch = release/2.1
[submodule "modules/Scaffolding"]
path = modules/Scaffolding
url = https://github.com/aspnet/Scaffolding.git
diff --git a/build/buildorder.props b/build/buildorder.props
index 8976913413..ad4b49f520 100644
--- a/build/buildorder.props
+++ b/build/buildorder.props
@@ -22,7 +22,7 @@
-
+
diff --git a/build/submodules.props b/build/submodules.props
index 1a035581ee..8e1742afd8 100644
--- a/build/submodules.props
+++ b/build/submodules.props
@@ -54,7 +54,7 @@
-
+
diff --git a/modules/Identity b/modules/Identity
deleted file mode 160000
index fa3cfd08eb..0000000000
--- a/modules/Identity
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit fa3cfd08eb6af819adc5fef2d9b603638c4b4b3b
diff --git a/src/Identity/.gitignore b/src/Identity/.gitignore
new file mode 100644
index 0000000000..22d237f27e
--- /dev/null
+++ b/src/Identity/.gitignore
@@ -0,0 +1,32 @@
+[Oo]bj/
+[Bb]in/
+TestResults/
+.nuget/
+_ReSharper.*/
+packages/
+artifacts/
+PublishProfiles/
+*.user
+*.suo
+*.cache
+*.docstates
+_ReSharper.*
+nuget.exe
+*net45.csproj
+*net451.csproj
+*k10.csproj
+*.psess
+*.vsp
+*.pidb
+*.userprefs
+*DS_Store
+*.ncrunchsolution
+*.*sdf
+*.ipch
+*.sln.ide
+project.lock.json
+.vs
+.vscode
+.build/
+.testPublish/
+global.json
diff --git a/src/Identity/Directory.Build.props b/src/Identity/Directory.Build.props
new file mode 100644
index 0000000000..230ecfc69e
--- /dev/null
+++ b/src/Identity/Directory.Build.props
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+ Microsoft ASP.NET Core
+ https://github.com/aspnet/Identity
+ git
+ $(MSBuildThisFileDirectory)
+ $(MSBuildThisFileDirectory)build\Key.snk
+ true
+ true
+
+
+
diff --git a/src/Identity/Directory.Build.targets b/src/Identity/Directory.Build.targets
new file mode 100644
index 0000000000..53b3f6e1da
--- /dev/null
+++ b/src/Identity/Directory.Build.targets
@@ -0,0 +1,7 @@
+
+
+ $(MicrosoftNETCoreApp20PackageVersion)
+ $(MicrosoftNETCoreApp21PackageVersion)
+ $(NETStandardLibrary20PackageVersion)
+
+
diff --git a/src/Identity/Identity.sln b/src/Identity/Identity.sln
new file mode 100644
index 0000000000..3beeb039f6
--- /dev/null
+++ b/src/Identity/Identity.sln
@@ -0,0 +1,482 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2027
+MinimumVisualStudioVersion = 15.0.26730.03
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0F647068-6602-4E24-B1DC-8ED91481A50A}"
+ ProjectSection(SolutionItems) = preProject
+ src\Directory.Build.props = src\Directory.Build.props
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{52D59F18-62D2-4D17-8CF2-BE192445AF8E}"
+ ProjectSection(SolutionItems) = preProject
+ test\Directory.Build.props = test\Directory.Build.props
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity", "src\Identity\Microsoft.AspNetCore.Identity.csproj", "{1729302E-A58E-4652-B639-5B6B68DA2748}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.Test", "test\Identity.Test\Microsoft.AspNetCore.Identity.Test.csproj", "{2CF3927B-19E4-4866-9BAA-2C131580E7C3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.InMemory.Test", "test\InMemory.Test\Microsoft.AspNetCore.Identity.InMemory.Test.csproj", "{65161409-C4C4-4D63-A73B-231FCFF4D503}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentitySample.Mvc", "samples\IdentitySample.Mvc\IdentitySample.Mvc.csproj", "{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test", "test\EF.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj", "{37236EA3-915D-46D5-997C-DF513C500E4B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test", "test\EF.InMemory.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj", "{EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore", "src\EF\Microsoft.AspNetCore.Identity.EntityFrameworkCore.csproj", "{4490894C-3572-4E63-86F1-EE5105CE8A06}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.AspNetCoreCompat", "src\AspNetCoreCompat\Microsoft.AspNet.Identity.AspNetCoreCompat.csproj", "{6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.Specification.Tests", "src\Specification.Tests\Microsoft.AspNetCore.Identity.Specification.Tests.csproj", "{5608E828-DD54-4E2A-B73C-FC22268BE797}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Identity.Core", "src\Core\Microsoft.Extensions.Identity.Core.csproj", "{D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Identity.Stores", "src\Stores\Microsoft.Extensions.Identity.Stores.csproj", "{FADA11FC-DC06-4832-A569-7B2374A6CD42}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{1F83D453-E094-4D28-BCFA-9E537ABB5AD6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{42F5B772-1D61-4C18-9457-412DE8E170A5}"
+ ProjectSection(SolutionItems) = preProject
+ Directory.Build.props = Directory.Build.props
+ Directory.Build.targets = Directory.Build.targets
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeWPFClient", "samples\NativeWPFClient\NativeWPFClient.csproj", "{39AA4E4D-5E62-4213-8641-BF8012D45DE4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentitySample.DefaultUI", "samples\IdentitySample.DefaultUI\IdentitySample.DefaultUI.csproj", "{ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.UI", "src\UI\Microsoft.AspNetCore.Identity.UI.csproj", "{894E102D-56D4-4B02-8F13-8781F4324C3E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.DefaultUI.WebSite", "test\WebSites\Identity.DefaultUI.WebSite\Identity.DefaultUI.WebSite.csproj", "{CAE02AD2-F941-4ACB-B469-13EFF551BB74}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.FunctionalTests", "test\Identity.FunctionalTests\Microsoft.AspNetCore.Identity.FunctionalTests.csproj", "{B3616029-7DA6-4FB3-8722-D5AC69884B3F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ DebugNoWPF|Any CPU = DebugNoWPF|Any CPU
+ DebugNoWPF|x64 = DebugNoWPF|x64
+ DebugNoWPF|x86 = DebugNoWPF|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ ReleaseNoWPF|Any CPU = ReleaseNoWPF|Any CPU
+ ReleaseNoWPF|x64 = ReleaseNoWPF|x64
+ ReleaseNoWPF|x86 = ReleaseNoWPF|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|x64.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|x86.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|x64.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|x64.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|x86.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|x86.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|x64.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|x86.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|x64.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|x64.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|x86.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|x86.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|x64.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|x86.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|Any CPU.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|x64.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|x64.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|x86.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|x86.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|x64.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|x86.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x64.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x64.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x86.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x86.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|x64.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|x86.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|x64.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|x64.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|x86.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|x86.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|x64.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|x86.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|x64.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|x64.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|x86.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|x86.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|x64.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|x86.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x64.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x64.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x86.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x86.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x64.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x86.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x64.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x64.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x86.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x86.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x64.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x86.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x64.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x64.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x86.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x86.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x64.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x86.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x64.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x64.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x86.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x86.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x64.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x86.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x64.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x64.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x86.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x86.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Debug|x64.Build.0 = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Debug|x86.Build.0 = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Release|x64.ActiveCfg = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Release|x64.Build.0 = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Release|x86.ActiveCfg = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.Release|x86.Build.0 = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Debug|x64.Build.0 = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Debug|x86.Build.0 = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Release|x64.ActiveCfg = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Release|x64.Build.0 = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Release|x86.ActiveCfg = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.Release|x86.Build.0 = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Debug|x64.Build.0 = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Debug|x86.Build.0 = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Release|x64.ActiveCfg = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Release|x64.Build.0 = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Release|x86.ActiveCfg = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.Release|x86.Build.0 = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.ReleaseNoWPF|x64.ActiveCfg = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.ReleaseNoWPF|x64.Build.0 = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.ReleaseNoWPF|x86.ActiveCfg = Release|Any CPU
+ {894E102D-56D4-4B02-8F13-8781F4324C3E}.ReleaseNoWPF|x86.Build.0 = Release|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Debug|x64.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Debug|x86.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Release|x64.ActiveCfg = Release|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Release|x64.Build.0 = Release|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Release|x86.ActiveCfg = Release|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.Release|x86.Build.0 = Release|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.ReleaseNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.ReleaseNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.ReleaseNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.ReleaseNoWPF|x64.Build.0 = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.ReleaseNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74}.ReleaseNoWPF|x86.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Debug|x64.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Debug|x86.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.DebugNoWPF|Any CPU.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.DebugNoWPF|Any CPU.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.DebugNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.DebugNoWPF|x64.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.DebugNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.DebugNoWPF|x86.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Release|x64.ActiveCfg = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Release|x64.Build.0 = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Release|x86.ActiveCfg = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.Release|x86.Build.0 = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.ReleaseNoWPF|Any CPU.ActiveCfg = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.ReleaseNoWPF|Any CPU.Build.0 = Release|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.ReleaseNoWPF|x64.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.ReleaseNoWPF|x64.Build.0 = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.ReleaseNoWPF|x86.ActiveCfg = Debug|Any CPU
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F}.ReleaseNoWPF|x86.Build.0 = Debug|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {1729302E-A58E-4652-B639-5B6B68DA2748} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {65161409-C4C4-4D63-A73B-231FCFF4D503} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6} = {58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}
+ {37236EA3-915D-46D5-997C-DF513C500E4B} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {4490894C-3572-4E63-86F1-EE5105CE8A06} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {5608E828-DD54-4E2A-B73C-FC22268BE797} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {1F83D453-E094-4D28-BCFA-9E537ABB5AD6} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {39AA4E4D-5E62-4213-8641-BF8012D45DE4} = {58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}
+ {ACC75F4F-EA7D-49E0-A64C-9D4A3DFD5B8A} = {58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}
+ {894E102D-56D4-4B02-8F13-8781F4324C3E} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {CAE02AD2-F941-4ACB-B469-13EFF551BB74} = {1F83D453-E094-4D28-BCFA-9E537ABB5AD6}
+ {B3616029-7DA6-4FB3-8722-D5AC69884B3F} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B3F2A592-CCE0-40C2-8CA4-7B1293DED874}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Identity/IdentityCore.sln b/src/Identity/IdentityCore.sln
new file mode 100644
index 0000000000..3971ae00b5
--- /dev/null
+++ b/src/Identity/IdentityCore.sln
@@ -0,0 +1,319 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.10
+MinimumVisualStudioVersion = 15.0.26730.03
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0F647068-6602-4E24-B1DC-8ED91481A50A}"
+ ProjectSection(SolutionItems) = preProject
+ src\Directory.Build.props = src\Directory.Build.props
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{52D59F18-62D2-4D17-8CF2-BE192445AF8E}"
+ ProjectSection(SolutionItems) = preProject
+ test\Directory.Build.props = test\Directory.Build.props
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity", "src\Identity\Microsoft.AspNetCore.Identity.csproj", "{1729302E-A58E-4652-B639-5B6B68DA2748}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.Test", "test\Identity.Test\Microsoft.AspNetCore.Identity.Test.csproj", "{2CF3927B-19E4-4866-9BAA-2C131580E7C3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.InMemory.Test", "test\InMemory.Test\Microsoft.AspNetCore.Identity.InMemory.Test.csproj", "{65161409-C4C4-4D63-A73B-231FCFF4D503}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentitySample.Mvc", "samples\IdentitySample.Mvc\IdentitySample.Mvc.csproj", "{E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test", "test\EF.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.Test.csproj", "{37236EA3-915D-46D5-997C-DF513C500E4B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test", "test\EF.InMemory.Test\Microsoft.AspNetCore.Identity.EntityFrameworkCore.InMemory.Test.csproj", "{EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.EntityFrameworkCore", "src\EF\Microsoft.AspNetCore.Identity.EntityFrameworkCore.csproj", "{4490894C-3572-4E63-86F1-EE5105CE8A06}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.AspNetCoreCompat", "src\AspNetCoreCompat\Microsoft.AspNet.Identity.AspNetCoreCompat.csproj", "{6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.Specification.Tests", "src\Specification.Tests\Microsoft.AspNetCore.Identity.Specification.Tests.csproj", "{5608E828-DD54-4E2A-B73C-FC22268BE797}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Identity.Core", "src\Core\Microsoft.Extensions.Identity.Core.csproj", "{D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Identity.Stores", "src\Stores\Microsoft.Extensions.Identity.Stores.csproj", "{FADA11FC-DC06-4832-A569-7B2374A6CD42}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2C657F6C-D8AD-4833-9C59-2301A16957BD}"
+ ProjectSection(SolutionItems) = preProject
+ Directory.Build.props = Directory.Build.props
+ Directory.Build.targets = Directory.Build.targets
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentitySample.DefaultUI", "samples\IdentitySample.DefaultUI\IdentitySample.DefaultUI.csproj", "{D5FB2E24-4C71-430C-A289-59C8D59164B0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.UI", "src\UI\Microsoft.AspNetCore.Identity.UI.csproj", "{1FB3E9BB-E20A-4807-A4C3-F86A341304DB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Identity.FunctionalTests", "test\Identity.FunctionalTests\Microsoft.AspNetCore.Identity.FunctionalTests.csproj", "{BAC36757-9A47-43CB-A6F3-86E8C4650A28}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{C47C1165-9F19-4DF8-ABA9-707ACEB3BDC7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.DefaultUI.WebSite", "test\WebSites\Identity.DefaultUI.WebSite\Identity.DefaultUI.WebSite.csproj", "{EA424B4D-0BE1-49AC-A106-CC6CC808A104}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|x64.Build.0 = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|x64.ActiveCfg = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|x64.Build.0 = Release|Any CPU
+ {1729302E-A58E-4652-B639-5B6B68DA2748}.Release|x86.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|x64.Build.0 = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|x64.ActiveCfg = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|x64.Build.0 = Release|Any CPU
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3}.Release|x86.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|x64.Build.0 = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|Any CPU.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|x64.ActiveCfg = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|x64.Build.0 = Release|Any CPU
+ {65161409-C4C4-4D63-A73B-231FCFF4D503}.Release|x86.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|x64.Build.0 = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x64.ActiveCfg = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x64.Build.0 = Release|Any CPU
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6}.Release|x86.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|x64.Build.0 = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|x64.ActiveCfg = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|x64.Build.0 = Release|Any CPU
+ {37236EA3-915D-46D5-997C-DF513C500E4B}.Release|x86.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|x64.Build.0 = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|x64.ActiveCfg = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|x64.Build.0 = Release|Any CPU
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD}.Release|x86.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|x64.Build.0 = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x64.ActiveCfg = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x64.Build.0 = Release|Any CPU
+ {4490894C-3572-4E63-86F1-EE5105CE8A06}.Release|x86.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x64.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Debug|x86.Build.0 = Debug|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x64.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x64.Build.0 = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x86.ActiveCfg = Release|Any CPU
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475}.Release|x86.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x64.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Debug|x86.Build.0 = Debug|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x64.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x64.Build.0 = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x86.ActiveCfg = Release|Any CPU
+ {5608E828-DD54-4E2A-B73C-FC22268BE797}.Release|x86.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x64.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Debug|x86.Build.0 = Debug|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x64.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x64.Build.0 = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x86.ActiveCfg = Release|Any CPU
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8}.Release|x86.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x64.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Debug|x86.Build.0 = Debug|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x64.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x64.Build.0 = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x86.ActiveCfg = Release|Any CPU
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42}.Release|x86.Build.0 = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|x64.Build.0 = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Debug|x86.Build.0 = Debug|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|x64.ActiveCfg = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|x64.Build.0 = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|x86.ActiveCfg = Release|Any CPU
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0}.Release|x86.Build.0 = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|x64.Build.0 = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Debug|x86.Build.0 = Debug|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|x64.ActiveCfg = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|x64.Build.0 = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|x86.ActiveCfg = Release|Any CPU
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB}.Release|x86.Build.0 = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|x64.Build.0 = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Debug|x86.Build.0 = Debug|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|x64.ActiveCfg = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|x64.Build.0 = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|x86.ActiveCfg = Release|Any CPU
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28}.Release|x86.Build.0 = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|x64.Build.0 = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Debug|x86.Build.0 = Debug|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|x64.ActiveCfg = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|x64.Build.0 = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|x86.ActiveCfg = Release|Any CPU
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {1729302E-A58E-4652-B639-5B6B68DA2748} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {2CF3927B-19E4-4866-9BAA-2C131580E7C3} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {65161409-C4C4-4D63-A73B-231FCFF4D503} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {E1BFA023-CFFD-49CE-8466-1C28DD2EC1F6} = {58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}
+ {37236EA3-915D-46D5-997C-DF513C500E4B} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {EA7EB28F-53B8-4009-9C6B-74DB090CA8DD} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {4490894C-3572-4E63-86F1-EE5105CE8A06} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {6A74C6EA-B241-4D6B-BCE4-BF89EC1D2475} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {5608E828-DD54-4E2A-B73C-FC22268BE797} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {D5905D78-A32E-44B8-8F21-EDAEDC95D9B8} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {FADA11FC-DC06-4832-A569-7B2374A6CD42} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {D5FB2E24-4C71-430C-A289-59C8D59164B0} = {58D94A0E-C2B7-43A7-8826-99ECBB1E0A50}
+ {1FB3E9BB-E20A-4807-A4C3-F86A341304DB} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
+ {BAC36757-9A47-43CB-A6F3-86E8C4650A28} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {C47C1165-9F19-4DF8-ABA9-707ACEB3BDC7} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
+ {EA424B4D-0BE1-49AC-A106-CC6CC808A104} = {C47C1165-9F19-4DF8-ABA9-707ACEB3BDC7}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {21D598B0-2383-4B22-826D-E7FB4921BD66}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Identity/NuGetPackageVerifier.json b/src/Identity/NuGetPackageVerifier.json
new file mode 100644
index 0000000000..df04266b02
--- /dev/null
+++ b/src/Identity/NuGetPackageVerifier.json
@@ -0,0 +1,17 @@
+{
+ "Default": {
+ "rules": [
+ "DefaultCompositeRule"
+ ],
+ "packages": {
+ "Microsoft.AspNetCore.Identity.UI": {
+ "Exclusions": {
+ "DOC_MISSING": {
+ "lib/netstandard2.0/Microsoft.AspNetCore.Identity.UI.dll": "This is a library with packaged UI",
+ "lib/netstandard2.0/Microsoft.AspNetCore.Identity.UI.Views.dll": "This assembly is generated and contains precompiled razor pages"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/Identity/README.md b/src/Identity/README.md
new file mode 100644
index 0000000000..4e4f345af9
--- /dev/null
+++ b/src/Identity/README.md
@@ -0,0 +1,30 @@
+ASP.NET Core Identity
+===
+
+AppVeyor: [](https://ci.appveyor.com/project/aspnetci/Identity/branch/dev)
+
+Travis: [](https://travis-ci.org/aspnet/Identity)
+
+ASP.NET Core Identity is the membership system for building ASP.NET Core web applications, including membership, login, and user data. ASP.NET Core Identity allows you to add login features to your application and makes it easy to customize data about the logged in user.
+
+This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo.
+
+## ASP.NET Identity for ASP.NET MVC 5
+
+The previous versions of Identity for MVC5 and lower, previously available on CodePlex, are available at https://github.com/aspnet/AspNetIdentity
+
+## Community Maintained Store Providers
+
+**IMPORTANT: Extensions are built by a variety of sources and not maintained as part of the ASP.NET Identity project. When considering a third party provider, be sure to evaluate quality, licensing, compatibility, support, etc. to ensure they meet your requirements.**
+
+* ASP.NET Identity MongoDB Providers:
+ * [By Tugberk Ugurlu](https://github.com/tugberkugurlu/AspNetCore.Identity.MongoDB)
+ * [By Alexandre Spieser](https://github.com/alexandre-spieser/AspNetCore.Identity.MongoDbCore)
+ * [ASP.NET Identity LinqToDB Provider](https://github.com/ili/LinqToDB.Identity)
+ * [ASP.NET Identity DynamoDB Provider](https://github.com/miltador/AspNetCore.Identity.DynamoDB)
+ * ASP.NET Identity RavenDB Providers:
+ * [By Judah Gabriel Himango](https://github.com/JudahGabriel/RavenDB.Identity)
+ * [By Iskandar Rafiev](https://github.com/maqduni/AspNetCore.Identity.RavenDB)
+ * [ASP.NET Identity Cassandra Provider](https://github.com/lkubis/AspNetCore.Identity.Cassandra)
+ * [ASP.NET Identity Firebase Provider](https://github.com/aguacongas/Identity.Firebase)
+ * [ASP.NET Identity Redis Provider](https://github.com/aguacongas/Identity.Redis)
diff --git a/src/Identity/build/Key.snk b/src/Identity/build/Key.snk
new file mode 100644
index 0000000000..e10e4889c1
Binary files /dev/null and b/src/Identity/build/Key.snk differ
diff --git a/src/Identity/build/dependencies.props b/src/Identity/build/dependencies.props
new file mode 100644
index 0000000000..21e3cb41e5
--- /dev/null
+++ b/src/Identity/build/dependencies.props
@@ -0,0 +1,81 @@
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+
+
+
+
+ 0.9.9
+ 2.1.3-rtm-15831
+ 2.2.1
+ 2.0.0
+ 2.1.5
+ 15.6.1
+ 3.0.1
+ 4.7.49
+ 2.0.3
+ 4.5.0
+ 0.8.0
+ 2.3.1
+ 2.4.0
+
+
+
+
+
+
+
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.2
+ 2.1.2
+ 2.1.1
+ 2.1.1
+ 2.1.0
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+ 2.1.1
+
+
diff --git a/src/Identity/build/repo.props b/src/Identity/build/repo.props
new file mode 100644
index 0000000000..b4c0d5f738
--- /dev/null
+++ b/src/Identity/build/repo.props
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+ Internal.AspNetCore.Universe.Lineup
+ 2.1.0-rc1-*
+ https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json
+
+
+
+
+
+
+
diff --git a/src/Identity/build/repo.targets b/src/Identity/build/repo.targets
new file mode 100644
index 0000000000..867ea2537a
--- /dev/null
+++ b/src/Identity/build/repo.targets
@@ -0,0 +1,8 @@
+
+
+
+
+ Configuration=$(Configuration)NoWPF
+
+
+
diff --git a/src/Identity/build/sources.props b/src/Identity/build/sources.props
new file mode 100644
index 0000000000..9215df9751
--- /dev/null
+++ b/src/Identity/build/sources.props
@@ -0,0 +1,17 @@
+
+
+
+
+ $(DotNetRestoreSources)
+
+ $(RestoreSources);
+ https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
+ https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
+ https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
+
+
+ $(RestoreSources);
+ https://api.nuget.org/v3/index.json;
+
+
+
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml
new file mode 100644
index 0000000000..3f15aaca23
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml
@@ -0,0 +1,53 @@
+@page
+@model IndexModel
+@{
+ ViewData["Title"] = "Profile";
+}
+
+
@ViewData["Title"]
+@Html.Partial("_StatusMessage", Model.StatusMessage)
+
+
+@section Scripts {
+
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs
new file mode 100644
index 0000000000..23303774f0
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs
@@ -0,0 +1,165 @@
+// Copyright (c) .NET Foundation. 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.ComponentModel.DataAnnotations;
+using System.Text.Encodings.Web;
+using System.Threading.Tasks;
+using IdentitySample.DefaultUI.Data;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.UI.Services;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+
+namespace IdentitySample.DefaultUI
+{
+ public class IndexModel : PageModel
+ {
+ private readonly UserManager _userManager;
+ private readonly SignInManager _signInManager;
+ private readonly IEmailSender _emailSender;
+
+ public IndexModel(
+ UserManager userManager,
+ SignInManager signInManager,
+ IEmailSender emailSender)
+ {
+ _userManager = userManager;
+ _signInManager = signInManager;
+ _emailSender = emailSender;
+ }
+
+ public string Username { get; set; }
+
+ public bool IsEmailConfirmed { get; set; }
+
+ [TempData]
+ public string StatusMessage { get; set; }
+
+ [BindProperty]
+ public InputModel Input { get; set; }
+
+ public class InputModel
+ {
+ [Required]
+ [EmailAddress]
+ public string Email { get; set; }
+
+ [Phone]
+ [Display(Name = "Phone number")]
+ public string PhoneNumber { get; set; }
+
+ [Required]
+ [DataType(DataType.Text)]
+ [Display(Name = "Full Name")]
+ public string Name { get; set; }
+
+ [Required]
+ [Range(0, 199, ErrorMessage = "Age must be between 0 and 199")]
+ [Display(Name = "Age")]
+ public int Age { get; set; }
+ }
+
+ public async Task OnGetAsync()
+ {
+ var user = await _userManager.GetUserAsync(User);
+ if (user == null)
+ {
+ return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+ }
+
+ Username = user.UserName;
+ Input = new InputModel
+ {
+ Name = user.Name,
+ Age = user.Age,
+ Email = user.Email,
+ PhoneNumber = user.PhoneNumber
+ };
+
+ IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
+
+ return Page();
+ }
+
+ public async Task OnPostAsync()
+ {
+ if (!ModelState.IsValid)
+ {
+ return Page();
+ }
+
+ var user = await _userManager.GetUserAsync(User);
+ if (user == null)
+ {
+ return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+ }
+
+ if (Input.Name != user.Name)
+ {
+ user.Name = Input.Name;
+ }
+
+ if (Input.Age != user.Age)
+ {
+ user.Age = Input.Age;
+ }
+
+ var updateProfileResult = await _userManager.UpdateAsync(user);
+ if (!updateProfileResult.Succeeded)
+ {
+ throw new InvalidOperationException($"Unexpected error ocurred updating the profile for user with ID '{user.Id}'");
+ }
+
+ if (Input.Email != user.Email)
+ {
+ var setEmailResult = await _userManager.SetEmailAsync(user, Input.Email);
+ if (!setEmailResult.Succeeded)
+ {
+ throw new InvalidOperationException($"Unexpected error occurred setting email for user with ID '{user.Id}'.");
+ }
+ }
+
+ if (Input.PhoneNumber != user.PhoneNumber)
+ {
+ var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
+ if (!setPhoneResult.Succeeded)
+ {
+ throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{user.Id}'.");
+ }
+ }
+
+ await _signInManager.RefreshSignInAsync(user);
+ StatusMessage = "Your profile has been updated";
+ return RedirectToPage();
+ }
+
+ public async Task OnPostSendVerificationEmailAsync()
+ {
+ if (!ModelState.IsValid)
+ {
+ return Page();
+ }
+
+ var user = await _userManager.GetUserAsync(User);
+ if (user == null)
+ {
+ return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+ }
+
+ var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
+ var callbackUrl = Url.Page(
+ "/Account/ConfirmEmail",
+ pageHandler: null,
+ values: new { user.Id, code },
+ protocol: Request.Scheme);
+ await _emailSender.SendEmailAsync(
+ user.Email,
+ "Confirm your email",
+ $"Please confirm your account by clicking here .");
+
+ StatusMessage = "Verification email sent. Please check your email.";
+ return RedirectToPage();
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml
new file mode 100644
index 0000000000..259373e966
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml
@@ -0,0 +1,47 @@
+@page
+@model RegisterModel
+@{
+ ViewData["Title"] = "Register";
+}
+
+@ViewData["Title"]
+
+
+
+@section Scripts {
+
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml.cs b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml.cs
new file mode 100644
index 0000000000..35cb402bb8
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml.cs
@@ -0,0 +1,115 @@
+// Copyright (c) .NET Foundation. 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.ComponentModel.DataAnnotations;
+using System.Text.Encodings.Web;
+using System.Threading.Tasks;
+using IdentitySample.DefaultUI.Data;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.UI.Services;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.Extensions.Logging;
+
+namespace IdentitySample.DefaultUI
+{
+ public class RegisterModel : PageModel
+ {
+ private readonly SignInManager _signInManager;
+ private readonly UserManager _userManager;
+ private readonly ILogger _logger;
+ private readonly IEmailSender _emailSender;
+
+ public RegisterModel(
+ UserManager userManager,
+ SignInManager signInManager,
+ ILogger logger,
+ IEmailSender emailSender)
+ {
+ _userManager = userManager;
+ _signInManager = signInManager;
+ _logger = logger;
+ _emailSender = emailSender;
+ }
+
+ [BindProperty]
+ public InputModel Input { get; set; }
+
+ public string ReturnUrl { get; set; }
+
+ public class InputModel
+ {
+ [Required]
+ [EmailAddress]
+ [Display(Name = "Email")]
+ public string Email { get; set; }
+
+ [Required]
+ [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
+ [DataType(DataType.Password)]
+ [Display(Name = "Password")]
+ public string Password { get; set; }
+
+ [DataType(DataType.Password)]
+ [Display(Name = "Confirm password")]
+ [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
+ public string ConfirmPassword { get; set; }
+
+ [Required]
+ [DataType(DataType.Text)]
+ [Display(Name = "Full name")]
+ public string Name { get; set; }
+
+ [Required]
+ [Range(0,199, ErrorMessage = "Age must be between 0 and 199 years")]
+ [Display(Name = "Age")]
+ public int Age { get; set; }
+ }
+
+ public void OnGet(string returnUrl = null)
+ {
+ ReturnUrl = returnUrl;
+ }
+
+ public async Task OnPostAsync(string returnUrl = null)
+ {
+ returnUrl = returnUrl ?? Url.Content("~/");
+ if (ModelState.IsValid)
+ {
+ var user = new ApplicationUser {
+ UserName = Input.Email,
+ Email = Input.Email,
+ Name = Input.Name,
+ Age = Input.Age
+ };
+
+ var result = await _userManager.CreateAsync(user, Input.Password);
+ if (result.Succeeded)
+ {
+ _logger.LogInformation("User created a new account with password.");
+
+ var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
+ var callbackUrl = Url.Page(
+ "/Account/ConfirmEmail",
+ pageHandler: null,
+ values: new { userId = user.Id, code = code },
+ protocol: Request.Scheme);
+
+ await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
+ $"Please confirm your account by clicking here .");
+
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ return LocalRedirect(returnUrl);
+ }
+ foreach (var error in result.Errors)
+ {
+ ModelState.AddModelError(string.Empty, error.Description);
+ }
+ }
+
+ // If we got this far, something failed, redisplay form
+ return Page();
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/_ViewImports.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/_ViewImports.cshtml
new file mode 100644
index 0000000000..777abd9e19
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/_ViewImports.cshtml
@@ -0,0 +1,2 @@
+@namespace IdentitySample.DefaultUI
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/_ViewStart.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/_ViewStart.cshtml
new file mode 100644
index 0000000000..c4284f6c20
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "/Views/Shared/_Layout.cshtml";
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Controllers/HomeController.cs b/src/Identity/samples/IdentitySample.DefaultUI/Controllers/HomeController.cs
new file mode 100644
index 0000000000..d0883b03d3
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Controllers/HomeController.cs
@@ -0,0 +1,13 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace IdentitySample.DefaultUI.Controllers
+{
+ public class HomeController : Controller
+ {
+ [HttpGet]
+ public IActionResult Index()
+ {
+ return View();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Data/ApplicationDbContext.cs b/src/Identity/samples/IdentitySample.DefaultUI/Data/ApplicationDbContext.cs
new file mode 100644
index 0000000000..1e96af6bee
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Data/ApplicationDbContext.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+
+namespace IdentitySample.DefaultUI.Data
+{
+ public class ApplicationDbContext : IdentityDbContext
+ {
+ public ApplicationDbContext(DbContextOptions options) : base(options)
+ {
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Data/ApplicationUser.cs b/src/Identity/samples/IdentitySample.DefaultUI/Data/ApplicationUser.cs
new file mode 100644
index 0000000000..cba3ed5f40
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Data/ApplicationUser.cs
@@ -0,0 +1,12 @@
+using Microsoft.AspNetCore.Identity;
+
+namespace IdentitySample.DefaultUI.Data
+{
+ public class ApplicationUser : IdentityUser
+ {
+ [ProtectedPersonalData]
+ public string Name { get; set; }
+ [PersonalData]
+ public int Age { get; set; }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/20180126174859_CreateIdentitySchema.Designer.cs b/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/20180126174859_CreateIdentitySchema.Designer.cs
new file mode 100644
index 0000000000..acee5cb362
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/20180126174859_CreateIdentitySchema.Designer.cs
@@ -0,0 +1,239 @@
+//
+using System;
+using IdentitySample.DefaultUI.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Storage.Internal;
+
+namespace IdentitySample.DefaultUI.Data.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20180126174859_CreateIdentitySchema")]
+ partial class CreateIdentitySchema
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "2.1.0-preview1-28153")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("IdentitySample.DefaultUI.Data.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AccessFailedCount");
+
+ b.Property("Age");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Email")
+ .HasMaxLength(256);
+
+ b.Property("EmailConfirmed");
+
+ b.Property("LockoutEnabled");
+
+ b.Property("LockoutEnd");
+
+ b.Property("Name");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256);
+
+ b.Property("PasswordHash");
+
+ b.Property("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed");
+
+ b.Property("SecurityStamp");
+
+ b.Property("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasName("UserNameIndex")
+ .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasName("RoleNameIndex")
+ .HasFilter("[NormalizedName] IS NOT NULL");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasMaxLength(128);
+
+ b.Property("ProviderKey")
+ .HasMaxLength(128);
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(128);
+
+ b.Property("Name")
+ .HasMaxLength(128);
+
+ b.Property("Value");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/20180126174859_CreateIdentitySchema.cs b/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/20180126174859_CreateIdentitySchema.cs
new file mode 100644
index 0000000000..713e581f6d
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/20180126174859_CreateIdentitySchema.cs
@@ -0,0 +1,223 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace IdentitySample.DefaultUI.Data.Migrations
+{
+ public partial class CreateIdentitySchema : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "AspNetRoles",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ Name = table.Column(maxLength: 256, nullable: true),
+ NormalizedName = table.Column(maxLength: 256, nullable: true),
+ ConcurrencyStamp = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoles", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUsers",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ UserName = table.Column(maxLength: 256, nullable: true),
+ NormalizedUserName = table.Column(maxLength: 256, nullable: true),
+ Email = table.Column(maxLength: 256, nullable: true),
+ NormalizedEmail = table.Column(maxLength: 256, nullable: true),
+ EmailConfirmed = table.Column(nullable: false),
+ PasswordHash = table.Column(nullable: true),
+ SecurityStamp = table.Column(nullable: true),
+ ConcurrencyStamp = table.Column(nullable: true),
+ PhoneNumber = table.Column(nullable: true),
+ PhoneNumberConfirmed = table.Column(nullable: false),
+ TwoFactorEnabled = table.Column(nullable: false),
+ LockoutEnd = table.Column(nullable: true),
+ LockoutEnabled = table.Column(nullable: false),
+ AccessFailedCount = table.Column(nullable: false),
+ Name = table.Column(nullable: true),
+ Age = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUsers", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetRoleClaims",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
+ RoleId = table.Column(nullable: false),
+ ClaimType = table.Column(nullable: true),
+ ClaimValue = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "AspNetRoles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserClaims",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
+ UserId = table.Column(nullable: false),
+ ClaimType = table.Column(nullable: true),
+ ClaimValue = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AspNetUserClaims_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserLogins",
+ columns: table => new
+ {
+ LoginProvider = table.Column(maxLength: 128, nullable: false),
+ ProviderKey = table.Column(maxLength: 128, nullable: false),
+ ProviderDisplayName = table.Column(nullable: true),
+ UserId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
+ table.ForeignKey(
+ name: "FK_AspNetUserLogins_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserRoles",
+ columns: table => new
+ {
+ UserId = table.Column(nullable: false),
+ RoleId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
+ table.ForeignKey(
+ name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "AspNetRoles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_AspNetUserRoles_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserTokens",
+ columns: table => new
+ {
+ UserId = table.Column(nullable: false),
+ LoginProvider = table.Column(maxLength: 128, nullable: false),
+ Name = table.Column(maxLength: 128, nullable: false),
+ Value = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
+ table.ForeignKey(
+ name: "FK_AspNetUserTokens_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetRoleClaims_RoleId",
+ table: "AspNetRoleClaims",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "RoleNameIndex",
+ table: "AspNetRoles",
+ column: "NormalizedName",
+ unique: true,
+ filter: "[NormalizedName] IS NOT NULL");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserClaims_UserId",
+ table: "AspNetUserClaims",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserLogins_UserId",
+ table: "AspNetUserLogins",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserRoles_RoleId",
+ table: "AspNetUserRoles",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "EmailIndex",
+ table: "AspNetUsers",
+ column: "NormalizedEmail");
+
+ migrationBuilder.CreateIndex(
+ name: "UserNameIndex",
+ table: "AspNetUsers",
+ column: "NormalizedUserName",
+ unique: true,
+ filter: "[NormalizedUserName] IS NOT NULL");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "AspNetRoleClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserLogins");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserRoles");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserTokens");
+
+ migrationBuilder.DropTable(
+ name: "AspNetRoles");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUsers");
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/ApplicationDbContextModelSnapshot.cs
new file mode 100644
index 0000000000..8eb1302cd7
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Data/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -0,0 +1,238 @@
+//
+using System;
+using IdentitySample.DefaultUI.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage;
+using Microsoft.EntityFrameworkCore.Storage.Internal;
+
+namespace IdentitySample.DefaultUI.Data.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ partial class ApplicationDbContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "2.1.0-preview1-28153")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("IdentitySample.DefaultUI.Data.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AccessFailedCount");
+
+ b.Property("Age");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Email")
+ .HasMaxLength(256);
+
+ b.Property("EmailConfirmed");
+
+ b.Property("LockoutEnabled");
+
+ b.Property("LockoutEnd");
+
+ b.Property("Name");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256);
+
+ b.Property("PasswordHash");
+
+ b.Property("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed");
+
+ b.Property("SecurityStamp");
+
+ b.Property("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasName("UserNameIndex")
+ .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasName("RoleNameIndex")
+ .HasFilter("[NormalizedName] IS NOT NULL");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasMaxLength(128);
+
+ b.Property("ProviderKey")
+ .HasMaxLength(128);
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(128);
+
+ b.Property("Name")
+ .HasMaxLength(128);
+
+ b.Property("Value");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("IdentitySample.DefaultUI.Data.ApplicationUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/IdentitySample.DefaultUI.csproj b/src/Identity/samples/IdentitySample.DefaultUI/IdentitySample.DefaultUI.csproj
new file mode 100644
index 0000000000..43b55a62d9
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/IdentitySample.DefaultUI.csproj
@@ -0,0 +1,35 @@
+
+
+
+ Identity sample MVC application on ASP.NET Core using the default UI
+ netcoreapp2.1;net461
+ aspnetcore-2ff9bc27-5e8c-4484-90ca-e3aace89b72a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Program.cs b/src/Identity/samples/IdentitySample.DefaultUI/Program.cs
new file mode 100644
index 0000000000..6a8f2a7048
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Program.cs
@@ -0,0 +1,23 @@
+using System.IO;
+using Microsoft.AspNetCore.Hosting;
+
+namespace IdentitySample.DefaultUI
+{
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ var host = CreateWebHostBuilder(args)
+ .Build();
+
+ host.Run();
+ }
+
+ public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
+ new WebHostBuilder()
+ .UseKestrel()
+ .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseIISIntegration()
+ .UseStartup();
+ }
+}
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Properties/launchSettings.json b/src/Identity/samples/IdentitySample.DefaultUI/Properties/launchSettings.json
new file mode 100644
index 0000000000..cef8aeebde
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Properties/launchSettings.json
@@ -0,0 +1,25 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:28248/",
+ "sslPort": 0
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "web": {
+ "commandName": "web",
+ "environmentVariables": {
+ "ASPNET_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Startup.cs b/src/Identity/samples/IdentitySample.DefaultUI/Startup.cs
new file mode 100644
index 0000000000..76962038f4
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Startup.cs
@@ -0,0 +1,68 @@
+using IdentitySample.DefaultUI.Data;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace IdentitySample.DefaultUI
+{
+ public class Startup
+ {
+ public Startup(IHostingEnvironment env)
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(env.ContentRootPath)
+ .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
+ .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
+
+ builder.AddEnvironmentVariables();
+ Configuration = builder.Build();
+ }
+
+ public IConfigurationRoot Configuration { get; set; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ // Add framework services.
+ services.AddDbContext(
+ options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
+ x => x.MigrationsAssembly("IdentitySample.DefaultUI")));
+
+ services.AddMvc();
+
+ services.AddDefaultIdentity()
+ .AddRoles()
+ .AddEntityFrameworkStores();
+ }
+
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ app.UseDatabaseErrorPage();
+ }
+ else
+ {
+ app.UseExceptionHandler("/Home/Error");
+ }
+
+ app.UseStaticFiles();
+
+ app.UseAuthentication();
+
+ app.UseMvc(routes =>
+ {
+ routes.MapRoute(
+ name: "default",
+ template: "{controller=Home}/{action=Index}/{id?}");
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Views/Home/Index.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Views/Home/Index.cshtml
new file mode 100644
index 0000000000..59dc45d93a
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Views/Home/Index.cshtml
@@ -0,0 +1,233 @@
+@{
+ Layout = "/Views/Shared/_Layout.cshtml";
+ ViewBag.Title = "Home Page";
+}
+
+
+
ASP.NET Identity
+
ASP.NET Identity is the membership system for ASP.NET apps. Following are the features of ASP.NET Identity in this sample application.
+
Learn more »
+
+
+
+
+
+ Initialize ASP.NET Identity
+
+ You can initialize ASP.NET Identity when the application starts. Since ASP.NET Identity is Entity Framework based in this sample,
+ you can create DatabaseInitializer which is configured to get called each time the app starts.
+ Please look in App_Start\IdentityConfig.cs
+ This code shows the following
+
+ When should the Initializer run and when should the database be created
+ Create Admin user
+ Create Admin role
+ Add Admin user to Admin role
+
+
+
+
+
+
+ Add profile data for the user
+
+ Please follow this tutorial.
+
+
+ Add profile information in the Users Table
+ Look in Models\IdentityModels.cs for examples
+
+
+
+
+
+
+ Validation
+
+ When you create a User using a username or password, the Identity system performs validation on the username and password, and the passwords are hashed before they are
+ stored in the database. You can customize the validation by changing some of the properties of the validators such as Turn alphanumeric on/off, set minimum password length
+ or you can write your own custom validators and register them with the UserManager.
+
+
+
+
+
+ Register a user and login
+
+ Click @Html.ActionLink("Register", "Register", "Account") and see the code in AccountController.cs and Register Action.
+ Click @Html.ActionLink("Log in", "Login", "Account") and see the code in AccountController.cs and Login Action.
+
+
+
+
+
+ Social Logins
+
+ You can the support so that users can login using their Facebook, Google, Twitter, Microsoft Account and more.
+
+
+
+
+
+
+
+
+ Basic User Management
+
+ Do Create, Update, List and Delete Users.
+ Assign a Role to a User.
+ Only Users In Role Admin can access this page. This uses the [Authorize(Roles = "Admin")] on the UserAdmin controller.
+
+
+
+
+
+ Basic Role Management
+
+ Do Create, Update, List and Delete Roles.
+ Only Users In Role Admin can access this page. This authorization is done by using the [Authorize(Roles = "Admin")] on the RolesAdmin controller.
+
+
+
+
+
+ Account Confirmation
+
+ When you register a new account, you will be sent an email confirmation.
+ You can use an email service such as SendGrid which integrates nicely with Windows Azure and requires no configuration or
+ set up an SMTP server to send email.
+ You can send email using the EmailService which is registered in App_Start\IdentityConfig.cs
+
+
+
+
+
+ Two-Factor Authentication
+
+ This sample shows how you can use Two-Factor authentication. This sample has a SMS and email service registered where you can send SMS or email for sending the security code.
+ You can add more two-factor authentication factors such as QR codes and plug them into ASP.NET Identity.
+
+
+ You can use a SMS using Twilio or use any means of sending SMS. Please read for more details on using Twilio.
+ You can send SMS using the SmsService which is registered in App_Start\IdentityConfig.cs
+
+
+ You can use an email service such as SendGrid or
+ set up an SMTP server to send email.
+ You can send email using the EmailService which is registered in App_Start\IdentityConfig.cs
+
+
+
+ When you login, you can add a phone number by clicking the Manage page.
+
+
+ Once you add a phone number and have the Phone service hooked to send a SMS, you will get a code through SMS to confirm your phone number.
+
+
+ In the Manage page, you can turn on Two-Factor authentication.
+
+
+ When you logout and login, after you enter the username and password, you will get an option of how to get the security code to use for two-factor authentication.
+
+
+ You can copy the code from your SMS or email and enter in the form to login.
+
+
+ The sample also shows how to protect against Brute force attacks against two-factor codes. When you enter a code incorrectly for 5 times then you will be
+ lockedout for 5 min before you can enter a new code. These settings can be configured in App_Start\IdentityConfig.cs by setting DefaultAccountLockoutTimeSpan and MaxFailedAccessAttemptsBeforeLockout on the UserManager.
+
+
+ If the machine you are browsing this website is your own machine, you can choose to check the "Remember Me" option after you enter the code.
+ This option will remember you forever on this machine and will not ask you for the two-factor authentication, the next time when you login to the website.
+ You can change your "Remember Me" settings for two-factor authentication in the Manage page.
+
+
+
+
+
+
+
+ Account Lockout
+
+ Provide a way to Lockout out the user if the user enters their password or two-factor codes incorrectly.
+ The number of invalid attempts and the timespan for the users are locked out can be configured.
+ A developer can optionally turn off Account Lockout for certain user accounts should they need to.
+
+
+ Account LockOut settings can be configured in the UserManager in IdentityConfig.cs
+
+
+
+
+
+ Security Token provider
+
+ Support a way to regenerate the Security Token for the user in cases when the User changes there password or any other security related information such as removing an associated login(such as Facebook, Google, Microsoft Account etc).
+ This is needed to ensure that any tokens generated with the old password are invalidated. In the sample project, if you change the users password then a new token is generated for the user and any previous tokens are invalidated.
+ This feature provides an extra layer of security to your application since when you change your password, you will be logged out from everywhere (all other browsers) where you have logged into this application.
+
+
+
+ The provider is registered when you add CookieAuthentication in StartupAuth to your application.
+
+
+
+
+
+
+ Password Reset
+
+ Allows the user to reset their passwords if they have forgotten their password. In this sample users need to confirm their email before they can reset their passwords.
+
+
+
+
+
+ Custom Storage providers
+
+ You can extend ASP.NET Identity to write your own custom storage provider for storing the ASP.NET Identity system and user data
+ in a persistance system of your choice such as MondoDb, RavenDb, Azure Table Storage etc.
+
+
+
+
+
+
+
+
+ Documentation
+
+
+
+
+
+
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_Layout.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_Layout.cshtml
new file mode 100644
index 0000000000..d0d0d86988
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_Layout.cshtml
@@ -0,0 +1,44 @@
+
+
+
+
+
+ @ViewData["Title"] - Identity Sample
+
+
+
+
+
+
+
+
+
+ @await Html.PartialAsync("_LoginPartial")
+
+
+
+
+
+
+
+
+
+ @RenderSection("scripts", required: false)
+
+
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_LoginPartial.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_LoginPartial.cshtml
new file mode 100644
index 0000000000..3e8d8f66d3
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_LoginPartial.cshtml
@@ -0,0 +1,24 @@
+@using IdentitySample.DefaultUI.Data
+@inject SignInManager SignInManager
+@inject UserManager UserManager
+
+@if (SignInManager.IsSignedIn(User))
+{
+
+}
+else
+{
+
+}
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_ValidationScriptsPartial.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_ValidationScriptsPartial.cshtml
new file mode 100644
index 0000000000..a6c30d4d82
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Views/Shared/_ValidationScriptsPartial.cshtml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Views/_ViewImports.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Views/_ViewImports.cshtml
new file mode 100644
index 0000000000..cca35071d9
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Views/_ViewImports.cshtml
@@ -0,0 +1,2 @@
+@using Microsoft.AspNetCore.Identity
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Views/_ViewStart.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Views/_ViewStart.cshtml
new file mode 100644
index 0000000000..a5f10045db
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "_Layout";
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/appsettings.json b/src/Identity/samples/IdentitySample.DefaultUI/appsettings.json
new file mode 100644
index 0000000000..f781a53564
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/appsettings.json
@@ -0,0 +1,13 @@
+{
+ "ConnectionStrings": {
+ "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-IdentitySample.DefaultUI-47781151-7d38-4b7b-8fe4-9a8b299f124f;Trusted_Connection=True;MultipleActiveResultSets=true"
+ },
+ "Logging": {
+ "IncludeScopes": false,
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/web.Debug.config b/src/Identity/samples/IdentitySample.DefaultUI/web.Debug.config
new file mode 100644
index 0000000000..2e302f9f95
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/web.Debug.config
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/web.Release.config b/src/Identity/samples/IdentitySample.DefaultUI/web.Release.config
new file mode 100644
index 0000000000..c35844462b
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/web.Release.config
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/web.config b/src/Identity/samples/IdentitySample.DefaultUI/web.config
new file mode 100644
index 0000000000..f7ac679334
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/web.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/css/site.css b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/css/site.css
new file mode 100644
index 0000000000..6d0f6e44ec
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/css/site.css
@@ -0,0 +1,35 @@
+body {
+ padding-top: 50px;
+ padding-bottom: 20px;
+}
+
+/* Wrapping element */
+/* Set some basic padding to keep content from hitting the edges */
+.body-content {
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+/* Carousel */
+.carousel-caption p {
+ font-size: 20px;
+ line-height: 1.4;
+}
+
+/* Make .svg files in the carousel display properly in older browsers */
+.carousel-inner .item img[src$=".svg"] {
+ width: 100%;
+}
+
+/* QR code generator */
+#qrCode {
+ margin: 15px;
+}
+
+/* Hide/rearrange for smaller screens */
+@media screen and (max-width: 767px) {
+ /* Hide captions */
+ .carousel-caption {
+ display: none;
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/css/site.min.css b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/css/site.min.css
new file mode 100644
index 0000000000..5e93e30ae3
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/css/site.min.css
@@ -0,0 +1 @@
+body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}}
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/favicon.ico b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/favicon.ico
new file mode 100644
index 0000000000..a3a799985c
Binary files /dev/null and b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/favicon.ico differ
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/js/site.js b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/js/site.js
new file mode 100644
index 0000000000..0f3411a45b
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/js/site.js
@@ -0,0 +1 @@
+// Write your JavaScript code.
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/js/site.min.js b/src/Identity/samples/IdentitySample.DefaultUI/wwwroot/js/site.min.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/Identity/samples/IdentitySample.Mvc/Controllers/AccountController.cs b/src/Identity/samples/IdentitySample.Mvc/Controllers/AccountController.cs
new file mode 100644
index 0000000000..ca996ea292
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.Mvc/Controllers/AccountController.cs
@@ -0,0 +1,565 @@
+using System.Linq;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using IdentitySample.Models;
+using IdentitySample.Models.AccountViewModels;
+using IdentitySample.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.Extensions.Logging;
+
+namespace IdentitySample.Controllers
+{
+ [Authorize]
+ public class AccountController : Controller
+ {
+ private readonly UserManager _userManager;
+ private readonly SignInManager _signInManager;
+ private readonly IEmailSender _emailSender;
+ private readonly ISmsSender _smsSender;
+ private readonly ILogger _logger;
+
+ public AccountController(
+ UserManager userManager,
+ SignInManager signInManager,
+ IEmailSender emailSender,
+ ISmsSender smsSender,
+ ILoggerFactory loggerFactory)
+ {
+ _userManager = userManager;
+ _signInManager = signInManager;
+ _emailSender = emailSender;
+ _smsSender = smsSender;
+ _logger = loggerFactory.CreateLogger();
+ }
+
+ //
+ // GET: /Account/Login
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult Login(string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ return View();
+ }
+
+ //
+ // POST: /Account/Login
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task Login(LoginViewModel model, string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ if (ModelState.IsValid)
+ {
+ // This doesn't count login failures towards account lockout
+ // To enable password failures to trigger account lockout, set lockoutOnFailure: true
+ var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
+ if (result.Succeeded)
+ {
+ _logger.LogInformation(1, "User logged in.");
+ return RedirectToLocal(returnUrl);
+ }
+ if (result.RequiresTwoFactor)
+ {
+ return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
+ }
+ if (result.IsLockedOut)
+ {
+ _logger.LogWarning(2, "User account locked out.");
+ return View("Lockout");
+ }
+ else
+ {
+ ModelState.AddModelError(string.Empty, "Invalid login attempt.");
+ return View(model);
+ }
+ }
+
+ // If we got this far, something failed, redisplay form
+ return View(model);
+ }
+
+ //
+ // GET: /Account/Register
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult Register(string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ return View();
+ }
+
+ //
+ // POST: /Account/Register
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task Register(RegisterViewModel model, string returnUrl = null)
+ {
+ ViewData["ReturnUrl"] = returnUrl;
+ if (ModelState.IsValid)
+ {
+ var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
+ var result = await _userManager.CreateAsync(user, model.Password);
+ if (result.Succeeded)
+ {
+ // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
+ // Send an email with this link
+ //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
+ //var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
+ //await _emailSender.SendEmailAsync(model.Email, "Confirm your account",
+ // "Please confirm your account by clicking this link: link ");
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ _logger.LogInformation(3, "User created a new account with password.");
+ return RedirectToLocal(returnUrl);
+ }
+ AddErrors(result);
+ }
+
+ // If we got this far, something failed, redisplay form
+ return View(model);
+ }
+
+ //
+ // POST: /Account/LogOff
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task LogOff()
+ {
+ await _signInManager.SignOutAsync();
+ _logger.LogInformation(4, "User logged out.");
+ return RedirectToAction(nameof(HomeController.Index), "Home");
+ }
+
+ //
+ // POST: /Account/ExternalLogin
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public IActionResult ExternalLogin(string provider, string returnUrl = null)
+ {
+ // Request a redirect to the external login provider.
+ var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
+ var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
+ return Challenge(properties, provider);
+ }
+
+ //
+ // GET: /Account/ExternalLoginCallback
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task ExternalLoginCallback(string returnUrl = null, string remoteError = null)
+ {
+ if (remoteError != null)
+ {
+ ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
+ return View(nameof(Login));
+ }
+ var info = await _signInManager.GetExternalLoginInfoAsync();
+ if (info == null)
+ {
+ return RedirectToAction(nameof(Login));
+ }
+
+ // Sign in the user with this external login provider if the user already has a login.
+ var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
+ if (result.Succeeded)
+ {
+ // Update any authentication tokens if login succeeded
+ await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
+
+ _logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider);
+ return RedirectToLocal(returnUrl);
+ }
+ if (result.RequiresTwoFactor)
+ {
+ return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl });
+ }
+ if (result.IsLockedOut)
+ {
+ return View("Lockout");
+ }
+ else
+ {
+ // If the user does not have an account, then ask the user to create an account.
+ ViewData["ReturnUrl"] = returnUrl;
+ ViewData["LoginProvider"] = info.LoginProvider;
+ var email = info.Principal.FindFirstValue(ClaimTypes.Email);
+ return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email });
+ }
+ }
+
+ //
+ // POST: /Account/ExternalLoginConfirmation
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null)
+ {
+ if (ModelState.IsValid)
+ {
+ // Get the information about the user from the external login provider
+ var info = await _signInManager.GetExternalLoginInfoAsync();
+ if (info == null)
+ {
+ return View("ExternalLoginFailure");
+ }
+ var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
+ var result = await _userManager.CreateAsync(user);
+ if (result.Succeeded)
+ {
+ result = await _userManager.AddLoginAsync(user, info);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ _logger.LogInformation(6, "User created an account using {Name} provider.", info.LoginProvider);
+
+ // Update any authentication tokens as well
+ await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
+
+ return RedirectToLocal(returnUrl);
+ }
+ }
+ AddErrors(result);
+ }
+
+ ViewData["ReturnUrl"] = returnUrl;
+ return View(model);
+ }
+
+ // GET: /Account/ConfirmEmail
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task ConfirmEmail(string userId, string code)
+ {
+ if (userId == null || code == null)
+ {
+ return View("Error");
+ }
+ var user = await _userManager.FindByIdAsync(userId);
+ if (user == null)
+ {
+ return View("Error");
+ }
+ var result = await _userManager.ConfirmEmailAsync(user, code);
+ return View(result.Succeeded ? "ConfirmEmail" : "Error");
+ }
+
+ //
+ // GET: /Account/ForgotPassword
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ForgotPassword()
+ {
+ return View();
+ }
+
+ //
+ // POST: /Account/ForgotPassword
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task ForgotPassword(ForgotPasswordViewModel model)
+ {
+ if (ModelState.IsValid)
+ {
+ var user = await _userManager.FindByEmailAsync(model.Email);
+ if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
+ {
+ // Don't reveal that the user does not exist or is not confirmed
+ return View("ForgotPasswordConfirmation");
+ }
+
+ // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
+ // Send an email with this link
+ //var code = await _userManager.GeneratePasswordResetTokenAsync(user);
+ //var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
+ //await _emailSender.SendEmailAsync(model.Email, "Reset Password",
+ // "Please reset your password by clicking here: link ");
+ //return View("ForgotPasswordConfirmation");
+ }
+
+ // If we got this far, something failed, redisplay form
+ return View(model);
+ }
+
+ //
+ // GET: /Account/ForgotPasswordConfirmation
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ForgotPasswordConfirmation()
+ {
+ return View();
+ }
+
+ //
+ // GET: /Account/ResetPassword
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ResetPassword(string code = null)
+ {
+ return code == null ? View("Error") : View();
+ }
+
+ //
+ // POST: /Account/ResetPassword
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task ResetPassword(ResetPasswordViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+ var user = await _userManager.FindByEmailAsync(model.Email);
+ if (user == null)
+ {
+ // Don't reveal that the user does not exist
+ return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
+ }
+ var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
+ if (result.Succeeded)
+ {
+ return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
+ }
+ AddErrors(result);
+ return View();
+ }
+
+ //
+ // GET: /Account/ResetPasswordConfirmation
+ [HttpGet]
+ [AllowAnonymous]
+ public IActionResult ResetPasswordConfirmation()
+ {
+ return View();
+ }
+
+ //
+ // GET: /Account/SendCode
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task SendCode(string returnUrl = null, bool rememberMe = false)
+ {
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ {
+ return View("Error");
+ }
+ var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user);
+ var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
+ return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
+ }
+
+ //
+ // POST: /Account/SendCode
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task SendCode(SendCodeViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View();
+ }
+
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ {
+ return View("Error");
+ }
+
+ if (model.SelectedProvider == "Authenticator")
+ {
+ return RedirectToAction(nameof(VerifyAuthenticatorCode), new { ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
+ }
+
+ // Generate the token and send it
+ var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider);
+ if (string.IsNullOrWhiteSpace(code))
+ {
+ return View("Error");
+ }
+
+ var message = "Your security code is: " + code;
+ if (model.SelectedProvider == "Email")
+ {
+ await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message);
+ }
+ else if (model.SelectedProvider == "Phone")
+ {
+ await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message);
+ }
+
+ return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
+ }
+
+ //
+ // GET: /Account/VerifyCode
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null)
+ {
+ // Require that the user has already logged in via username/password or external login
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ {
+ return View("Error");
+ }
+ return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
+ }
+
+ //
+ // POST: /Account/VerifyCode
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task VerifyCode(VerifyCodeViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+
+ // The following code protects for brute force attacks against the two factor codes.
+ // If a user enters incorrect codes for a specified amount of time then the user account
+ // will be locked out for a specified amount of time.
+ var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser);
+ if (result.Succeeded)
+ {
+ return RedirectToLocal(model.ReturnUrl);
+ }
+ if (result.IsLockedOut)
+ {
+ _logger.LogWarning(7, "User account locked out.");
+ return View("Lockout");
+ }
+ else
+ {
+ ModelState.AddModelError(string.Empty, "Invalid code.");
+ return View(model);
+ }
+ }
+
+ //
+ // GET: /Account/VerifyAuthenticatorCode
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task VerifyAuthenticatorCode(bool rememberMe, string returnUrl = null)
+ {
+ // Require that the user has already logged in via username/password or external login
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ {
+ return View("Error");
+ }
+ return View(new VerifyAuthenticatorCodeViewModel { ReturnUrl = returnUrl, RememberMe = rememberMe });
+ }
+
+ //
+ // POST: /Account/VerifyAuthenticatorCode
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task VerifyAuthenticatorCode(VerifyAuthenticatorCodeViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+
+ // The following code protects for brute force attacks against the two factor codes.
+ // If a user enters incorrect codes for a specified amount of time then the user account
+ // will be locked out for a specified amount of time.
+ var result = await _signInManager.TwoFactorAuthenticatorSignInAsync(model.Code, model.RememberMe, model.RememberBrowser);
+ if (result.Succeeded)
+ {
+ return RedirectToLocal(model.ReturnUrl);
+ }
+ if (result.IsLockedOut)
+ {
+ _logger.LogWarning(7, "User account locked out.");
+ return View("Lockout");
+ }
+ else
+ {
+ ModelState.AddModelError(string.Empty, "Invalid code.");
+ return View(model);
+ }
+ }
+
+ //
+ // GET: /Account/UseRecoveryCode
+ [HttpGet]
+ [AllowAnonymous]
+ public async Task UseRecoveryCode(string returnUrl = null)
+ {
+ // Require that the user has already logged in via username/password or external login
+ var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
+ if (user == null)
+ {
+ return View("Error");
+ }
+ return View(new UseRecoveryCodeViewModel { ReturnUrl = returnUrl });
+ }
+
+ //
+ // POST: /Account/UseRecoveryCode
+ [HttpPost]
+ [AllowAnonymous]
+ [ValidateAntiForgeryToken]
+ public async Task UseRecoveryCode(UseRecoveryCodeViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+
+ var result = await _signInManager.TwoFactorRecoveryCodeSignInAsync(model.Code);
+ if (result.Succeeded)
+ {
+ return RedirectToLocal(model.ReturnUrl);
+ }
+ else
+ {
+ ModelState.AddModelError(string.Empty, "Invalid code.");
+ return View(model);
+ }
+ }
+
+
+ #region Helpers
+
+ private void AddErrors(IdentityResult result)
+ {
+ foreach (var error in result.Errors)
+ {
+ ModelState.AddModelError(string.Empty, error.Description);
+ }
+ }
+
+ private Task GetCurrentUserAsync()
+ {
+ return _userManager.GetUserAsync(HttpContext.User);
+ }
+
+ private IActionResult RedirectToLocal(string returnUrl)
+ {
+ if (Url.IsLocalUrl(returnUrl))
+ {
+ return Redirect(returnUrl);
+ }
+ else
+ {
+ return RedirectToAction(nameof(HomeController.Index), "Home");
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.Mvc/Controllers/HomeController.cs b/src/Identity/samples/IdentitySample.Mvc/Controllers/HomeController.cs
new file mode 100644
index 0000000000..b98b2869ec
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.Mvc/Controllers/HomeController.cs
@@ -0,0 +1,13 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace IdentitySample.Controllers
+{
+ public class HomeController : Controller
+ {
+ [HttpGet]
+ public IActionResult Index()
+ {
+ return View();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.Mvc/Controllers/ManageController.cs b/src/Identity/samples/IdentitySample.Mvc/Controllers/ManageController.cs
new file mode 100644
index 0000000000..628345fbe5
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.Mvc/Controllers/ManageController.cs
@@ -0,0 +1,379 @@
+using System.Linq;
+using System.Threading.Tasks;
+using IdentitySample.Models;
+using IdentitySample.Models.ManageViewModels;
+using IdentitySample.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace IdentitySamples.Controllers
+{
+
+ [Authorize]
+ public class ManageController : Controller
+ {
+ private readonly UserManager _userManager;
+ private readonly SignInManager _signInManager;
+ private readonly IEmailSender _emailSender;
+ private readonly ISmsSender _smsSender;
+ private readonly ILogger _logger;
+
+ public ManageController(
+ UserManager userManager,
+ SignInManager signInManager,
+ IEmailSender emailSender,
+ ISmsSender smsSender,
+ ILoggerFactory loggerFactory)
+ {
+ _userManager = userManager;
+ _signInManager = signInManager;
+ _emailSender = emailSender;
+ _smsSender = smsSender;
+ _logger = loggerFactory.CreateLogger();
+ }
+
+ //
+ // GET: /Manage/Index
+ [HttpGet]
+ public async Task Index(ManageMessageId? message = null)
+ {
+ ViewData["StatusMessage"] =
+ message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
+ : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
+ : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
+ : message == ManageMessageId.Error ? "An error has occurred."
+ : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
+ : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
+ : "";
+
+ var user = await GetCurrentUserAsync();
+ var model = new IndexViewModel
+ {
+ HasPassword = await _userManager.HasPasswordAsync(user),
+ PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
+ TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
+ Logins = await _userManager.GetLoginsAsync(user),
+ BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user),
+ AuthenticatorKey = await _userManager.GetAuthenticatorKeyAsync(user)
+ };
+ return View(model);
+ }
+
+ //
+ // POST: /Manage/RemoveLogin
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task RemoveLogin(RemoveLoginViewModel account)
+ {
+ ManageMessageId? message = ManageMessageId.Error;
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ message = ManageMessageId.RemoveLoginSuccess;
+ }
+ }
+ return RedirectToAction(nameof(ManageLogins), new { Message = message });
+ }
+
+ //
+ // GET: /Manage/AddPhoneNumber
+ public IActionResult AddPhoneNumber()
+ {
+ return View();
+ }
+
+ //
+ // POST: /Manage/AddPhoneNumber
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task AddPhoneNumber(AddPhoneNumberViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+ // Generate the token and send it
+ var user = await GetCurrentUserAsync();
+ var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
+ await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
+ return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
+ }
+
+ //
+ // POST: /Manage/ResetAuthenticatorKey
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task ResetAuthenticatorKey()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ await _userManager.ResetAuthenticatorKeyAsync(user);
+ _logger.LogInformation(1, "User reset authenticator key.");
+ }
+ return RedirectToAction(nameof(Index), "Manage");
+ }
+
+ //
+ // POST: /Manage/GenerateRecoveryCode
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task GenerateRecoveryCode()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var codes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 5);
+ _logger.LogInformation(1, "User generated new recovery code.");
+ return View("DisplayRecoveryCodes", new DisplayRecoveryCodesViewModel { Codes = codes });
+ }
+ return View("Error");
+ }
+
+ //
+ // POST: /Manage/EnableTwoFactorAuthentication
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task EnableTwoFactorAuthentication()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ await _userManager.SetTwoFactorEnabledAsync(user, true);
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ _logger.LogInformation(1, "User enabled two-factor authentication.");
+ }
+ return RedirectToAction(nameof(Index), "Manage");
+ }
+
+ //
+ // POST: /Manage/DisableTwoFactorAuthentication
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task DisableTwoFactorAuthentication()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ await _userManager.SetTwoFactorEnabledAsync(user, false);
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ _logger.LogInformation(2, "User disabled two-factor authentication.");
+ }
+ return RedirectToAction(nameof(Index), "Manage");
+ }
+
+ //
+ // GET: /Manage/VerifyPhoneNumber
+ [HttpGet]
+ public async Task VerifyPhoneNumber(string phoneNumber)
+ {
+ var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
+ // Send an SMS to verify the phone number
+ return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
+ }
+
+ //
+ // POST: /Manage/VerifyPhoneNumber
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
+ }
+ }
+ // If we got this far, something failed, redisplay the form
+ ModelState.AddModelError(string.Empty, "Failed to verify phone number");
+ return View(model);
+ }
+
+ //
+ // GET: /Manage/RemovePhoneNumber
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task RemovePhoneNumber()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.SetPhoneNumberAsync(user, null);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
+ }
+ }
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
+ }
+
+ //
+ // GET: /Manage/ChangePassword
+ [HttpGet]
+ public IActionResult ChangePassword()
+ {
+ return View();
+ }
+
+ //
+ // POST: /Manage/ChangePassword
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task ChangePassword(ChangePasswordViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ _logger.LogInformation(3, "User changed their password successfully.");
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
+ }
+ AddErrors(result);
+ return View(model);
+ }
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
+ }
+
+ //
+ // GET: /Manage/SetPassword
+ [HttpGet]
+ public IActionResult SetPassword()
+ {
+ return View();
+ }
+
+ //
+ // POST: /Manage/SetPassword
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public async Task SetPassword(SetPasswordViewModel model)
+ {
+ if (!ModelState.IsValid)
+ {
+ return View(model);
+ }
+
+ var user = await GetCurrentUserAsync();
+ if (user != null)
+ {
+ var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, isPersistent: false);
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
+ }
+ AddErrors(result);
+ return View(model);
+ }
+ return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
+ }
+
+ //GET: /Manage/ManageLogins
+ [HttpGet]
+ public async Task ManageLogins(ManageMessageId? message = null)
+ {
+ ViewData["StatusMessage"] =
+ message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
+ : message == ManageMessageId.AddLoginSuccess ? "The external login was added."
+ : message == ManageMessageId.Error ? "An error has occurred."
+ : "";
+ var user = await GetCurrentUserAsync();
+ if (user == null)
+ {
+ return View("Error");
+ }
+ var userLogins = await _userManager.GetLoginsAsync(user);
+ var schemes = await _signInManager.GetExternalAuthenticationSchemesAsync();
+ var otherLogins = schemes.Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList();
+ ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
+ return View(new ManageLoginsViewModel
+ {
+ CurrentLogins = userLogins,
+ OtherLogins = otherLogins
+ });
+ }
+
+ //
+ // POST: /Manage/LinkLogin
+ [HttpPost]
+ [ValidateAntiForgeryToken]
+ public IActionResult LinkLogin(string provider)
+ {
+ // Request a redirect to the external login provider to link a login for the current user
+ var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
+ var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
+ return Challenge(properties, provider);
+ }
+
+ //
+ // GET: /Manage/LinkLoginCallback
+ [HttpGet]
+ public async Task LinkLoginCallback()
+ {
+ var user = await GetCurrentUserAsync();
+ if (user == null)
+ {
+ return View("Error");
+ }
+ var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
+ if (info == null)
+ {
+ return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
+ }
+ var result = await _userManager.AddLoginAsync(user, info);
+ var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
+ return RedirectToAction(nameof(ManageLogins), new { Message = message });
+ }
+
+ #region Helpers
+
+ private void AddErrors(IdentityResult result)
+ {
+ foreach (var error in result.Errors)
+ {
+ ModelState.AddModelError(string.Empty, error.Description);
+ }
+ }
+
+ public enum ManageMessageId
+ {
+ AddPhoneSuccess,
+ AddLoginSuccess,
+ ChangePasswordSuccess,
+ SetTwoFactorSuccess,
+ SetPasswordSuccess,
+ RemoveLoginSuccess,
+ RemovePhoneSuccess,
+ Error
+ }
+
+ private Task GetCurrentUserAsync()
+ {
+ return _userManager.GetUserAsync(HttpContext.User);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.Mvc/CopyAspNetLoader.cmd b/src/Identity/samples/IdentitySample.Mvc/CopyAspNetLoader.cmd
new file mode 100644
index 0000000000..f23e9109d0
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.Mvc/CopyAspNetLoader.cmd
@@ -0,0 +1,7 @@
+REM copy the AspNet.Loader.dll to bin folder
+md bin
+
+REM figure out the path of AspNet.Loader.dll
+FOR /F %%j IN ('dir /b /o:-d ..\..\packages\Microsoft.AspNetCore.Loader.IIS.Interop*') do (SET AspNetLoaderPath=..\..\packages\%%j\tools\AspNet.Loader.dll)
+echo Found AspNetLoader.dll at %AspNetLoaderPath%. Copying to bin\
+copy %AspNetLoaderPath% bin\
\ No newline at end of file
diff --git a/src/Identity/samples/IdentitySample.Mvc/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs b/src/Identity/samples/IdentitySample.Mvc/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs
new file mode 100644
index 0000000000..c68785939b
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.Mvc/Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs
@@ -0,0 +1,217 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using IdentitySample.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace IdentitySample.Data.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("00000000000000_CreateIdentitySchema")]
+ partial class CreateIdentitySchema
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .HasAnnotation("ProductVersion", "1.0.0-rc3")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b =>
+ {
+ b.Property("Id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("NormalizedName")
+ .HasAnnotation("MaxLength", 256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .HasName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider");
+
+ b.Property("ProviderKey");
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("LoginProvider");
+
+ b.Property("Name");
+
+ b.Property("Value");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("WebApplication13.Models.ApplicationUser", b =>
+ {
+ b.Property("Id");
+
+ b.Property("AccessFailedCount");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Email")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("EmailConfirmed");
+
+ b.Property("LockoutEnabled");
+
+ b.Property("LockoutEnd");
+
+ b.Property("NormalizedEmail")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("NormalizedUserName")
+ .HasAnnotation("MaxLength", 256);
+
+ b.Property("PasswordHash");
+
+ b.Property("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed");
+
+ b.Property("SecurityStamp");
+
+ b.Property("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .HasAnnotation("MaxLength", 256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasName("UserNameIndex");
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+ .WithMany("Claims")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b =>
+ {
+ b.HasOne("WebApplication13.Models.ApplicationUser")
+ .WithMany("Claims")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b =>
+ {
+ b.HasOne("WebApplication13.Models.ApplicationUser")
+ .WithMany("Logins")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+ .WithMany("Users")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("WebApplication13.Models.ApplicationUser")
+ .WithMany("Roles")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+ }
+ }
+}
diff --git a/src/Identity/samples/IdentitySample.Mvc/Data/Migrations/00000000000000_CreateIdentitySchema.cs b/src/Identity/samples/IdentitySample.Mvc/Data/Migrations/00000000000000_CreateIdentitySchema.cs
new file mode 100644
index 0000000000..7233e2d3bc
--- /dev/null
+++ b/src/Identity/samples/IdentitySample.Mvc/Data/Migrations/00000000000000_CreateIdentitySchema.cs
@@ -0,0 +1,219 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace IdentitySample.Data.Migrations
+{
+ public partial class CreateIdentitySchema : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "AspNetRoles",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ ConcurrencyStamp = table.Column(nullable: true),
+ Name = table.Column(maxLength: 256, nullable: true),
+ NormalizedName = table.Column(maxLength: 256, nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoles", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserTokens",
+ columns: table => new
+ {
+ UserId = table.Column(nullable: false),
+ LoginProvider = table.Column