You need to override the ValidateAsync by creating the Custom PasswordValidator class which implement IResourceOwnerPasswordValidator interface like below.
public class OwnerPasswordValidatorService : IResourceOwnerPasswordValidator
{
public UserManager<ApplicationUser> _userManager { get; }
public OwnerPasswordValidatorService(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
var user = await _userManager.FindByNameAsync(context.UserName);
if (user == null)
{
user = await _userManager.FindByEmailAsync(context.UserName);
if (user == null)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect");
return;
}
}
var passwordValid = await _userManager.CheckPasswordAsync(user, context.Password);
if (!passwordValid)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect");
return;
}
context.Result = new GrantValidationResult(subject: context.UserName, authenticationMethod: "custom");
}
}
Then configure your dependency for your custom class like below.
services.AddIdentityServer()
.AddDeveloperSigningCredential()
...
.AddAspNetIdentity<ApplicationUser>()
.AddResourceOwnerValidator<OwnerPasswordValidatorService>() //here
.AddProfileService<ProfileService>();
If any one still cannot make it work let me know. I will be happy to help.