Invalid login attempt in MVC - asp.net-mvc

I am currently changing the default template of MVC5 project (with identity). When I first time register and login, all goes well. But when I made some changes like project at default level stores UserName as Email. But when I make change it to store UserName as from Form then it gives 'Invalid' login attempt. Can anyone tell me that where I am going wrong. Either I have to make changes at any other places if yes then where?
Here are my register function:
Before:
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
I have changed this line to this:
var user = new ApplicationUser { UserName = model.usrName, Email = model.Email , PhoneNumber=model.Contact};
And my login function is as it comes in default. like,
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
Now, can someone please tell me where i am wrong?

If you want to change UserName from model.Email to model.usrName, you have to use model.usrName in your Login function. Like this:
var result = await SignInManager.PasswordSignInAsync(model.usrName, model.Password, model.RememberMe, shouldLockout: false);
Because UserName and Password fields are default unique parameters to login. So it wants to complete login operation with UserName field.

Related

How to create admin user in ASP.NET MVC 5 with table aspNetUsers

I want to add function in my account controller if user have status 1 then redirect to profile page if user have status 0 then redirect to index page.
I tried with authorize roles but no success user roles utilize two tables and me I want use one table.
If anyone has any idea or has a method like this I want admin user
the code source :
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}`
`
enter image description hereenter image description here
enter image description here
You could either reroute in your home page, or do something like this:
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var user = context.Users.Single(u => u.UserName == model.UserName); // or email
if (user.Status == 1) return RedirectToAction("Profile", "Account");
return RedirectToAction("Index", "Home");
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}

Authorized sections of .net web app are accessible prior to confirmation email being clicked

I'm using .net 4.5.2 and sendgrid. I've used the link below as a guide but rather than using sendgrid v2 i'm using sendgrid v3.
https://learn.microsoft.com/en-us/aspnet/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity
The email confirmation works with a link sent to the registered users email address. When that link is clicked the "Email Confirmation" field in AspNetUsers goes from false to true.
But when the user first submits the registration form - and prior to clicking the confirm email - they become logged into the system. Somehow _LoginPartial is being invoked because the users email address and logoff end up being at the top of the navbar.
So after thinking about it a bit the login action in ActionController is obviously being called just after registration but before email confirmation is clicked. That's not in the Microsoft doc i don't think.
But any advice to fix that would be great. I could check the AspNetUser table for EmailConfirmation == false. But is there a right place to do that?
I checked out this post Prevent login when EmailConfirmed is false and commented out the default login action code and replaced it with this below but it didn't seem to make a difference.
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
//Add this to check if the email was confirmed.
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
ModelState.AddModelError("", "You need to confirm your email.");
return View(model);
}
if (await UserManager.IsLockedOutAsync(user.Id))
{
return View("Lockout");
}
if (await UserManager.CheckPasswordAsync(user, model.Password))
{
// Uncomment to enable lockout when password login fails
//await UserManager.ResetAccessFailedCountAsync(user.Id);
return await LoginCommon(user, model.RememberMe, returnUrl);
}
else
{
// Uncomment to enable lockout when password login fails
//await UserManager.AccessFailedAsync(user.Id);
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
The register action:
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser {UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
/*These bottom three lines were commented out */
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking ");
return RedirectToAction("ConfirmRegistration");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
Login action:
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
In your Register action, comment/remove the line:
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
That will disable the automatic sign in upon registering. Then, in your Login action, add the following code after the initial ModelState.IsValid check, to check if the user's email has been confirmed:
var user = await UserManager.FindByEmailAsync(model.Email);
if (user != null && !await UserManager.IsEmailConfirmedAsync(user.Id))
{
ModelState.AddModelError("", "Please confirm your email address before signing in.");
return View(model);
}

Logging in with un registered email address throws exception

I'm having a little logic problem logging into the site. If there is no registered email address I want validation on the page to fail and show a message under the email address field that says something like "Email address doesn't exist" or something to that nature.
But I'm not sure how this code below for login should take care of that...
In this code below 'user' is null when no email address is found so PasswordSignInAsync throws an exception because the user.UserName property is null.
How would I handle the validation for this and shouldn't this be already built into the logic for the ASP.Net MVC template with single sign on I created?
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Require the user to have a confirmed email before they can log on.
var user = await UserManager.FindByEmailAsync(model.Email);
if (user != null)
{
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your account-Resend");
// Uncomment to debug locally
// ViewBag.Link = callbackUrl;
ViewBag.errorMessage = "You must have a confirmed email to log on. "
+ "The confirmation token has been resent to your email account.";
return View("Error");
}
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
If you want that the message "Invalid login attempt" is shown as validation error for the e-mail address field, you have to set the ModelError for the specific property of your viewModel which is holding the e-mail address.
So it should look like this, whereas the "EmailAdress" is the name of the viewModel property:
ModelState.AddModelError("EmailAddress", "Invalid login attempt.");

UserManager.FindByEmail() returning Null

I'm trying to implement email address based usernames in AspNet.Identity for MVC5. My application works find as long as there is a registered email/username on the system.
I just discovered that if the user does not exist and tries to login an exception gets thrown on Line 72.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 71: //Add this to check if the email was confirmed.
Line 72: var userid = UserManager.FindByEmail(model.Email).Id;
Here is my code.
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
//Add this to check if the email was confirmed.
var userid = UserManager.FindByEmail(model.Email).Id;
// **Line 72. 'userid' is empty.**
// Here is my attempt but doesn't do anything.
if (string.IsNullOrEmpty(userid)) {
ModelState.AddModelError("","You are not registered!");
}
if (!UserManager.IsEmailConfirmed(userid))
{
ModelState.AddModelError("", "E-mail address has not been confirmed.");
return View(model);
}
}
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
Thank you!
I tried the code below and worked for me:
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
string userName = ""; // to be used as arg to PasswordSignInAsync
// you'd better declare the appropriate Type.
// using "var" doesn't work here - I don't know why...
ApplicationUser user = await UserManager.FindByEmailAsync(model.UserName);
if (user != null)
{
// found an existing user having the given Email
// so let's get it's UserName to test SignIn
userName = user.UserName;
// just for debugging - check your AspNetUser table
// ModelState.AddModelError("", userName + " ID = " + user.Id.ToString());
}
else
{
// Hum... no email found - perhaps the user is really trying the UserName
// Perhaps Email != UserName
// It's interesting to give the user the option to use Email or UserName
// to get authenticated.
// Let's play, then!
userName = model.UserName;
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(userName, model.Password,
model.RememberMe, shouldLockout: true);
// from here on, it's the scaffolded code...
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
Hope it's useful, even after all that time.
Please, let us know if your problem was solved.
Regards.
I added the code below and it works but I still don't understand how FindByNameAsyn() method actually work as opposed to FindByName()? Also
Is there a better way to do this? Thank you!
// Code that works.
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}

Asp.net Identity : User.Identity.GetUserId() is always null and User.Identity.IsAuthenticated is alway false

See my code below:
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
string UserId = User.Identity.GetUserId();
return RedirectToAction("ClientDetails","Home");
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", "Account", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
The UserId is always null and User.Identity.IsAuthenticated is always false. But I can view the View ClientDetails which requires authentication.
I assume your example is the code from your AccountController.Login() method. I had the same problem as you but discovered that the User object won't be populated until the next request. Try this approach:
case SignInStatus.Success:
return RedirectToAction("DoWork", "Account");
public async Task<ActionResult> DoWork()
{
//this works
string UserId = User.Identity.GetUserId();
//return to View or Redirect again
}
For the "The UserId is always null" part of the question, you can look up the user by the model.UserName:
var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
ApplicationUser user = UserManager.FindByName(model.UserName);
string UserId = user.Id;
// UserId is now populated
return RedirectToAction("ClientDetails","Home");
etc. Not sure if you wanted User.Identity.IsAuthenticated true or whether that was an observation - this doesn't change that part.
Worked with me after tagging the method with [Authorize]
attribute and sending the access-token in the authorize header, it seems that the access-token is needed to recognize the user

Resources