【问题标题】:How to change default Error message of IdentityServer4 with Password Grant flow如何使用密码授予流程更改 IdentityServer4 的默认错误消息
【发布时间】:2019-04-29 10:13:20
【问题描述】:

当使用带有资源所有者密码流和 asp.net 身份的 IdentityServer4 时,登录失败时总是返回相同的错误消息。密码无效或用户被锁定都没有关系。

{
    "error": "invalid_grant",
    "error_description": "invalid_username_or_password"
}

这里是Identity和Identity server的配置:

services.AddIdentityCore<User>()
    .AddEntityFrameworkStores<ApplicationDBContext>()
    .AddDefaultTokenProviders()
    .AddUserManager<UserManager<User>>()
    .AddSignInManager<ApplicationSignInManager>();

var builder = services.AddIdentityServer()
    .AddInMemoryIdentityResources(Config.IdentityResources)
    .AddInMemoryApiResources(Config.Apis)
    .AddInMemoryClients(Config.Clients)
    .AddAspNetIdentity<User>();

由于我使用带有 asp.net 身份的资源所有者密码流,登录用户没有自定义用户服务。那么如何根据登录过程中发生的情况显示错误消息?

【问题讨论】:

  • ASP.NET Core Identity 集成注册了IResourceOwnerPasswordValidator 的自定义实现,它似乎控制着发回的响应。您可能需要提供自己的实现才能更改您提到的 error_description 属性。请注意,更改 error 属性是不明智的,因为它来自规范。您可能会争辩说,提供有关锁定等的更多信息也是一个坏主意,但这取决于您。
  • 感谢您的帮助,我可以覆盖 IResourceOwnerPasswordValidator 接口实现的验证方法并返回我需要的消息。非常感谢。请回答问题,以便我将您的答案标记为已接受
  • 没问题 - 我很高兴能帮上忙。我建议你用你的最终解决方案自己回答这个问题,因为这将是一个比我能提供的更好的答案。 :)

标签: c# asp.net-core asp.net-identity identityserver4


【解决方案1】:

这对我来说是这样的:

using IdentityServer4.Models;
using IdentityServer4.Validation;
using Microsoft.AspNetCore.Identity;

public class CustomResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    private readonly CustomUserRepository _repository;

    public CustomResourceOwnerPasswordValidator(CustomUserRepository repository)
    {
        _repository = repository;
    }

    // https://docs.identityserver.io/en/latest/topics/resource_owner.html
    public async System.Threading.Tasks.Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        var user = await _repository.FindUser(context.UserName, context.Password);
        if (user != null)
        {
            var passwordHasher = new PasswordHasher();
            var result = passwordHasher.VerifyHashedPassword(user.User.Password, context.Password);
            // https://docs.identityserver.io/en/latest/reference/grant_validation_result.html#refgrantvalidationresult
            if (result)
            {
                context.Result = new GrantValidationResult(subject: user.Id, authenticationMethod: "password");
            }
            else
            {
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid password");
            }
        }
        else
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid user");
        }
    }
}

这是在 Startup.cs 时这样注册的:

        var builder = services
            .AddIdentityServer()
            .AddSigningCredential(certificate)
            .AddInMemoryIdentityResources(Resources.Get())
            .AddInMemoryClients(Clients.Get(baseUri))
            .AddValidationKey(certificate)
            .AddProfileService<ProfileService>();
            .AddResourceOwnerValidator<CustomResourceOwnerPasswordValidator>();

对我来说,为了让它工作,我需要在注册步骤结束时包含.AddAspNetIdentity&lt;User&gt;();

【讨论】:

    猜你喜欢
    • 2021-08-08
    • 2017-02-26
    • 2017-03-09
    • 1970-01-01
    • 2022-08-17
    • 2018-06-04
    • 2018-12-01
    • 1970-01-01
    • 2021-12-17
    相关资源
    最近更新 更多