SignInManager.PasswordSignInAsync 总是返回失败

pdu*_*ube 3 asp.net-mvc asp.net-identity asp.net-core-2.0

将我的应用程序从 .NET Framework 4.6 转换为 .NET Core 2 后,我对数据库进行了请求的更改以支持新的身份模型,即添加到 AspNetUsers 和新表的几个字段。

日志记录在 .NET Core 中工作正常。

现在我需要回到 .NET Framework 4.6 应用程序,当我尝试登录时,SignInManager.PasswordSignInAsync 总是返回失败。我使用 SQL Profiler 检查了查询,我看不到任何错误的查询(运行的任何查询都没有错误)。

CREATE TABLE [dbo].[AspNetUsers](
    [Id] [nvarchar](128) NOT NULL,
    [UserKeyId] [bigint] NOT NULL,
    [Email] [nvarchar](256) NULL,
    [EmailConfirmed] [bit] NOT NULL,
    [PasswordHash] [nvarchar](max) NULL,
    [SecurityStamp] [nvarchar](max) NULL,
    [PhoneNumber] [nvarchar](max) NULL,
    [PhoneNumberConfirmed] [bit] NOT NULL,
    [TwoFactorEnabled] [bit] NOT NULL,
    [LockoutEndDateUtc] [datetime] NULL,
    [LockoutEnabled] [bit] NOT NULL,
    [AccessFailedCount] [int] NOT NULL,
    [UserName] [nvarchar](256) NOT NULL,
    [CreationDate] [datetimeoffset](7) NOT NULL DEFAULT ('1900-01-01T00:00:00.000'),
    [FirstName] [nvarchar](max) NULL,
    [LastName] [nvarchar](max) NULL,
    [NormalizedEmail] [nvarchar](256) NULL,
    [NormalizedUserName] [nvarchar](256) NULL,
    [ConcurrencyStamp] [nvarchar](max) NULL,
    [LockoutEnd] [datetimeoffset](7) NULL,
 CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

失败的地方(即结果 = SignInStatus.Failure):

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);
Run Code Online (Sandbox Code Playgroud)

在 AspNetUsers 表中:电子邮件 = 用户名

我认为我不需要回滚对数据库所做的更改,那么如何找出 PasswordSignInAsync 返回失败的确切原因?

pdu*_*ube 7

问题出在哈希上。我在 .NET Framework 4.6 中的旧应用程序使用的是 Identity 2.0。当我将我的应用程序转换为 .NET Core 2 时,我实际上创建了一个新项目并逐个文件迁移代码,因此它使用了更强大的 Identity 3.0。作为一个不太好的功能,当您登录时会重写散列,因此密码散列是用 Identity 3.0 重写的,我的旧应用程序无法解码。

但是,您可以选择设置 .NET Core 以阻止使用 Identity 3.0。

你只需要在 Startup.cs 的 ConfigureServices 添加这一行:

services.Configure<PasswordHasherOptions>(options =>
    options.CompatibilityMode = PasswordHasherCompatibilityMode.IdentityV2
);
Run Code Online (Sandbox Code Playgroud)