I'm learning MVC and for creating Login and Register with Custom Existing Database I followed this tutorial and created custom User Manager and Sign In Manager. It allowed me to register a user properly and users are saved in my db properly. But password is saved as string without encryption as user entered it and also while login CheckPasswordAsync returns System.FormatException: Invalid length for a Base-64 char array or string. For Implementing UserPasswordStore I followed this tutorial code for my custom signinmanager and User store is
public class CustomUserManager : UserManager<MyAppUser>
{
public CustomUserManager(IUserStore<MyAppUser> store) : base(store) { }
internal static CustomUserManager Create()
{
return new CustomUserManager(new CustomUserStore());
}
public override Task<bool> CheckPasswordAsync(MyAppUser user, string password)
{
return base.CheckPasswordAsync(user, password);
}
}
public class CustomUserStore : IUserStore<MyAppUser>, IUserPasswordStore<MyAppUser>
{
private LearningDBContext database;
public Task CreateAsync(MyAppUser user)
{
try
{
var context = userStore.Context as LearningDBContext;
context.MyAppUsers.Add(user);
context.Configuration.ValidateOnSaveEnabled = false;
return context.SaveChangesAsync();
}
catch { }
return Task.FromResult<bool>(true);
}
#endregion
#region Password Store Region
public Task SetPasswordHashAsync(MyAppUser user, string passwordHash)
{
var identityUser = ToIdentityUser(user);
var task = userStore.HasPasswordAsync(identityUser);
setMyAppUser(user, identityUser);
return Task.FromResult(0);
}
private void setMyAppUser(MyAppUser user, IdentityUser identityUser)
{
user.Password = identityUser.PasswordHash;
user.Id = identityUser.Id;
user.UserName = identityUser.UserName;
}
public Task<string> GetPasswordHashAsync(MyAppUser user)
{
var identityUser = ToIdentityUser(user);
var task = userStore.GetPasswordHashAsync(identityUser);
setMyAppUser(user, identityUser);
return task;
}
public Task<bool> HasPasswordAsync(MyAppUser user)
{
var identityUser = ToIdentityUser(user);
var task = userStore.HasPasswordAsync(identityUser);
setMyAppUser(user, identityUser);
return task;
}
private IdentityUser ToIdentityUser(MyAppUser user)
{
return new IdentityUser()
{
Id = user.Id,
PasswordHash = user.Password,
UserName = user.UserName
};
}
#endregion
}
and in controller I'm calling
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
I can't figure out the reason. Can anybody help?
Thanks to help from @trailmax I was able to solve this problem. I was saving password directly and as I was using default implementation without overriding system was checking for hashed password. So, I needed to either save hashed password or override CheckPassword method for checking manually. It works both ways.