Net Core 3.1 API dengan validasi kata sandi khusus Identity Server 4

Saya sedang membangun API menggunakan server identitas dan saya perlu menggunakan database yang ada. Kata sandi pengguna disimpan dengan kata sandi hash khusus. Saya menggunakan FindClientByIdAsync untuk memvalidasi pengguna dan kata sandi, tetapi karena kata sandi dienkripsi dalam algoritma non-standar saya mendapatkan pesan kesalahan invalid_client. Jika saya mengubah waktu eksekusi (dengan breakpoint) nilai kata sandi untuk nilai yang tidak terenkripsi, otentikasi berfungsi. Mungkinkah mengubah validasi client_secret untuk FindClientByIdAsync?

Kelas ClientStore khusus

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 }
        };
    }
}

Konfigurasi server identitas di kelas Startup

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 sumber
comment
Anda tidak dapat menggunakan FindClientByIdAsync untuk pengguna. Pengguna bukanlah klien. Untuk terminologi harap baca dokumentasi.   -  person Ruard van Elburg    schedule 06.06.2020


Jawaban (1)


Anda harus menerapkan IResourceOwnerPasswordValidator seperti yang ditunjukkan Damien di blog

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);
    }
}

Dan tambahkan builder.AddResourceOwnerValidator<CustomResourceOwnerPasswordValidator>(); di file startup.

person Kishan Vaishnav    schedule 20.06.2020