Reputation: 533
I'm trying to add some basic authentication to my asp.net core website.
I have my users stored in a sqlite database and i'm trying to verify the password the user enters but for some reason it always fails even though the entered password is correct.
Any advise here?
This is my login action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel ivm)
{
if (ModelState.IsValid)
{
var user = _userRepo.Get(ivm.Email);
if (user == null)
{
ModelState.AddModelError("UserError", "User not found");
return View("Index", ivm);
}
PasswordHasher<User> hasher = new PasswordHasher<User>();
var result = hasher.VerifyHashedPassword(user, user.Password, ivm.Password);
if (result != PasswordVerificationResult.Failed)
{
string role = "";
if (user.Role == Models.Enums.Role.Admin)
role = "Admin";
else
role = "User";
var claims = new[] { new Claim(ClaimTypes.Name, user.Id.ToString()), new Claim(ClaimTypes.Role, role) };
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await AuthenticationHttpContextExtensions.SignInAsync(HttpContext, CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("PasswordError", "Wrong password");
return View("Index", ivm);
}
}
else
{
ModelState.AddModelError("ModelError", "ModelError");
return View("Index", ivm);
}
}
User:
[Table("Users")]
public class User
{
public string Email { get; set; }
public string Password { get; set; }
public Role Role { get; set; }
public Guid Id { get; set; }
}
Current init just an admin user:
var user = new User
{
Email = "email.com",
Role = Models.Enums.Role.Admin,
Id = Guid.NewGuid()
};
PasswordHasher<User> phw = new PasswordHasher<User>();
string hashed = phw.HashPassword(user, "superpassword");
user.Password = hashed;
db.Users.Add(user);
db.SaveChanges();
Upvotes: 1
Views: 710
Reputation: 2838
In my ASP.NET Core project I use UserManager
which handles password checking pretty well
bool correctPassword = await _userManager.CheckPasswordAsync(user, password);
UserManager
also handles user creation without having to deal with password hasher.
One of the overloads:
public virtual Task<IdentityResult> CreateAsync(TUser user, string password);
Update 1:
based on the code you provided, you assign password hash to Password
member of User
class
instead, you should use PasswordHash
property e.g.
hostAdminUser = new ApplicationUser()
{
UserName = SetupConsts.Users.Host.UserName,
Email = SetupConsts.Users.Host.Email,
EmailConfirmed = true,
PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(hostAdminUser, SetupConsts.Users.Passwords.Default)
};
await _userManager.CreateAsync(hostAdminUser);
so, here's the relevant bit: PasswordHash = new PasswordHasher<ApplicationUser>
Update 2:
In order to use UserManager
in ASP.NET Core you need to inject it into your controller
public class AuthController : Controller
{
private UserManager<ApplicationUser> _userManager;
public AuthController(
UserManager<ApplicationUser> userManager
)
{
_userManager = userManager;
}
you are then supposed to use _userManager
instance.
In Startup.cs find the method called ConfigureServices
, and put the following line required for Dependency Injection
services.AddTransient<UserManager<ApplicationUser>>();
Upvotes: 1