Reputation: 6868
I am doing custom authentication in mvc using asp.net identity and owin
framework but unfortunately not getting user with correct credentials with below method:
var user = UserManager.Find(email, HashedNewPassword);
I have stored my email and password like below in my database table:
Id EmailAdress Password
1 [email protected] 123456
Right now I am doing like this but later on I will hash this password and store it in table. This is just for testing Microsoft owin framework.
But I am not getting user with this credentials:
Emaild Id:[email protected]
Password:123456.
This is my code:
Controller:
[Authorize]
public class AuthenticationController : Controller
{
public AuthenticationController()
: this(new UserManager<UserModel>(new UserStore(new MyEntities())))
{
}
public AuthenticationController(UserManager<UserModel> userManager)
{
UserManager = userManager;
}
public UserManager<UserModel> UserManager { get; private set; }
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(string email, string password, string returnUrl)
{
if (ModelState.IsValid)
{
var user = UserManager.Find(email, password); //getting null here
}
}
}
UserModel:
public class UserModel : IUser
{
public string Id { get; private set; }
public string UserName { get { return Email; } set { Email = value; } }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public UserModel(string email, string firstName, string lastName)
{
Email = email;
FirstName = firstName;
LastName = lastName;
}
public UserModel(Users dbUser)
{
if (dbUser == null)
return;
Id = dbUser.Id.ToString();
Email = dbUser.EmailAddress;
FirstName = dbUser.FirstName;
LastName = dbUser.LastName;
}
}
public class UserStore : IUserStore<UserModel>, IUserPasswordStore<UserModel>
{
public Task<UserModel> FindByNameAsync(string userName)
{
return Task.Factory.StartNew(() =>
{
HttpContext.Current = _httpContext ?? HttpContext.Current;
var dbUser = GetDbUser(userName);
if (dbUser == null)
return null;
return new UserModel(dbUser);
});
}
private Users GetDbUser(string userName)
{
using (var db = new MyEntities())
{
return db.Users.FirstOrDefault(u => u.EmailAddress.Equals(userName, StringComparison.OrdinalIgnoreCase));
}
}
public Task<string> GetPasswordHashAsync(UserModel user)
{
return Task.Factory.StartNew(() =>
{
HttpContext.Current = _httpContext ?? HttpContext.Current;
var userObj = GetDbUser(user);
int len = userObj.Password.Length % 4;
//solved this error with below code :Invalid length for a Base-64 char array
if (len > 0) userObj.Password = userObj.Password.PadRight(userObj.Password.Length + (4 - len), '=');
return userObj.Password; //sometimes progam gets stuck here on debugging
});
}
private Users GetDbUser(UserModel user)
{
if (user.Id == null)
return null;
return GetDbUser(Convert.ToInt32(user.Id));
}
private Users GetDbUser(int userId)
{
using (var db = new MyEntities())
{
return db.Users.FirstOrDefault(u => u.Id == userId);
}
}
}
What is the problem?
Upvotes: 0
Views: 1103
Reputation: 35
var user = UserManager.Find(email, password); //getting null here
I had a similar problem. Your function return null, because this function must work with UserName.
1.
var user = UserManager.Find(UserName, password);
That is you input: Login : MyLogin
password: 123123
e-mail: [email protected]
and this function work with login (UserName fiel on the table AspNetUserLogins)
You want to transfer
var user = UserManager.Find([email protected], password);
but actually it is transferred
var user = UserManager.Find(MyLogin, password);
Attenction! These are two different cells in the table
ApplicationUser user = new ApplicationUser { UserName = model.Email, Email = model.Email, Year = model.Year };
Upvotes: 0
Reputation: 239250
If I understand you correctly, you're storing the password as plain text in the database? If that's the case, then that's your problem. You can't just choose to hash it later; Identity needs it hashed in order to match the password. This is how authentication works:
So, when Identity compares the hashed version of 123456
to the plain-text 123456
, it will never match. In order for it to match, the password saved in the DB must be hashed as well.
Upvotes: 1