验证凭据自定义用户DB - IResourceOwnerPasswordValidator

Hus*_*man 2 thinktecture-ident-server asp.net-core identityserver4

我正在使用Identity Server 4并实现了以下两个接口:

IResourceOwnerPasswordValidator:用于根据我的自定义数据库验证用户凭据

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                
    }
}
Run Code Online (Sandbox Code Playgroud)

IProfileService:用于获取必要的声明

 public class ProfileService : IdentityServer4.Services.IProfileService
{
    public IUserRepository _userRepository;
    public ProfileService(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }
    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        //code is ommitted
    }
Run Code Online (Sandbox Code Playgroud)

然后将必要的接口和依赖项添加到Startup类中的服务.我还通过注入具有以下实现的登录服务来修改帐户控制器:

   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);
    }
Run Code Online (Sandbox Code Playgroud)

AccountController"登录"操作通过调用以下方式验证凭据:

 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  
Run Code Online (Sandbox Code Playgroud)

在调试项目时,调用AccountContoller的Login Action,然后调用我的登录服务.验证用户凭据后,将显示同意页面,该页面将触发ProfileService GetProfileDataAsync方法.

但是,从未调用过ResourceOwnerPasswordValidator.我是以正确的方式实现LoginService还是应该替换IResourceOwnerPasswordValidation注入的IUserRepository,然后在Login Service ValidateCredentails中调用"ValidateAsync"方法?

如果是这种情况,那么将其传递给LoginService有什么好处,因为我已经以这种方式验证用户了?

Wau*_*una 10

我遇到了同样的问题。解决方案是按照您所做的那样做,但随后需要修改 Startup.cs 才能看到它。

// Adds IdentityServer
services.AddIdentityServer()
    .AddResourceOwnerValidator<**PasswordAuthentication**>()
Run Code Online (Sandbox Code Playgroud)

注意:请确保不要将其添加到AddIdentity也具有相同.AddResourceOwnerValidator功能的 . 我花了一段时间。希望这可以帮助某人。


ade*_*lin 5

根据文件:

如果要使用OAuth 2.0资源所有者密码凭据授权(也称为密码),则需要实现并注册IResourceOwnerPasswordValidator接口:

由于您不使用密码授予,因此预期的行为是不调用ResourceOwnerPasswordValidator.对于您的情况,您不需要ResourceOwnerPasswordValidator实施.