I am using Identity Server 4 and implemented the following two interfaces:
IResourceOwnerPasswordValidator: for the purpose of validating user credentials against my custom DB
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
private IUserRepository _userRepository;
public ResourceOwnerPasswordValidator(IUserRepository userRepository)
{
this._userRepository = userRepository;
}
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
var isAuthenticated = _userRepository.ValidatePassword(context.UserName, context.Password);
//code is omitted for simplicity
}
}
IProfileService: for getting necessary claims
public class ProfileService : IdentityServer4.Services.IProfileService
{
public IUserRepository _userRepository;
public ProfileService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
//code is ommitted
}
Then added then necessary Interfaces and dependencies to the services in Startup class. I have also modified the Account Controller by injecting the login service which has the following implementation:
public class LoginService
{
private readonly IUserRepository _userRepository;
public LoginService( IUserRepository userRepository)
{
_userRepository = userRepository;
}
public bool ValidateCredentials(string username, string password)
{
return _userRepository.ValidatePassword(username, password);
}
The AccountController "Login" Action validate for the credentials by calling:
if (_loginService.ValidateCredentials(model.Username, model.Password))
{
var user = _loginService.FindByUsername(model.Username);
await HttpContext.Authentication.SignInAsync(user.Subject, user.Username);
//other code is omitted
When debugging the project the Login Action of AccountContoller is called, then my login service. After validating the user credentials, the consent page is displayed, which trigger the ProfileService GetProfileDataAsync Method.
However, the ResourceOwnerPasswordValidator was never called. Am I Implementing the LoginService in the correct manner or should I replace the IUserRepository injected by IResourceOwnerPasswordValidation then call the "ValidateAsync" method in Login Service ValidateCredentails?
And if that was the case, what is the advantage of passing that to LoginService, since I am already validating users in this way?