Browse Source

Move DataProtection and Extensions.Identity to netstandard2.0/2.1 (#11008)

Hao Kung 6 years ago
parent
commit
f35564ba06
48 changed files with 896 additions and 76 deletions
  1. 3 0
      eng/SharedFramework.External.props
  2. 7 7
      eng/SharedFramework.Local.props
  3. 3 3
      src/DataProtection/Abstractions/ref/Microsoft.AspNetCore.DataProtection.Abstractions.csproj
  4. 0 0
      src/DataProtection/Abstractions/ref/Microsoft.AspNetCore.DataProtection.Abstractions.netstandard2.0.cs
  5. 2 1
      src/DataProtection/Abstractions/src/Microsoft.AspNetCore.DataProtection.Abstractions.csproj
  6. 3 3
      src/DataProtection/AzureKeyVault/ref/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj
  7. 0 0
      src/DataProtection/AzureKeyVault/ref/Microsoft.AspNetCore.DataProtection.AzureKeyVault.netstandard2.0.cs
  8. 1 1
      src/DataProtection/AzureKeyVault/src/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj
  9. 3 3
      src/DataProtection/AzureStorage/ref/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj
  10. 0 0
      src/DataProtection/AzureStorage/ref/Microsoft.AspNetCore.DataProtection.AzureStorage.netstandard2.0.cs
  11. 1 1
      src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj
  12. 3 3
      src/DataProtection/Cryptography.Internal/ref/Microsoft.AspNetCore.Cryptography.Internal.csproj
  13. 0 0
      src/DataProtection/Cryptography.Internal/ref/Microsoft.AspNetCore.Cryptography.Internal.netstandard2.0.cs
  14. 2 1
      src/DataProtection/Cryptography.Internal/src/Microsoft.AspNetCore.Cryptography.Internal.csproj
  15. 7 3
      src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj
  16. 0 0
      src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.netcoreapp2.0.cs
  17. 16 0
      src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.netstandard2.0.cs
  18. 2 1
      src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj
  19. 2 0
      src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/NetCorePbkdf2Provider.cs
  20. 6 0
      src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs
  21. 4 4
      src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.csproj
  22. 0 0
      src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netstandard2.0.cs
  23. 2 2
      src/DataProtection/DataProtection/src/DataProtectionServiceCollectionExtensions.cs
  24. 13 10
      src/DataProtection/DataProtection/src/Internal/DataProtectionHostedService.cs
  25. 4 2
      src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.csproj
  26. 30 2
      src/DataProtection/DataProtection/test/HostingTests.cs
  27. 2 1
      src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests.csproj
  28. 3 3
      src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.csproj
  29. 0 0
      src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netstandard2.1.cs
  30. 1 1
      src/DataProtection/EntityFrameworkCore/src/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.csproj
  31. 3 3
      src/DataProtection/Extensions/ref/Microsoft.AspNetCore.DataProtection.Extensions.csproj
  32. 0 0
      src/DataProtection/Extensions/ref/Microsoft.AspNetCore.DataProtection.Extensions.netstandard2.0.cs
  33. 2 1
      src/DataProtection/Extensions/src/Microsoft.AspNetCore.DataProtection.Extensions.csproj
  34. 3 3
      src/DataProtection/StackExchangeRedis/ref/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj
  35. 0 0
      src/DataProtection/StackExchangeRedis/ref/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.netstandard2.0.cs
  36. 1 1
      src/DataProtection/StackExchangeRedis/src/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj
  37. 5 3
      src/Hosting/Hosting/src/Internal/WebHost.cs
  38. 2 2
      src/Hosting/Hosting/test/WebHostTests.cs
  39. 0 2
      src/Identity/Core/ref/Microsoft.AspNetCore.Identity.csproj
  40. 0 2
      src/Identity/Core/src/Microsoft.AspNetCore.Identity.csproj
  41. 8 2
      src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.csproj
  42. 707 0
      src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs
  43. 3 1
      src/Identity/Extensions.Core/src/Microsoft.Extensions.Identity.Core.csproj
  44. 34 0
      src/Identity/Extensions.Core/src/PasswordHasher.cs
  45. 3 3
      src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.csproj
  46. 0 0
      src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netstandard2.0.cs
  47. 3 1
      src/Identity/Extensions.Stores/src/Microsoft.Extensions.Identity.Stores.csproj
  48. 2 0
      src/Shared/WebEncoders/WebEncoders.cs

+ 3 - 0
eng/SharedFramework.External.props

@@ -91,6 +91,9 @@
     This references are part of Microsoft.NETCore.App, so are listed here as references to be used during compilation only.
   -->
   <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'">
+    <_CompilationOnlyReference Include="Microsoft.Win32.Registry" />
+    <_CompilationOnlyReference Include="System.Security.Cryptography.Cng" />
+    <_CompilationOnlyReference Include="System.Security.Principal.Windows" />
     <_CompilationOnlyReference Include="System.Buffers" />
     <_CompilationOnlyReference Include="System.ComponentModel.Annotations" />
     <_CompilationOnlyReference Include="System.Runtime.CompilerServices.Unsafe" />

+ 7 - 7
eng/SharedFramework.Local.props

@@ -8,8 +8,15 @@
 <Project>
   <ItemGroup>
     <!-- These assemblies are available as both a NuGet package and in the shared framework -->
+    <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.DataProtection.Abstractions" />
+    <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.Cryptography.Internal" />
+    <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" />
+    <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.DataProtection" />
+    <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.DataProtection.Extensions" />
     <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.Http.Features" />
     <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.Metadata" />
+    <AspNetCoreAppReferenceAndPackage Include="Microsoft.Extensions.Identity.Core" />
+    <AspNetCoreAppReferenceAndPackage Include="Microsoft.Extensions.Identity.Stores" />
     <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.Connections.Abstractions" />
     <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.Authorization" />
     <AspNetCoreAppReferenceAndPackage Include="Microsoft.AspNetCore.Http.Connections.Common" />
@@ -20,11 +27,6 @@
 
     <!-- These assemblies are only in the shared framework -->
     <AspNetCoreAppReference Include="Microsoft.AspNetCore" />
-    <AspNetCoreAppReference Include="Microsoft.AspNetCore.DataProtection.Abstractions" />
-    <AspNetCoreAppReference Include="Microsoft.AspNetCore.Cryptography.Internal" />
-    <AspNetCoreAppReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" />
-    <AspNetCoreAppReference Include="Microsoft.AspNetCore.DataProtection" />
-    <AspNetCoreAppReference Include="Microsoft.AspNetCore.DataProtection.Extensions" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Antiforgery" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Hosting.Abstractions" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Hosting" />
@@ -40,8 +42,6 @@
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.WebUtilities" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Html.Abstractions" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Identity" />
-    <AspNetCoreAppReference Include="Microsoft.Extensions.Identity.Core" />
-    <AspNetCoreAppReference Include="Microsoft.Extensions.Identity.Stores" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Server.HttpSys" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Server.IISIntegration" />
     <AspNetCoreAppReference Include="Microsoft.AspNetCore.Server.IIS" />

+ 3 - 3
src/DataProtection/Abstractions/ref/Microsoft.AspNetCore.DataProtection.Abstractions.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.DataProtection.Abstractions.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.DataProtection.Abstractions.netstandard2.0.cs" />
     
   </ItemGroup>
 </Project>

+ 0 - 0
src/DataProtection/Abstractions/ref/Microsoft.AspNetCore.DataProtection.Abstractions.netcoreapp3.0.cs → src/DataProtection/Abstractions/ref/Microsoft.AspNetCore.DataProtection.Abstractions.netstandard2.0.cs


+ 2 - 1
src/DataProtection/Abstractions/src/Microsoft.AspNetCore.DataProtection.Abstractions.csproj

@@ -5,8 +5,9 @@
 Commonly used types:
 Microsoft.AspNetCore.DataProtection.IDataProtectionProvider
 Microsoft.AspNetCore.DataProtection.IDataProtector</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
+    <IsShippingPackage>true</IsShippingPackage>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection</PackageTags>
   </PropertyGroup>

+ 3 - 3
src/DataProtection/AzureKeyVault/ref/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.DataProtection.AzureKeyVault.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.DataProtection.AzureKeyVault.netstandard2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.DataProtection"  />
     <Reference Include="Microsoft.Azure.KeyVault"  />
     <Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory"  />

+ 0 - 0
src/DataProtection/AzureKeyVault/ref/Microsoft.AspNetCore.DataProtection.AzureKeyVault.netcoreapp3.0.cs → src/DataProtection/AzureKeyVault/ref/Microsoft.AspNetCore.DataProtection.AzureKeyVault.netstandard2.0.cs


+ 1 - 1
src/DataProtection/AzureKeyVault/src/Microsoft.AspNetCore.DataProtection.AzureKeyVault.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <Description>Microsoft Azure KeyVault key encryption support.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection;azure;keyvault</PackageTags>
     <IsShippingPackage>true</IsShippingPackage>

+ 3 - 3
src/DataProtection/AzureStorage/ref/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.DataProtection.AzureStorage.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.DataProtection.AzureStorage.netstandard2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.DataProtection"  />
     <Reference Include="Microsoft.Azure.Storage.Blob"  />
   </ItemGroup>

+ 0 - 0
src/DataProtection/AzureStorage/ref/Microsoft.AspNetCore.DataProtection.AzureStorage.netcoreapp3.0.cs → src/DataProtection/AzureStorage/ref/Microsoft.AspNetCore.DataProtection.AzureStorage.netstandard2.0.cs


+ 1 - 1
src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <Description>Microsoft Azure Blob storage support as key store.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection;azure;blob</PackageTags>

+ 3 - 3
src/DataProtection/Cryptography.Internal/ref/Microsoft.AspNetCore.Cryptography.Internal.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.Cryptography.Internal.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.Cryptography.Internal.netstandard2.0.cs" />
     
   </ItemGroup>
 </Project>

+ 0 - 0
src/DataProtection/Cryptography.Internal/ref/Microsoft.AspNetCore.Cryptography.Internal.netcoreapp3.0.cs → src/DataProtection/Cryptography.Internal/ref/Microsoft.AspNetCore.Cryptography.Internal.netstandard2.0.cs


+ 2 - 1
src/DataProtection/Cryptography.Internal/src/Microsoft.AspNetCore.Cryptography.Internal.csproj

@@ -2,8 +2,9 @@
 
   <PropertyGroup>
     <Description>Infrastructure for ASP.NET Core cryptographic packages. Applications and libraries should not reference this package directly.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
+    <IsShippingPackage>true</IsShippingPackage>
     <NoWarn>$(NoWarn);CS1591</NoWarn>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>

+ 7 - 3
src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj

@@ -1,10 +1,14 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0;netcoreapp2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.Cryptography.KeyDerivation.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.Cryptography.KeyDerivation.netstandard2.0.cs" />
+    <Reference Include="Microsoft.AspNetCore.Cryptography.Internal"  />
+  </ItemGroup>
+<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
+    <Compile Include="Microsoft.AspNetCore.Cryptography.KeyDerivation.netcoreapp2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.Cryptography.Internal"  />
   </ItemGroup>
 </Project>

+ 0 - 0
src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.netcoreapp3.0.cs → src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.netcoreapp2.0.cs


+ 16 - 0
src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.netstandard2.0.cs

@@ -0,0 +1,16 @@
+// 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.
+
+namespace Microsoft.AspNetCore.Cryptography.KeyDerivation
+{
+    public static partial class KeyDerivation
+    {
+        public static byte[] Pbkdf2(string password, byte[] salt, Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf prf, int iterationCount, int numBytesRequested) { throw null; }
+    }
+    public enum KeyDerivationPrf
+    {
+        HMACSHA1 = 0,
+        HMACSHA256 = 1,
+        HMACSHA512 = 2,
+    }
+}

+ 2 - 1
src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj

@@ -2,8 +2,9 @@
 
   <PropertyGroup>
     <Description>ASP.NET Core utilities for key derivation.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFrameworks>netstandard2.0;netcoreapp2.0</TargetFrameworks>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
+    <IsShippingPackage>true</IsShippingPackage>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection</PackageTags>

+ 2 - 0
src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/NetCorePbkdf2Provider.cs

@@ -1,6 +1,7 @@
 // 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.
 
+#if NETCOREAPP2_0
 using System;
 using System.Diagnostics;
 using System.Security.Cryptography;
@@ -61,3 +62,4 @@ namespace Microsoft.AspNetCore.Cryptography.KeyDerivation.PBKDF2
         }
     }
 }
+#endif

+ 6 - 0
src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs

@@ -27,9 +27,15 @@ namespace Microsoft.AspNetCore.Cryptography.KeyDerivation.PBKDF2
             }
             else
             {
+#if NETSTANDARD2_0
+                return new ManagedPbkdf2Provider();
+#elif NETCOREAPP2_0
                 // fastest implementation on .NET Core for Linux/macOS.
                 // Not supported on .NET Framework
                 return new NetCorePbkdf2Provider();
+#else
+#error Update target frameworks
+#endif
             }
         }
     }

+ 4 - 4
src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.csproj

@@ -1,14 +1,14 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.DataProtection.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.DataProtection.netstandard2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.Cryptography.Internal"  />
     <Reference Include="Microsoft.AspNetCore.DataProtection.Abstractions"  />
-    <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions"  />
     <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions"  />
+    <Reference Include="Microsoft.Extensions.Hosting.Abstractions"  />
     <Reference Include="Microsoft.Extensions.Logging.Abstractions"  />
     <Reference Include="Microsoft.Extensions.Options"  />
     <Reference Include="Microsoft.Win32.Registry"  />

+ 0 - 0
src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netcoreapp3.0.cs → src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netstandard2.0.cs


+ 2 - 2
src/DataProtection/DataProtection/src/DataProtectionServiceCollectionExtensions.cs

@@ -9,8 +9,8 @@ using Microsoft.AspNetCore.DataProtection.Internal;
 using Microsoft.AspNetCore.DataProtection.KeyManagement;
 using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
 using Microsoft.AspNetCore.DataProtection.XmlEncryption;
-using Microsoft.AspNetCore.Hosting;
 using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging.Abstractions;
 using Microsoft.Extensions.Options;
@@ -77,7 +77,7 @@ namespace Microsoft.Extensions.DependencyInjection
 
             services.TryAddSingleton<IKeyManager, XmlKeyManager>();
             services.TryAddSingleton<IApplicationDiscriminator, HostingApplicationDiscriminator>();
-            services.TryAddEnumerable(ServiceDescriptor.Singleton<IStartupFilter, DataProtectionStartupFilter>());
+            services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, DataProtectionHostedService>());
 
             // Internal services
             services.TryAddSingleton<IDefaultKeyResolver, DefaultKeyResolver>();

+ 13 - 10
src/DataProtection/DataProtection/src/Internal/DataProtectionStartupFilter.cs → src/DataProtection/DataProtection/src/Internal/DataProtectionHostedService.cs

@@ -1,31 +1,32 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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 Microsoft.AspNetCore.Builder;
+using System.Threading;
+using System.Threading.Tasks;
 using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
-using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging.Abstractions;
 
 namespace Microsoft.AspNetCore.DataProtection.Internal
 {
-    internal class DataProtectionStartupFilter : IStartupFilter
+    internal class DataProtectionHostedService : IHostedService
     {
         private readonly IKeyRingProvider _keyRingProvider;
-        private readonly ILogger<DataProtectionStartupFilter> _logger;
+        private readonly ILogger<DataProtectionHostedService> _logger;
 
-        public DataProtectionStartupFilter(IKeyRingProvider keyRingProvider)
+        public DataProtectionHostedService(IKeyRingProvider keyRingProvider)
             : this(keyRingProvider, NullLoggerFactory.Instance)
         { }
 
-        public DataProtectionStartupFilter(IKeyRingProvider keyRingProvider, ILoggerFactory loggerFactory)
+        public DataProtectionHostedService(IKeyRingProvider keyRingProvider, ILoggerFactory loggerFactory)
         {
             _keyRingProvider = keyRingProvider;
-            _logger = loggerFactory.CreateLogger<DataProtectionStartupFilter>();
+            _logger = loggerFactory.CreateLogger<DataProtectionHostedService>();
         }
 
-        public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
+        public Task StartAsync(CancellationToken token)
         {
             try
             {
@@ -42,7 +43,9 @@ namespace Microsoft.AspNetCore.DataProtection.Internal
                 _logger.KeyRingFailedToLoadOnStartup(ex);
             }
 
-            return next;
+            return Task.CompletedTask;
         }
+
+        public Task StopAsync(CancellationToken token) => Task.CompletedTask;
     }
 }

+ 4 - 2
src/DataProtection/DataProtection/src/Microsoft.AspNetCore.DataProtection.csproj

@@ -2,8 +2,9 @@
 
   <PropertyGroup>
     <Description>ASP.NET Core logic to protect and unprotect data, similar to DPAPI.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
+    <IsShippingPackage>true</IsShippingPackage>
     <NoWarn>$(NoWarn);CS1591</NoWarn>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
@@ -17,13 +18,14 @@
   <ItemGroup>
     <Reference Include="Microsoft.AspNetCore.Cryptography.Internal" />
     <Reference Include="Microsoft.AspNetCore.DataProtection.Abstractions" />
-    <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions" />
     <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
+    <Reference Include="Microsoft.Extensions.Hosting.Abstractions" />
     <Reference Include="Microsoft.Extensions.Logging.Abstractions" />
     <Reference Include="Microsoft.Extensions.Options" />
     <Reference Include="Microsoft.Win32.Registry" />
     <Reference Include="System.Security.Cryptography.Xml" />
     <Reference Include="System.Security.Principal.Windows" />
+    <SuppressBaselineReference Include="Microsoft.AspNetCore.Hosting.Abstractions" />
   </ItemGroup>
 
 </Project>

+ 30 - 2
src/DataProtection/DataProtection/test/HostingTests.cs

@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
 using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
 using Microsoft.AspNetCore.Hosting.Server;
 using Microsoft.AspNetCore.Http.Features;
 using Microsoft.AspNetCore.Testing;
@@ -20,7 +21,7 @@ namespace Microsoft.AspNetCore.DataProtection.Test
     public class HostingTests
     {
         [Fact]
-        public async Task LoadsKeyRingBeforeServerStarts()
+        public async Task WebhostLoadsKeyRingBeforeServerStarts()
         {
             var tcs = new TaskCompletionSource<object>();
             var mockKeyRing = new Mock<IKeyRingProvider>();
@@ -46,6 +47,33 @@ namespace Microsoft.AspNetCore.DataProtection.Test
             mockKeyRing.VerifyAll();
         }
 
+        [Fact]
+        public async Task GenericHostLoadsKeyRingBeforeServerStarts()
+        {
+            var tcs = new TaskCompletionSource<object>();
+            var mockKeyRing = new Mock<IKeyRingProvider>();
+            mockKeyRing.Setup(m => m.GetCurrentKeyRing())
+                .Returns(Mock.Of<IKeyRing>())
+                .Callback(() => tcs.TrySetResult(null));
+
+            var builder = new HostBuilder()
+                .ConfigureServices(s =>
+                    s.AddDataProtection()
+                    .Services
+                    .Replace(ServiceDescriptor.Singleton(mockKeyRing.Object))
+                    .AddSingleton<IServer>(
+                        new FakeServer(onStart: () => tcs.TrySetException(new InvalidOperationException("Server was started before key ring was initialized")))))
+                .ConfigureWebHost(b => b.UseStartup<TestStartup>());
+
+            using (var host = builder.Build())
+            {
+                await host.StartAsync();
+            }
+
+            await tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
+            mockKeyRing.VerifyAll();
+        }
+
         [Fact]
         public async Task StartupContinuesOnFailureToLoadKey()
         {

+ 2 - 1
src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <TargetFramework>netcoreapp3.0</TargetFramework>
@@ -15,6 +15,7 @@
     <Reference Include="Microsoft.AspNetCore.Cryptography.Internal" />
     <Reference Include="Microsoft.AspNetCore.DataProtection" />
     <Reference Include="Microsoft.Extensions.DependencyInjection" />
+    <Reference Include="Microsoft.Extensions.Hosting" />
   </ItemGroup>
 
 </Project>

+ 3 - 3
src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.1</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
+    <Compile Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netstandard2.1.cs" />
     <Reference Include="Microsoft.AspNetCore.DataProtection"  />
     <Reference Include="Microsoft.EntityFrameworkCore"  />
   </ItemGroup>

+ 0 - 0
src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netcoreapp3.0.cs → src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netstandard2.1.cs


+ 1 - 1
src/DataProtection/EntityFrameworkCore/src/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <Description>Support for storing keys using Entity Framework Core.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.1</TargetFramework>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection;entityframeworkcore</PackageTags>

+ 3 - 3
src/DataProtection/Extensions/ref/Microsoft.AspNetCore.DataProtection.Extensions.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.DataProtection.Extensions.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.DataProtection.Extensions.netstandard2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.DataProtection"  />
     <Reference Include="Microsoft.Extensions.DependencyInjection"  />
   </ItemGroup>

+ 0 - 0
src/DataProtection/Extensions/ref/Microsoft.AspNetCore.DataProtection.Extensions.netcoreapp3.0.cs → src/DataProtection/Extensions/ref/Microsoft.AspNetCore.DataProtection.Extensions.netstandard2.0.cs


+ 2 - 1
src/DataProtection/Extensions/src/Microsoft.AspNetCore.DataProtection.Extensions.csproj

@@ -2,8 +2,9 @@
 
   <PropertyGroup>
     <Description>Additional APIs for ASP.NET Core data protection.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
+    <IsShippingPackage>true</IsShippingPackage>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection</PackageTags>
   </PropertyGroup>

+ 3 - 3
src/DataProtection/StackExchangeRedis/ref/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis.netstandard2.0.cs" />
     <Reference Include="Microsoft.AspNetCore.DataProtection"  />
     <Reference Include="StackExchange.Redis"  />
   </ItemGroup>

+ 0 - 0
src/DataProtection/StackExchangeRedis/ref/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.netcoreapp3.0.cs → src/DataProtection/StackExchangeRedis/ref/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.netstandard2.0.cs


+ 1 - 1
src/DataProtection/StackExchangeRedis/src/Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <Description>Support for storing data protection keys in Redis.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection;redis</PackageTags>

+ 5 - 3
src/Hosting/Hosting/src/Internal/WebHost.cs

@@ -149,6 +149,10 @@ namespace Microsoft.AspNetCore.Hosting.Internal
 
             _applicationLifetime = _applicationServices.GetRequiredService<ApplicationLifetime>();
             _hostedServiceExecutor = _applicationServices.GetRequiredService<HostedServiceExecutor>();
+
+            // Fire IHostedService.Start
+            await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);
+
             var diagnosticSource = _applicationServices.GetRequiredService<DiagnosticListener>();
             var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
             var hostingApp = new HostingApplication(application, _logger, diagnosticSource, httpContextFactory);
@@ -158,8 +162,6 @@ namespace Microsoft.AspNetCore.Hosting.Internal
             // Fire IApplicationLifetime.Started
             _applicationLifetime?.NotifyStarted();
 
-            // Fire IHostedService.Start
-            await _hostedServiceExecutor.StartAsync(cancellationToken).ConfigureAwait(false);
 
             _logger.Started();
 
@@ -339,7 +341,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
             }
 
             // Fire the IHostedService.Stop
-            if (_hostedServiceExecutor != null && _startedServer)
+            if (_hostedServiceExecutor != null)
             {
                 await _hostedServiceExecutor.StopAsync(cancellationToken).ConfigureAwait(false);
             }

+ 2 - 2
src/Hosting/Hosting/test/WebHostTests.cs

@@ -702,8 +702,8 @@ namespace Microsoft.AspNetCore.Hosting
                 await Assert.ThrowsAsync<InvalidOperationException>(() => host.StartAsync());
                 Assert.True(hostedServiceCalls1[0]);
                 Assert.False(hostedServiceCalls2[0]);
-                Assert.True(started.All(s => s));
-                Assert.True(started2.All(s => s));
+                Assert.False(started.All(s => s)); // Server doesn't start if hosted services throw
+                Assert.False(started2.All(s => s));
                 host.Dispose();
                 Assert.True(hostedServiceCalls1[1]);
                 Assert.True(hostedServiceCalls2[1]);

+ 0 - 2
src/Identity/Core/ref/Microsoft.AspNetCore.Identity.csproj

@@ -6,8 +6,6 @@
   <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
     <Compile Include="Microsoft.AspNetCore.Identity.netcoreapp3.0.cs" />
     <Reference Include="Microsoft.AspNetCore.Authentication.Cookies"  />
-    <Reference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation"  />
-    <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions"  />
     <Reference Include="Microsoft.Extensions.Identity.Core"  />
   </ItemGroup>
 </Project>

+ 0 - 2
src/Identity/Core/src/Microsoft.AspNetCore.Identity.csproj

@@ -10,8 +10,6 @@
 
   <ItemGroup>
     <Reference Include="Microsoft.AspNetCore.Authentication.Cookies" />
-    <Reference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" />
-    <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions" />
     <Reference Include="Microsoft.Extensions.Identity.Core" />
   </ItemGroup>
 

+ 8 - 2
src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.csproj

@@ -1,9 +1,15 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.Extensions.Identity.Core.netstandard2.0.cs" />
+    <Reference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation"  />
+    <Reference Include="Microsoft.Extensions.Logging"  />
+    <Reference Include="Microsoft.Extensions.Options"  />
+  </ItemGroup>
+<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
     <Compile Include="Microsoft.Extensions.Identity.Core.netcoreapp3.0.cs" />
     <Reference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation"  />
     <Reference Include="Microsoft.Extensions.Logging"  />

+ 707 - 0
src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs

@@ -0,0 +1,707 @@
+// 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.
+
+namespace Microsoft.AspNetCore.Identity
+{
+    public partial class AuthenticatorTokenProvider<TUser> : Microsoft.AspNetCore.Identity.IUserTwoFactorTokenProvider<TUser> where TUser : class
+    {
+        public AuthenticatorTokenProvider() { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> CanGenerateTwoFactorTokenAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GenerateAsync(string purpose, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> ValidateAsync(string purpose, string token, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+    }
+    public partial class ClaimsIdentityOptions
+    {
+        public ClaimsIdentityOptions() { }
+        public string RoleClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string SecurityStampClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string UserIdClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string UserNameClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class DefaultPersonalDataProtector : Microsoft.AspNetCore.Identity.IPersonalDataProtector
+    {
+        public DefaultPersonalDataProtector(Microsoft.AspNetCore.Identity.ILookupProtectorKeyRing keyRing, Microsoft.AspNetCore.Identity.ILookupProtector protector) { }
+        public virtual string Protect(string data) { throw null; }
+        public virtual string Unprotect(string data) { throw null; }
+    }
+    public partial class DefaultUserConfirmation<TUser> : Microsoft.AspNetCore.Identity.IUserConfirmation<TUser> where TUser : class
+    {
+        public DefaultUserConfirmation() { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> IsConfirmedAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+    }
+    public partial class EmailTokenProvider<TUser> : Microsoft.AspNetCore.Identity.TotpSecurityStampBasedTokenProvider<TUser> where TUser : class
+    {
+        public EmailTokenProvider() { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public override System.Threading.Tasks.Task<bool> CanGenerateTwoFactorTokenAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public override System.Threading.Tasks.Task<string> GetUserModifierAsync(string purpose, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+    }
+    public partial class IdentityBuilder
+    {
+        public IdentityBuilder(System.Type user, Microsoft.Extensions.DependencyInjection.IServiceCollection services) { }
+        public IdentityBuilder(System.Type user, System.Type role, Microsoft.Extensions.DependencyInjection.IServiceCollection services) { }
+        public System.Type RoleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public System.Type UserType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddClaimsPrincipalFactory<TFactory>() where TFactory : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddErrorDescriber<TDescriber>() where TDescriber : Microsoft.AspNetCore.Identity.IdentityErrorDescriber { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddPasswordValidator<TValidator>() where TValidator : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddPersonalDataProtection<TProtector, TKeyRing>() where TProtector : class, Microsoft.AspNetCore.Identity.ILookupProtector where TKeyRing : class, Microsoft.AspNetCore.Identity.ILookupProtectorKeyRing { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddRoleManager<TRoleManager>() where TRoleManager : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddRoleStore<TStore>() where TStore : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddRoles<TRole>() where TRole : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddRoleValidator<TRole>() where TRole : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddTokenProvider(string providerName, System.Type provider) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddTokenProvider<TProvider>(string providerName) where TProvider : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserManager<TUserManager>() where TUserManager : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserStore<TStore>() where TStore : class { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserValidator<TValidator>() where TValidator : class { throw null; }
+    }
+    public partial class IdentityError
+    {
+        public IdentityError() { }
+        public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string Description { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class IdentityErrorDescriber
+    {
+        public IdentityErrorDescriber() { }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError ConcurrencyFailure() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError DefaultError() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError DuplicateEmail(string email) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError DuplicateRoleName(string role) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError DuplicateUserName(string userName) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError InvalidEmail(string email) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError InvalidRoleName(string role) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError InvalidToken() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError InvalidUserName(string userName) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError LoginAlreadyAssociated() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError PasswordMismatch() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError PasswordRequiresDigit() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError PasswordRequiresLower() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError PasswordRequiresNonAlphanumeric() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError PasswordRequiresUniqueChars(int uniqueChars) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError PasswordRequiresUpper() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError PasswordTooShort(int length) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError RecoveryCodeRedemptionFailed() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError UserAlreadyHasPassword() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError UserAlreadyInRole(string role) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError UserLockoutNotEnabled() { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.IdentityError UserNotInRole(string role) { throw null; }
+    }
+    public partial class IdentityOptions
+    {
+        public IdentityOptions() { }
+        public Microsoft.AspNetCore.Identity.ClaimsIdentityOptions ClaimsIdentity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.LockoutOptions Lockout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.PasswordOptions Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.SignInOptions SignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.StoreOptions Stores { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.TokenOptions Tokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.UserOptions User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class IdentityResult
+    {
+        public IdentityResult() { }
+        public System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Identity.IdentityError> Errors { get { throw null; } }
+        public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } }
+        public static Microsoft.AspNetCore.Identity.IdentityResult Success { get { throw null; } }
+        public static Microsoft.AspNetCore.Identity.IdentityResult Failed(params Microsoft.AspNetCore.Identity.IdentityError[] errors) { throw null; }
+        public override string ToString() { throw null; }
+    }
+    public partial interface ILookupNormalizer
+    {
+        string NormalizeEmail(string email);
+        string NormalizeName(string name);
+    }
+    public partial interface ILookupProtector
+    {
+        string Protect(string keyId, string data);
+        string Unprotect(string keyId, string data);
+    }
+    public partial interface ILookupProtectorKeyRing
+    {
+        string CurrentKeyId { get; }
+        string this[string keyId] { get; }
+        System.Collections.Generic.IEnumerable<string> GetAllKeyIds();
+    }
+    public partial interface IPasswordHasher<TUser> where TUser : class
+    {
+        string HashPassword(TUser user, string password);
+        Microsoft.AspNetCore.Identity.PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword);
+    }
+    public partial interface IPasswordValidator<TUser> where TUser : class
+    {
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user, string password);
+    }
+    public partial interface IPersonalDataProtector
+    {
+        string Protect(string data);
+        string Unprotect(string data);
+    }
+    public partial interface IProtectedUserStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+    }
+    public partial interface IQueryableRoleStore<TRole> : Microsoft.AspNetCore.Identity.IRoleStore<TRole>, System.IDisposable where TRole : class
+    {
+        System.Linq.IQueryable<TRole> Roles { get; }
+    }
+    public partial interface IQueryableUserStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Linq.IQueryable<TUser> Users { get; }
+    }
+    public partial interface IRoleClaimStore<TRole> : Microsoft.AspNetCore.Identity.IRoleStore<TRole>, System.IDisposable where TRole : class
+    {
+        System.Threading.Tasks.Task AddClaimAsync(TRole role, System.Security.Claims.Claim claim, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+        System.Threading.Tasks.Task<System.Collections.Generic.IList<System.Security.Claims.Claim>> GetClaimsAsync(TRole role, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+        System.Threading.Tasks.Task RemoveClaimAsync(TRole role, System.Security.Claims.Claim claim, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
+    }
+    public partial interface IRoleStore<TRole> : System.IDisposable where TRole : class
+    {
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> CreateAsync(TRole role, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> DeleteAsync(TRole role, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<TRole> FindByIdAsync(string roleId, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<TRole> FindByNameAsync(string normalizedRoleName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetNormalizedRoleNameAsync(TRole role, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetRoleIdAsync(TRole role, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetRoleNameAsync(TRole role, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetRoleNameAsync(TRole role, string roleName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdateAsync(TRole role, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IRoleValidator<TRole> where TRole : class
+    {
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateAsync(Microsoft.AspNetCore.Identity.RoleManager<TRole> manager, TRole role);
+    }
+    public partial interface IUserAuthenticationTokenStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<string> GetTokenAsync(TUser user, string loginProvider, string name, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task RemoveTokenAsync(TUser user, string loginProvider, string name, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetTokenAsync(TUser user, string loginProvider, string name, string value, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserAuthenticatorKeyStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<string> GetAuthenticatorKeyAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetAuthenticatorKeyAsync(TUser user, string key, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserClaimsPrincipalFactory<TUser> where TUser : class
+    {
+        System.Threading.Tasks.Task<System.Security.Claims.ClaimsPrincipal> CreateAsync(TUser user);
+    }
+    public partial interface IUserClaimStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task AddClaimsAsync(TUser user, System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<System.Collections.Generic.IList<System.Security.Claims.Claim>> GetClaimsAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<System.Collections.Generic.IList<TUser>> GetUsersForClaimAsync(System.Security.Claims.Claim claim, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task RemoveClaimsAsync(TUser user, System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task ReplaceClaimAsync(TUser user, System.Security.Claims.Claim claim, System.Security.Claims.Claim newClaim, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserConfirmation<TUser> where TUser : class
+    {
+        System.Threading.Tasks.Task<bool> IsConfirmedAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user);
+    }
+    public partial interface IUserEmailStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<TUser> FindByEmailAsync(string normalizedEmail, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetEmailAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<bool> GetEmailConfirmedAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetNormalizedEmailAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetEmailAsync(TUser user, string email, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetEmailConfirmedAsync(TUser user, bool confirmed, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserLockoutStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<int> GetAccessFailedCountAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<bool> GetLockoutEnabledAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<System.DateTimeOffset?> GetLockoutEndDateAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<int> IncrementAccessFailedCountAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task ResetAccessFailedCountAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetLockoutEnabledAsync(TUser user, bool enabled, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetLockoutEndDateAsync(TUser user, System.DateTimeOffset? lockoutEnd, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserLoginStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task AddLoginAsync(TUser user, Microsoft.AspNetCore.Identity.UserLoginInfo login, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<TUser> FindByLoginAsync(string loginProvider, string providerKey, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<System.Collections.Generic.IList<Microsoft.AspNetCore.Identity.UserLoginInfo>> GetLoginsAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserPasswordStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<string> GetPasswordHashAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<bool> HasPasswordAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetPasswordHashAsync(TUser user, string passwordHash, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserPhoneNumberStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<string> GetPhoneNumberAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<bool> GetPhoneNumberConfirmedAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetPhoneNumberAsync(TUser user, string phoneNumber, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserRoleStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task AddToRoleAsync(TUser user, string roleName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<System.Collections.Generic.IList<string>> GetRolesAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<System.Collections.Generic.IList<TUser>> GetUsersInRoleAsync(string roleName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<bool> IsInRoleAsync(TUser user, string roleName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task RemoveFromRoleAsync(TUser user, string roleName, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserSecurityStampStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<string> GetSecurityStampAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetSecurityStampAsync(TUser user, string stamp, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserStore<TUser> : System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> CreateAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> DeleteAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<TUser> FindByIdAsync(string userId, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<TUser> FindByNameAsync(string normalizedUserName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetNormalizedUserNameAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetUserIdAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<string> GetUserNameAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetNormalizedUserNameAsync(TUser user, string normalizedName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetUserNameAsync(TUser user, string userName, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdateAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserTwoFactorRecoveryCodeStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<int> CountCodesAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task<bool> RedeemCodeAsync(TUser user, string code, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task ReplaceCodesAsync(TUser user, System.Collections.Generic.IEnumerable<string> recoveryCodes, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserTwoFactorStore<TUser> : Microsoft.AspNetCore.Identity.IUserStore<TUser>, System.IDisposable where TUser : class
+    {
+        System.Threading.Tasks.Task<bool> GetTwoFactorEnabledAsync(TUser user, System.Threading.CancellationToken cancellationToken);
+        System.Threading.Tasks.Task SetTwoFactorEnabledAsync(TUser user, bool enabled, System.Threading.CancellationToken cancellationToken);
+    }
+    public partial interface IUserTwoFactorTokenProvider<TUser> where TUser : class
+    {
+        System.Threading.Tasks.Task<bool> CanGenerateTwoFactorTokenAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user);
+        System.Threading.Tasks.Task<string> GenerateAsync(string purpose, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user);
+        System.Threading.Tasks.Task<bool> ValidateAsync(string purpose, string token, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user);
+    }
+    public partial interface IUserValidator<TUser> where TUser : class
+    {
+        System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user);
+    }
+    public partial class LockoutOptions
+    {
+        public LockoutOptions() { }
+        public bool AllowedForNewUsers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.TimeSpan DefaultLockoutTimeSpan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public int MaxFailedAccessAttempts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public enum PasswordHasherCompatibilityMode
+    {
+        IdentityV2 = 0,
+        IdentityV3 = 1,
+    }
+    public partial class PasswordHasherOptions
+    {
+        public PasswordHasherOptions() { }
+        public Microsoft.AspNetCore.Identity.PasswordHasherCompatibilityMode CompatibilityMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public int IterationCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class PasswordHasher<TUser> : Microsoft.AspNetCore.Identity.IPasswordHasher<TUser> where TUser : class
+    {
+        public PasswordHasher(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.PasswordHasherOptions> optionsAccessor = null) { }
+        public virtual string HashPassword(TUser user, string password) { throw null; }
+        public virtual Microsoft.AspNetCore.Identity.PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword) { throw null; }
+    }
+    public partial class PasswordOptions
+    {
+        public PasswordOptions() { }
+        public bool RequireDigit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public int RequiredLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public int RequiredUniqueChars { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool RequireLowercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool RequireNonAlphanumeric { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool RequireUppercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class PasswordValidator<TUser> : Microsoft.AspNetCore.Identity.IPasswordValidator<TUser> where TUser : class
+    {
+        public PasswordValidator(Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors = null) { }
+        public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public virtual bool IsDigit(char c) { throw null; }
+        public virtual bool IsLetterOrDigit(char c) { throw null; }
+        public virtual bool IsLower(char c) { throw null; }
+        public virtual bool IsUpper(char c) { throw null; }
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user, string password) { throw null; }
+    }
+    public enum PasswordVerificationResult
+    {
+        Failed = 0,
+        Success = 1,
+        SuccessRehashNeeded = 2,
+    }
+    public partial class PersonalDataAttribute : System.Attribute
+    {
+        public PersonalDataAttribute() { }
+    }
+    public partial class PhoneNumberTokenProvider<TUser> : Microsoft.AspNetCore.Identity.TotpSecurityStampBasedTokenProvider<TUser> where TUser : class
+    {
+        public PhoneNumberTokenProvider() { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public override System.Threading.Tasks.Task<bool> CanGenerateTwoFactorTokenAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public override System.Threading.Tasks.Task<string> GetUserModifierAsync(string purpose, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+    }
+    public partial class ProtectedPersonalDataAttribute : Microsoft.AspNetCore.Identity.PersonalDataAttribute
+    {
+        public ProtectedPersonalDataAttribute() { }
+    }
+    public partial class RoleManager<TRole> : System.IDisposable where TRole : class
+    {
+        public RoleManager(Microsoft.AspNetCore.Identity.IRoleStore<TRole> store, System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Identity.IRoleValidator<TRole>> roleValidators, Microsoft.AspNetCore.Identity.ILookupNormalizer keyNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors, Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.Identity.RoleManager<TRole>> logger) { }
+        protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } }
+        public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public virtual System.Linq.IQueryable<TRole> Roles { get { throw null; } }
+        public System.Collections.Generic.IList<Microsoft.AspNetCore.Identity.IRoleValidator<TRole>> RoleValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        protected Microsoft.AspNetCore.Identity.IRoleStore<TRole> Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public virtual bool SupportsQueryableRoles { get { throw null; } }
+        public virtual bool SupportsRoleClaims { get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AddClaimAsync(TRole role, System.Security.Claims.Claim claim) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> CreateAsync(TRole role) { throw null; }
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> DeleteAsync(TRole role) { throw null; }
+        public void Dispose() { }
+        protected virtual void Dispose(bool disposing) { }
+        public virtual System.Threading.Tasks.Task<TRole> FindByIdAsync(string roleId) { throw null; }
+        public virtual System.Threading.Tasks.Task<TRole> FindByNameAsync(string roleName) { throw null; }
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IList<System.Security.Claims.Claim>> GetClaimsAsync(TRole role) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GetRoleIdAsync(TRole role) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GetRoleNameAsync(TRole role) { throw null; }
+        public virtual string NormalizeKey(string key) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemoveClaimAsync(TRole role, System.Security.Claims.Claim claim) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> RoleExistsAsync(string roleName) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetRoleNameAsync(TRole role, string name) { throw null; }
+        protected void ThrowIfDisposed() { }
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdateAsync(TRole role) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task UpdateNormalizedRoleNameAsync(TRole role) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdateRoleAsync(TRole role) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateRoleAsync(TRole role) { throw null; }
+    }
+    public partial class RoleValidator<TRole> : Microsoft.AspNetCore.Identity.IRoleValidator<TRole> where TRole : class
+    {
+        public RoleValidator(Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors = null) { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateAsync(Microsoft.AspNetCore.Identity.RoleManager<TRole> manager, TRole role) { throw null; }
+    }
+    public partial class SignInOptions
+    {
+        public SignInOptions() { }
+        public bool RequireConfirmedAccount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool RequireConfirmedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool RequireConfirmedPhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class SignInResult
+    {
+        public SignInResult() { }
+        public static Microsoft.AspNetCore.Identity.SignInResult Failed { get { throw null; } }
+        public bool IsLockedOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } }
+        public bool IsNotAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } }
+        public static Microsoft.AspNetCore.Identity.SignInResult LockedOut { get { throw null; } }
+        public static Microsoft.AspNetCore.Identity.SignInResult NotAllowed { get { throw null; } }
+        public bool RequiresTwoFactor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } }
+        public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } }
+        public static Microsoft.AspNetCore.Identity.SignInResult Success { get { throw null; } }
+        public static Microsoft.AspNetCore.Identity.SignInResult TwoFactorRequired { get { throw null; } }
+        public override string ToString() { throw null; }
+    }
+    public partial class StoreOptions
+    {
+        public StoreOptions() { }
+        public int MaxLengthForKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool ProtectPersonalData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class TokenOptions
+    {
+        public static readonly string DefaultAuthenticatorProvider;
+        public static readonly string DefaultEmailProvider;
+        public static readonly string DefaultPhoneProvider;
+        public static readonly string DefaultProvider;
+        public TokenOptions() { }
+        public string AuthenticatorIssuer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string AuthenticatorTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string ChangeEmailTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string ChangePhoneNumberTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string EmailConfirmationTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string PasswordResetTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Collections.Generic.Dictionary<string, Microsoft.AspNetCore.Identity.TokenProviderDescriptor> ProviderMap { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class TokenProviderDescriptor
+    {
+        public TokenProviderDescriptor(System.Type type) { }
+        public object ProviderInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Type ProviderType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+    }
+    public abstract partial class TotpSecurityStampBasedTokenProvider<TUser> : Microsoft.AspNetCore.Identity.IUserTwoFactorTokenProvider<TUser> where TUser : class
+    {
+        protected TotpSecurityStampBasedTokenProvider() { }
+        public abstract System.Threading.Tasks.Task<bool> CanGenerateTwoFactorTokenAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user);
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<string> GenerateAsync(string purpose, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<string> GetUserModifierAsync(string purpose, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> ValidateAsync(string purpose, string token, Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+    }
+    public sealed partial class UpperInvariantLookupNormalizer : Microsoft.AspNetCore.Identity.ILookupNormalizer
+    {
+        public UpperInvariantLookupNormalizer() { }
+        public string NormalizeEmail(string email) { throw null; }
+        public string NormalizeName(string name) { throw null; }
+    }
+    public partial class UserClaimsPrincipalFactory<TUser> : Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory<TUser> where TUser : class
+    {
+        public UserClaimsPrincipalFactory(Microsoft.AspNetCore.Identity.UserManager<TUser> userManager, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.IdentityOptions> optionsAccessor) { }
+        public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        public Microsoft.AspNetCore.Identity.UserManager<TUser> UserManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<System.Security.Claims.ClaimsPrincipal> CreateAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected virtual System.Threading.Tasks.Task<System.Security.Claims.ClaimsIdentity> GenerateClaimsAsync(TUser user) { throw null; }
+    }
+    public partial class UserClaimsPrincipalFactory<TUser, TRole> : Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory<TUser> where TUser : class where TRole : class
+    {
+        public UserClaimsPrincipalFactory(Microsoft.AspNetCore.Identity.UserManager<TUser> userManager, Microsoft.AspNetCore.Identity.RoleManager<TRole> roleManager, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.IdentityOptions> options) : base (default(Microsoft.AspNetCore.Identity.UserManager<TUser>), default(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.IdentityOptions>)) { }
+        public Microsoft.AspNetCore.Identity.RoleManager<TRole> RoleManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected override System.Threading.Tasks.Task<System.Security.Claims.ClaimsIdentity> GenerateClaimsAsync(TUser user) { throw null; }
+    }
+    public partial class UserLoginInfo
+    {
+        public UserLoginInfo(string loginProvider, string providerKey, string displayName) { }
+        public string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class UserManager<TUser> : System.IDisposable where TUser : class
+    {
+        public const string ChangePhoneNumberTokenPurpose = "ChangePhoneNumber";
+        public const string ConfirmEmailTokenPurpose = "EmailConfirmation";
+        public const string ResetPasswordTokenPurpose = "ResetPassword";
+        public UserManager(Microsoft.AspNetCore.Identity.IUserStore<TUser> store, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.IdentityOptions> optionsAccessor, Microsoft.AspNetCore.Identity.IPasswordHasher<TUser> passwordHasher, System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Identity.IUserValidator<TUser>> userValidators, System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Identity.IPasswordValidator<TUser>> passwordValidators, Microsoft.AspNetCore.Identity.ILookupNormalizer keyNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors, System.IServiceProvider services, Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.Identity.UserManager<TUser>> logger) { }
+        protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } }
+        public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public Microsoft.AspNetCore.Identity.IPasswordHasher<TUser> PasswordHasher { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public System.Collections.Generic.IList<Microsoft.AspNetCore.Identity.IPasswordValidator<TUser>> PasswordValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        protected internal Microsoft.AspNetCore.Identity.IUserStore<TUser> Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public virtual bool SupportsQueryableUsers { get { throw null; } }
+        public virtual bool SupportsUserAuthenticationTokens { get { throw null; } }
+        public virtual bool SupportsUserAuthenticatorKey { get { throw null; } }
+        public virtual bool SupportsUserClaim { get { throw null; } }
+        public virtual bool SupportsUserEmail { get { throw null; } }
+        public virtual bool SupportsUserLockout { get { throw null; } }
+        public virtual bool SupportsUserLogin { get { throw null; } }
+        public virtual bool SupportsUserPassword { get { throw null; } }
+        public virtual bool SupportsUserPhoneNumber { get { throw null; } }
+        public virtual bool SupportsUserRole { get { throw null; } }
+        public virtual bool SupportsUserSecurityStamp { get { throw null; } }
+        public virtual bool SupportsUserTwoFactor { get { throw null; } }
+        public virtual bool SupportsUserTwoFactorRecoveryCodes { get { throw null; } }
+        public virtual System.Linq.IQueryable<TUser> Users { get { throw null; } }
+        public System.Collections.Generic.IList<Microsoft.AspNetCore.Identity.IUserValidator<TUser>> UserValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AccessFailedAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AddClaimAsync(TUser user, System.Security.Claims.Claim claim) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AddClaimsAsync(TUser user, System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AddLoginAsync(TUser user, Microsoft.AspNetCore.Identity.UserLoginInfo login) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AddPasswordAsync(TUser user, string password) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AddToRoleAsync(TUser user, string role) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> AddToRolesAsync(TUser user, System.Collections.Generic.IEnumerable<string> roles) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ChangeEmailAsync(TUser user, string newEmail, string token) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ChangePasswordAsync(TUser user, string currentPassword, string newPassword) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ChangePhoneNumberAsync(TUser user, string phoneNumber, string token) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> CheckPasswordAsync(TUser user, string password) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ConfirmEmailAsync(TUser user, string token) { throw null; }
+        public virtual System.Threading.Tasks.Task<int> CountRecoveryCodesAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> CreateAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> CreateAsync(TUser user, string password) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<byte[]> CreateSecurityTokenAsync(TUser user) { throw null; }
+        protected virtual string CreateTwoFactorRecoveryCode() { throw null; }
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> DeleteAsync(TUser user) { throw null; }
+        public void Dispose() { }
+        protected virtual void Dispose(bool disposing) { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<TUser> FindByEmailAsync(string email) { throw null; }
+        public virtual System.Threading.Tasks.Task<TUser> FindByIdAsync(string userId) { throw null; }
+        public virtual System.Threading.Tasks.Task<TUser> FindByLoginAsync(string loginProvider, string providerKey) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<TUser> FindByNameAsync(string userName) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GenerateChangeEmailTokenAsync(TUser user, string newEmail) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GenerateChangePhoneNumberTokenAsync(TUser user, string phoneNumber) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GenerateConcurrencyStampAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GenerateEmailConfirmationTokenAsync(TUser user) { throw null; }
+        public virtual string GenerateNewAuthenticatorKey() { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<string>> GenerateNewTwoFactorRecoveryCodesAsync(TUser user, int number) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GeneratePasswordResetTokenAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GenerateTwoFactorTokenAsync(TUser user, string tokenProvider) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GenerateUserTokenAsync(TUser user, string tokenProvider, string purpose) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<int> GetAccessFailedCountAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GetAuthenticationTokenAsync(TUser user, string loginProvider, string tokenName) { throw null; }
+        public virtual System.Threading.Tasks.Task<string> GetAuthenticatorKeyAsync(TUser user) { throw null; }
+        protected static string GetChangeEmailTokenPurpose(string newEmail) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IList<System.Security.Claims.Claim>> GetClaimsAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<string> GetEmailAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> GetLockoutEnabledAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<System.DateTimeOffset?> GetLockoutEndDateAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IList<Microsoft.AspNetCore.Identity.UserLoginInfo>> GetLoginsAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<string> GetPhoneNumberAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IList<string>> GetRolesAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<string> GetSecurityStampAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> GetTwoFactorEnabledAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<TUser> GetUserAsync(System.Security.Claims.ClaimsPrincipal principal) { throw null; }
+        public virtual string GetUserId(System.Security.Claims.ClaimsPrincipal principal) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<string> GetUserIdAsync(TUser user) { throw null; }
+        public virtual string GetUserName(System.Security.Claims.ClaimsPrincipal principal) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<string> GetUserNameAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IList<TUser>> GetUsersForClaimAsync(System.Security.Claims.Claim claim) { throw null; }
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IList<TUser>> GetUsersInRoleAsync(string roleName) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<System.Collections.Generic.IList<string>> GetValidTwoFactorProvidersAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<bool> HasPasswordAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> IsEmailConfirmedAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> IsInRoleAsync(TUser user, string role) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> IsLockedOutAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<bool> IsPhoneNumberConfirmedAsync(TUser user) { throw null; }
+        public virtual string NormalizeEmail(string email) { throw null; }
+        public virtual string NormalizeName(string name) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RedeemTwoFactorRecoveryCodeAsync(TUser user, string code) { throw null; }
+        public virtual void RegisterTokenProvider(string providerName, Microsoft.AspNetCore.Identity.IUserTwoFactorTokenProvider<TUser> provider) { }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemoveAuthenticationTokenAsync(TUser user, string loginProvider, string tokenName) { throw null; }
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemoveClaimAsync(TUser user, System.Security.Claims.Claim claim) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemoveClaimsAsync(TUser user, System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemoveFromRoleAsync(TUser user, string role) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemoveFromRolesAsync(TUser user, System.Collections.Generic.IEnumerable<string> roles) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemoveLoginAsync(TUser user, string loginProvider, string providerKey) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> RemovePasswordAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ReplaceClaimAsync(TUser user, System.Security.Claims.Claim claim, System.Security.Claims.Claim newClaim) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ResetAccessFailedCountAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ResetAuthenticatorKeyAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ResetPasswordAsync(TUser user, string token, string newPassword) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetAuthenticationTokenAsync(TUser user, string loginProvider, string tokenName, string tokenValue) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetEmailAsync(TUser user, string email) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetLockoutEnabledAsync(TUser user, bool enabled) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetLockoutEndDateAsync(TUser user, System.DateTimeOffset? lockoutEnd) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetPhoneNumberAsync(TUser user, string phoneNumber) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetTwoFactorEnabledAsync(TUser user, bool enabled) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> SetUserNameAsync(TUser user, string userName) { throw null; }
+        protected void ThrowIfDisposed() { }
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdateAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task UpdateNormalizedEmailAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task UpdateNormalizedUserNameAsync(TUser user) { throw null; }
+        protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdatePasswordHash(TUser user, string newPassword, bool validatePassword) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdateSecurityStampAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> UpdateUserAsync(TUser user) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidatePasswordAsync(TUser user, string password) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateUserAsync(TUser user) { throw null; }
+        public virtual System.Threading.Tasks.Task<bool> VerifyChangePhoneNumberTokenAsync(TUser user, string token, string phoneNumber) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.PasswordVerificationResult> VerifyPasswordAsync(Microsoft.AspNetCore.Identity.IUserPasswordStore<TUser> store, TUser user, string password) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> VerifyTwoFactorTokenAsync(TUser user, string tokenProvider, string token) { throw null; }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<bool> VerifyUserTokenAsync(TUser user, string tokenProvider, string purpose, string token) { throw null; }
+    }
+    public partial class UserOptions
+    {
+        public UserOptions() { }
+        public string AllowedUserNameCharacters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+        public bool RequireUniqueEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
+    }
+    public partial class UserValidator<TUser> : Microsoft.AspNetCore.Identity.IUserValidator<TUser> where TUser : class
+    {
+        public UserValidator(Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors = null) { }
+        public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+        [System.Diagnostics.DebuggerStepThroughAttribute]
+        public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Identity.IdentityResult> ValidateAsync(Microsoft.AspNetCore.Identity.UserManager<TUser> manager, TUser user) { throw null; }
+    }
+}
+namespace Microsoft.Extensions.DependencyInjection
+{
+    public static partial class IdentityServiceCollectionExtensions
+    {
+        public static Microsoft.AspNetCore.Identity.IdentityBuilder AddIdentityCore<TUser>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TUser : class { throw null; }
+        public static Microsoft.AspNetCore.Identity.IdentityBuilder AddIdentityCore<TUser>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<Microsoft.AspNetCore.Identity.IdentityOptions> setupAction) where TUser : class { throw null; }
+    }
+}
+namespace System.Security.Claims
+{
+    public static partial class PrincipalExtensions
+    {
+        public static string FindFirstValue(this System.Security.Claims.ClaimsPrincipal principal, string claimType) { throw null; }
+    }
+}

+ 3 - 1
src/Identity/Extensions.Core/src/Microsoft.Extensions.Identity.Core.csproj

@@ -2,8 +2,9 @@
 
   <PropertyGroup>
     <Description>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.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
+    <IsShippingPackage>true</IsShippingPackage>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;identity;membership</PackageTags>
   </PropertyGroup>
@@ -12,6 +13,7 @@
     <Reference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" />
     <Reference Include="Microsoft.Extensions.Logging" />
     <Reference Include="Microsoft.Extensions.Options" />
+    <SuppressBaselineReference Include="System.ComponentModel.Annotations" />
   </ItemGroup>
 
 </Project>

+ 34 - 0
src/Identity/Extensions.Core/src/PasswordHasher.cs

@@ -65,6 +65,28 @@ namespace Microsoft.AspNetCore.Identity
             _rng = options.Rng;
         }
 
+#if NETSTANDARD2_0
+        // Compares two byte arrays for equality. The method is specifically written so that the loop is not optimized.
+        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
+        private static bool ByteArraysEqual(byte[] a, byte[] b)
+        {
+            if (a == null && b == null)
+            {
+                return true;
+            }
+            if (a == null || b == null || a.Length != b.Length)
+            {
+                return false;
+            }
+            var areSame = true;
+            for (var i = 0; i < a.Length; i++)
+            {
+                areSame &= (a[i] == b[i]);
+            }
+            return areSame;
+        }
+#endif
+
         /// <summary>
         /// Returns a hashed representation of the supplied <paramref name="password"/> for the specified <paramref name="user"/>.
         /// </summary>
@@ -222,7 +244,13 @@ namespace Microsoft.AspNetCore.Identity
 
             // Hash the incoming password and verify it
             byte[] actualSubkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength);
+#if NETSTANDARD2_0
+            return ByteArraysEqual(actualSubkey, expectedSubkey);
+#elif NETCOREAPP3_0
             return CryptographicOperations.FixedTimeEquals(actualSubkey, expectedSubkey);
+#else
+#error Update target frameworks
+#endif
         }
 
         private static bool VerifyHashedPasswordV3(byte[] hashedPassword, string password, out int iterCount)
@@ -255,7 +283,13 @@ namespace Microsoft.AspNetCore.Identity
 
                 // Hash the incoming password and verify it
                 byte[] actualSubkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, subkeyLength);
+#if NETSTANDARD2_0
+                return ByteArraysEqual(actualSubkey, expectedSubkey);
+#elif NETCOREAPP3_0
                 return CryptographicOperations.FixedTimeEquals(actualSubkey, expectedSubkey);
+#else
+#error Update target frameworks
+#endif
             }
             catch
             {

+ 3 - 3
src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.csproj

@@ -1,10 +1,10 @@
 <!-- This file is automatically generated. -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>netcoreapp3.0</TargetFrameworks>
+    <TargetFrameworks>netstandard2.0</TargetFrameworks>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <Compile Include="Microsoft.Extensions.Identity.Stores.netcoreapp3.0.cs" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+    <Compile Include="Microsoft.Extensions.Identity.Stores.netstandard2.0.cs" />
     <Reference Include="Microsoft.Extensions.Logging"  />
     <Reference Include="Microsoft.Extensions.Identity.Core"  />
   </ItemGroup>

+ 0 - 0
src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netcoreapp3.0.cs → src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netstandard2.0.cs


+ 3 - 1
src/Identity/Extensions.Stores/src/Microsoft.Extensions.Identity.Stores.csproj

@@ -2,8 +2,9 @@
 
   <PropertyGroup>
     <Description>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.</Description>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <IsAspNetCoreApp>true</IsAspNetCoreApp>
+    <IsShippingPackage>true</IsShippingPackage>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;identity;membership</PackageTags>
   </PropertyGroup>
@@ -11,6 +12,7 @@
   <ItemGroup>
     <Reference Include="Microsoft.Extensions.Logging" />
     <Reference Include="Microsoft.Extensions.Identity.Core" />
+    <SuppressBaselineReference Include="System.ComponentModel.Annotations" />
   </ItemGroup>
 
 </Project>

+ 2 - 0
src/Shared/WebEncoders/WebEncoders.cs

@@ -2,7 +2,9 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+#if NETCOREAPP3_0
 using System.Buffers;
+#endif
 using System.Diagnostics;
 using System.Globalization;
 using Microsoft.Extensions.WebEncoders.Sources;