问题
I'm creating two projects (MVC 5 and Web API) using ASP.Net Identity 2.1 and I couldn't find how to use both email and username for authentication (an area called Admin must use a username and the common area must use email addresses for authentication).
The problem is that there is only one method for authentication and it does not allow you to specify if you will compare with the email address or the username.
SignInHelper.PasswordSignIn
What should I do to achieve this?
回答1:
SignInManager
will not you help with it, you'll need to use UserManager
and a bit more jiggery-pokery (that's technical term!):
This is what I have for this scenario:
var unauthUserByUsername = await userManager.FindByNameAsync(command.UserName);
var unauthUserByEmail = await userManager.FindByEmailAsync(command.UserName);
var unauthenticatedUser = unauthUserByUsername ?? unauthUserByEmail;
if (unauthenticatedUser == null)
{
logger.Warn("User {0} is trying to login but username is not correct", command.UserName);
return View(); // stop processing
}
var loggedInUser = await userManager.FindAsync(unauthenticatedUser.UserName, command.Password);
if (loggedInUser == null)
{
// username is correct, but password is not correct
logger.Warn("User {0} is trying to login with incorrect password", command.UserName);
await userManager.AccessFailedAsync(unauthenticatedUser.Id);
return View(); // stop processing
}
// Ok, from now on we have user who provided correct username and password.
// and because correct username/password was given, we reset count for incorrect logins.
await userManager.ResetAccessFailedCountAsync(loggedInUser.Id);
if (!loggedInUser.EmailConfirmed)
{
logger.Warn("User {0} is trying to login, entering correct login details, but email is not confirmed yet.", command.UserName);
return View("Please confirm your email"); // stop processing
}
if (await userManager.IsLockedOutAsync(loggedInUser.Id))
{
// when user is locked, but provide correct credentials, show them the lockout message
logger.Warn("User {0} is locked out and trying to login", command.UserName);
return View("Your account is locked");
}
logger.Info("User {0} is logged in", loggedInUser.UserName);
// actually sign-in.
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
await userManager.SignInAsync(authenticationManager, loggedInUser, false);
This checks if user has confirmed email, if user is locked out and does lock user out after a certain number of attempts (given all other settings for locking-out are enabled).
回答2:
This way both are allowed
var userEmail = await UserManager.FindByEmailAsync(model.Login);
if (userEmail == null)
{
var user = await UserManager.FindByNameAsync(model.Login);
if (user == null)
{
model.Login = "";
}
}
else
{
model.Login = userEmail.UserName;
}
var result = await SignInManager.PasswordSignInAsync(model.Login, model.Password, model.RememberMe, shouldLockout: false);
来源:https://stackoverflow.com/questions/25611957/allowing-both-email-and-username-for-authentication