For some reason I am yet to discover, but after a successful registration and activation, I cannot login with the email address, instead I get an error "Invalid login attempt".
As ASP.NET Identity 2.0 has improved with the use of Email login, I have modified the registration form to actually store a true username as the existing registration just seemed to duplicate by storing Username with the email address.
Please see below the standard code that comes with Install-Package Microsoft.AspNet.Identity.Samples -Pre'
following the creation of an empty ASP.NET Web Application (MVC) project:
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
My function is now as follows:
var user = new ApplicationUser { TitleId = model.TitleId, SexId = model.SexId, Forename = model.Forename, Surname = model.Surname, UserName = model.UserName, Email = model.Email, JoinDate = System.DateTime.Now };
As you can see UserName is now receiving a value from a form. This is all well and good except now I can't logon after registration and activation. The only work round is to modify the record by putting the value from the Email field into the UserName field which just seems daft.
Can somebody please advise as to what I might have missed?
You can try change to bool value in Startup.cs file in your project. "true->false"
In this line, services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
I had the same issue but found the solution to be a combination of both the accepted answer by Marcin and the answer by Hai. In AccountController.cs
you need to use FindByEmailAsync()
, instead of FindByNameAsync()
, then use SignInManager.PasswordSignInAsync()
but use the value of user.UserName
as the first argument (as long as user
is not null), instead of model.Email
. So a complete answer, based on the current boiler plate code, would be something like this:
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
// (...) ModelState.IsValid, etc
string user_name = ""; // in case 'user' is null (user not found)
var user = await UserManager.FindByEmailAsync(model.Email);
if (user != null)
{
user_name = user.UserName;
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
// (...) Require the user to have a confirmed email before they can log on, etc
}
}
// don't use model.Email below, use the value from user.UserName (if user not null)
var result = await SignInManager.PasswordSignInAsync(user_name, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
// (...)
You have to modify SignInHelper.PasswordSignIn
method. By default it uses FindByNameAsync
to check if user with given name exists:
public async Task<SignInStatus> PasswordSignIn(string userName, string password, bool isPersistent, bool shouldLockout)
{
var user = await UserManager.FindByNameAsync(userName);
// (...)
change it to use FindByEmailAsync
:
var user = await UserManager.FindByEmailAsync(userName);
You can find SignInHelper
class in *AppCode\IdentityConfig.cs` file.
In class AccountController.cs, method: public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
.
Modified this:
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
To this:
try
{
var user = db.Users.Where(u => u.Email.Equals(model.Email)).Single(); // where db is ApplicationDbContext instance
var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: false);
}
catch (InvalidOperationException)
{
// the user is not exist
}
The reason is UserName
and UserEmail
have different values but method PasswordSignInAsync
only uses UserName
to check for log in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With