Net Core 3.1 API พร้อมการตรวจสอบรหัสผ่านที่กำหนดเองของ Identity Server 4

ฉันกำลังสร้าง API โดยใช้เซิร์ฟเวอร์ข้อมูลระบุตัวตน และฉันจำเป็นต้องใช้ฐานข้อมูลที่มีอยู่ รหัสผ่านผู้ใช้จะถูกจัดเก็บด้วยรหัสผ่านแฮชที่กำหนดเอง ฉันใช้ FindClientByIdAsync เพื่อตรวจสอบผู้ใช้และรหัสผ่าน แต่เนื่องจากรหัสผ่านถูกเข้ารหัสในอัลกอริธึมที่ไม่ได้มาตรฐาน ฉันจึงได้รับข้อความแสดงข้อผิดพลาด invalid_client หากฉันเปลี่ยนเวลาดำเนินการ (ด้วยเบรกพอยต์) ค่าของรหัสผ่านสำหรับค่าที่ไม่ได้เข้ารหัส การรับรองความถูกต้องจะทำงาน เป็นไปได้หรือไม่ที่จะเปลี่ยนการตรวจสอบความถูกต้องของ client_secret สำหรับ FindClientByIdAsync

คลาส ClientStore แบบกำหนดเอง

public class ClientStore : IClientStore
{
    private readonly IMyUserRepository myUserRepository;

    public ClientStore(IMyUserRepository myUserRepository)
    {
        this.myUserRepository = myUserRepository;
    }

    public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
        {
            new IdentityResources.OpenId()
        };
    }

    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource("My_API", "My API")
        };
    }

    public async Task<Client> FindClientByIdAsync(string client)
    {
        var user = await myUserRepository.GetUserByEmailAsync(client);

        if (user == null)
            return null;

        return new Client()
        {
            ClientId = client,
            AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
            ClientSecrets =
            {
                new Secret(user.Password.Sha256()) //if I change to unencrypted works, but the value in database is hashed
            },
            AllowedScopes = { "GOLACO_API", IdentityServerConstants.StandardScopes.OpenId }
        };
    }
}

การกำหนดค่าเซิร์ฟเวอร์ข้อมูลประจำตัวในคลาสเริ่มต้น

services.AddIdentityServer(options =>
            {
                options.Events.RaiseSuccessEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseErrorEvents = true;
            })
            .AddSigningCredential(GetSigningCredential()) // here I just read the private.key file
            .AddInMemoryIdentityResources(ClientStore.GetIdentityResources())
            .AddInMemoryApiResources(ClientStore.GetApiResources())
            .AddClientStore<ClientStore>();

services.AddAuthentication("Bearer")
              .AddIdentityServerAuthentication(options =>
              {
                  options.Authority = configuration["Configuration"];
                  options.ApiName = "My_API";
                  options.RequireHttpsMetadata = false;
              });

        services.AddAuthentication()
            .AddFacebook("Facebook", options =>
            {
                options.AppId = "1234";
                options.AppSecret = "1234567890";
            });

        var policy = new AuthorizationPolicyBuilder()
               .RequireAuthenticatedUser()
               .Build();

person Tiago Crizanto    schedule 05.06.2020    source แหล่งที่มา
comment
คุณไม่สามารถใช้ FindClientByIdAsync สำหรับผู้ใช้ ผู้ใช้ไม่ใช่ลูกค้า สำหรับคำศัพท์ โปรดอ่านเอกสารประกอบ   -  person Ruard van Elburg    schedule 06.06.2020


คำตอบ (1)


คุณต้องใช้ IResourceOwnerPasswordValidator ตามที่ Damien แสดงใน บล็อก

public class CustomResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    private readonly IUserRepository _userRepository;

    public CustomResourceOwnerPasswordValidator(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        if (_userRepository.ValidateCredentials(context.UserName, context.Password))
        {
            var user = _userRepository.FindByUsername(context.UserName);
            context.Result = new GrantValidationResult(user.SubjectId, OidcConstants.AuthenticationMethods.Password);
        }

        return Task.FromResult(0);
    }
}

และเพิ่ม builder.AddResourceOwnerValidator<CustomResourceOwnerPasswordValidator>(); ในไฟล์เริ่มต้น

person Kishan Vaishnav    schedule 20.06.2020