.net核心标识,有意义的登录失败原因

时间:2018-09-17 08:08:25

标签: c# asp.net-core asp.net-core-identity

登录失败时,我想知道它是用户名,密码还是其他名称。

var signinResult = await _signInManager.PasswordSignInAsync(
    loginViewModel.UserName,
    loginViewModel.Password,
    false, false);

返回SignInResult,它仅告诉我它未被允许。

我能以某种方式从身份中获得更有意义的理由吗?

3 个答案:

答案 0 :(得分:3)

NotAllowed表示电子邮件或电话号码尚未确认(需要确认)。您可以使用类似以下的内容(假设您有一个来自DI的UserManager实例)对此进行显式检查:

await _userManager.IsEmailConfirmedAsync(user);
await _userManager.IsPhoneNumberConfirmedAsync(user);

要使用这两个功能中的任何一个,您需要user,可以像这样获得:

var user = await _userManager.FindByNameAsync(loginViewModel.UserName);

为了确定是用户名还是密码失败,您需要首先检查IsLockedOutIsNotAllowedRequiresTwoFactor。如果所有这些都返回false,则用户名或密码不正确。为了确定其中哪个是问题,可以检查await _userManager.FindByNameAsync(user)的返回值。这是一个完整的示例:

var signinResult = await _signInManager.PasswordSignInAsync(
    loginViewModel.UserName,
    loginViewModel.Password,
    false, false);

var user = await _userManager.FindByNameAsync(loginViewModel.UserName);

if (signinResult.IsNotAllowed)
{
    if (!await _userManager.IsEmailConfirmedAsync(user))
    {
        // Email isn't confirmed.
    }

    if (!await _userManager.IsPhoneNumberConfirmedAsync(user))
    {
        // Phone Number isn't confirmed.
    }
}
else if (signinResult.IsLockedOut)
{
    // Account is locked out.
}
else if (signinResult.RequiresTwoFactor)
{
    // 2FA required.
}
else
{
    // Username or password is incorrect.
    if (user == null)
    {
        // Username is incorrect.
    }
    else
    {
        // Password is incorrect.
    }
}

答案 1 :(得分:1)

PasswordSignInAsync仅在用户名/密码不正确时返回一般失败。这是因为首先您真的不应该公开哪个错误。如果您明确告诉最终用户密码错误,那么他们现在知道用户名是好的。如果这是恶意用户,则您的工作量减少了一半。现在,他们可以暴力破解密码。

但是,如果您确实需要此信息,只需尝试首先通过用户名获取用户:

var user = await _userManager.FindByNameAsync(loginViewModel.UserName);
if (user == null)
{
    // username is invalid
}

// Now attempt to login with password.

答案 2 :(得分:0)

就我而言,这是最愚蠢的原因之一,我给管理员用户添加了种子,却忘记将EmailConfirmed标记为true,并且在services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)方法中使用了ConfigureServices。 确保您在登录时不需要确认帐户,或者您要登录的用户的电子邮件已确认。