.net 核心身份,获得有意义的登录失败原因
.net core Identity, getting meaningful login failed reason
当登录失败时,我想知道是用户名、密码还是其他问题。
var signinResult = await _signInManager.PasswordSignInAsync(
loginViewModel.UserName,
loginViewModel.Password,
false, false);
returns SignInResult 只是告诉我这是 NotAllowed。
我能从身份中得到更有意义的理由吗?
NotAllowed
表示电子邮件或 Phone 号码尚未确认(需要确认)。你可以用类似下面的东西明确地检查这个(假设你有一个来自 DI 的 UserManager
实例):
await _userManager.IsEmailConfirmedAsync(user);
await _userManager.IsPhoneNumberConfirmedAsync(user);
要使用这两个函数中的任何一个,您需要 user
:
var user = await _userManager.FindByNameAsync(loginViewModel.UserName);
要确定是用户名还是密码失败,您需要先检查 IsLockedOut
、IsNotAllowed
和 RequiresTwoFactor
。如果所有这些 return false
,则用户名或密码不正确。为了确定其中哪一个是问题所在,您可以检查 await _userManager.FindByNameAsync(user)
中的 return 值。这是一个完整的例子:
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.
}
}
如果 username/password 不正确,PasswordSignInAsync
returns 只是一般性故障。这是因为您真的不应该首先揭露错误。如果您明确告诉最终用户密码错误,那么他们现在就知道用户名是正确的。如果这是一个恶意用户,你已经减半了他们的工作。现在他们可以暴力破解密码了。
不过,如果您确实需要此信息,只需先尝试通过用户名获取用户即可:
var user = await _userManager.FindByNameAsync(loginViewModel.UserName);
if (user == null)
{
// username is invalid
}
// Now attempt to login with password.
在我的例子中,这是最愚蠢的原因之一,我为管理员用户设置种子并忘记将 EmailConfirmed
标记为 true 并且在我的 ConfigureServices
方法中有 services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
。
确保您在登录时没有要求确认帐户,或者您尝试登录的用户是否已确认其电子邮件。
当登录失败时,我想知道是用户名、密码还是其他问题。
var signinResult = await _signInManager.PasswordSignInAsync(
loginViewModel.UserName,
loginViewModel.Password,
false, false);
returns SignInResult 只是告诉我这是 NotAllowed。
我能从身份中得到更有意义的理由吗?
NotAllowed
表示电子邮件或 Phone 号码尚未确认(需要确认)。你可以用类似下面的东西明确地检查这个(假设你有一个来自 DI 的 UserManager
实例):
await _userManager.IsEmailConfirmedAsync(user);
await _userManager.IsPhoneNumberConfirmedAsync(user);
要使用这两个函数中的任何一个,您需要 user
:
var user = await _userManager.FindByNameAsync(loginViewModel.UserName);
要确定是用户名还是密码失败,您需要先检查 IsLockedOut
、IsNotAllowed
和 RequiresTwoFactor
。如果所有这些 return false
,则用户名或密码不正确。为了确定其中哪一个是问题所在,您可以检查 await _userManager.FindByNameAsync(user)
中的 return 值。这是一个完整的例子:
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.
}
}
PasswordSignInAsync
returns 只是一般性故障。这是因为您真的不应该首先揭露错误。如果您明确告诉最终用户密码错误,那么他们现在就知道用户名是正确的。如果这是一个恶意用户,你已经减半了他们的工作。现在他们可以暴力破解密码了。
不过,如果您确实需要此信息,只需先尝试通过用户名获取用户即可:
var user = await _userManager.FindByNameAsync(loginViewModel.UserName);
if (user == null)
{
// username is invalid
}
// Now attempt to login with password.
在我的例子中,这是最愚蠢的原因之一,我为管理员用户设置种子并忘记将 EmailConfirmed
标记为 true 并且在我的 ConfigureServices
方法中有 services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
。
确保您在登录时没有要求确认帐户,或者您尝试登录的用户是否已确认其电子邮件。