C# ASP.NET标识提供程序SignInManager不断返回失败

C# ASP.NET标识提供程序SignInManager不断返回失败,c#,asp.net,asp.net-identity,C#,Asp.net,Asp.net Identity,我对MVC5的标准ASP身份提供程序有问题。一旦我登录该方法: await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); 不断返回失败。因此,我开始调试,使用: UserManager.FindByEmail(model.Email); 这将为尝试登录的用户返回有效的用户ID。 然后我用了: SignInManager.UserMa

我对MVC5的标准ASP身份提供程序有问题。一旦我登录该方法:

await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
不断返回失败。因此,我开始调试,使用:

UserManager.FindByEmail(model.Email);
这将为尝试登录的用户返回有效的用户ID。 然后我用了:

SignInManager.UserManager.CheckPassword(UserIDObtainedFromFind, model.Password);
这将返回true,这意味着我提供的密码是有效的


关于如何跟踪调试SignInManager.PasswordSignInAsync方法以查看失败的地方,有什么想法吗?

SignInManager.PasswordSignIn使用用户名,您应该仔细检查用户名是否与您发送的电子邮件相同。

如果
用户名!=电子邮件

ApplicationUser signedUser = UserManager.FindByEmail(model.Email);
var result = await SignInManager.PasswordSignInAsync(signedUser.UserName, model.Password, model.RememberMe, shouldLockout: false);
ApplicationUser signedUser = UserManager.FindByEmail(model.Email);
var result = await SignInManager.PasswordSignInAsync(signedUser.UserName, model.Password, model.RememberMe, shouldLockout: false);

对我来说,我发现使用SQL Profiler查看PasswordSignInAsync调用的查询很有帮助。在我的例子中,我注意到它试图找到一个鉴别器设置为“UserContext”的用户。这当然对我不起作用,因为我是从ASP.NET会员服务升级的,并且该鉴别器设置为User。由于新代码使用实体框架,因此该值似乎是从用户使用的类派生的。一个快速更新声明修复了这个问题

UPDATE AspNetUsers SET Discriminator = 'UserContext' WHERE Discriminator = 'User'
这是我的工作


这对我有效,因为我的用户名不等于我的电子邮件。您的电子邮件和用户名应该相同

现在有点老了,但这是我对这个问题的看法

我在一个实用程序中创建了一些静态数据,以确保身份数据库中存在一些标准内容(角色和管理员帐户)

我正在创建实体,并直接与上下文对话,以创建任何缺少的角色或该用户。我遇到的问题是没有设置
NormalizedUserName
NormalizedEmail
字段。我只是简单地设置了
电子邮件
用户名

我使用的最后一个代码(EF Core 2.x)类似于:

        if (!_context.Users.Any(_ => _.Id.Equals(Users.AdministratorId)))
        {
            var user = new ApplicationUser
            {
                Id = Users.AdministratorId,
                UserName = Users.AdministratorEmail,
                Email = Users.AdministratorEmail,
                EmailConfirmed = true,
                NormalizedEmail = Users.AdministratorEmail.ToUpper(),
                NormalizedUserName = Users.AdministratorEmail.ToUpper(),
                SecurityStamp = Guid.NewGuid().ToString()
            };

            var hasher = new PasswordHasher<ApplicationUser>();
            user.PasswordHash = hasher.HashPassword(user, "our_password");

            _context.Users.Add(user);
        }
if(!\u context.Users.Any(\u=>\ u.Id.Equals(Users.AdministratorId)))
{
var user=新应用程序用户
{
Id=Users.AdministratorId,
用户名=Users.AdministratorEmail,
电子邮件=Users.AdministratorEmail,
emailconfirm=true,
normalizedMail=Users.AdministratorEmail.ToUpper(),
NormalizedUserName=Users.AdministratorEmail.ToUpper(),
SecurityStamp=Guid.NewGuid().ToString()
};
var hasher=new PasswordHasher();
user.PasswordHash=hasher.HashPassword(用户,“我们的密码”);
_context.Users.Add(用户);
}
在启动检查中:

options.SignIn.RequireConfirmedEmail = false;
options.SignIn.RequireConfirmedPhoneNumber = false;

如果这些设置为true,您需要确认电子邮件或电话号码,然后才能登录。

如果以上任何一项都不是问题的原因(在我的情况下,问题是我自己的IUserStore实现中的复制粘贴错误),并回答您的问题“关于如何跟踪或调试SignInManager.PasswordSignInAsync方法以查看失败的地方,有什么想法吗?”,调试方法之一是将SignInManager.PasswordSignInAsync方法的内容复制到您自己的派生类(ApplicationSignInManager)中


如果您使用的是MVC5或更低版本,您可以在中找到源代码。

也许我的经验可以帮助某些人。 在我的例子中,问题是我更改了计算机,在新的Windows 10中安装了IIS功能,但没有安装ASP.NET功能


在我的情况下,相同的探针验证电子邮件和密码,电子邮件与我的用户相同

var userDO=\u userManager.findbyemailsync(Input.Email).Result;
var validator=\u userManager.CheckPasswordAsync(userDO,Input.Password);
电子邮件=用户名

真实结果

然后我检查了数据库,发现没有工作的用户的验证字段为false

然后必须在startup.cs中验证验证参数

public void配置服务(servicecolection服务)
{
//......
services.AddDefaultIdentity(options=>options.SignIn.RequireConfirmedAccount=false)
.AddRoles()
.AddEntityFrameworkStores

上述属性设置获取或设置一个标志,指示是否需要已确认的IUserConfirmation帐户登录

options.SignIn.RequireConfirmedEmail=false;
options.SignIn.RequireConfirmedPhoneNumber=false;

再见!

好的,你说对了。我用我的用户名字段来存储用户的用户名。还原它并添加一个用户名字段解决了我的问题。谢谢!你也应该还原NormalizedUserName,如果你手动操作的话,就像我提到的那样,手动添加更改用户名字段仍然会导致失败和错误e NormalizedUserName也必须更改才能使此修复生效。@MatthewFlynn说得好。你完全正确!即使对于.NET CORE 2.0,你的观察也会产生很大的差异。你就是那个人!发布代码时请使用正确的格式。你可以使用{}输入字段上方的按钮。有助于更好的可读性。将我的用户名更改为不再是电子邮件,并在登录失败时被卡住了一段时间,谢谢。只需向其他人指出,也可以将SignInStatus内var UserID中的“model.email”更改。成功案例为“signedUser.username”"太+1了,因为提到分析器,已经多年没有使用它了,忘记了它,但它正是我所需要的。谢谢!谢谢。我能够看到它是在查询默认表而不是自定义表。我使用了错误的连接字符串:)),以防有人像我一样!@Reza,至少不在这里,因为他能够获取<代码>的数据>FindByEmail
检查密码
options.SignIn.RequireConfirmedEmail = false;
options.SignIn.RequireConfirmedPhoneNumber = false;