openiddict / openiddict-core

Flexible and versatile OAuth 2.0/OpenID Connect stack for .NET
https://openiddict.com/
Apache License 2.0
4.35k stars 508 forks source link

how disable the client credentials automatically validated ? #700

Closed javico2609 closed 5 years ago

javico2609 commented 5 years ago

how disable the client credentials automatically validated ?

kevinchalet commented 5 years ago

What do you have in mind, exactly?

javico2609 commented 5 years ago

Hi. i implement my custom client credential validate like for E.g:

FindByClientIdAsync implement another logic to find the client-application object.

        var application = await service.FindByClientIdAsync(request.ClientId, CancellationToken.None);
       if (application == null)
        {
            throw new InvalidClientException();
        }

in the current behavior the app execute two db queries and fire it's own exception model and don't enter in my GlobalExceptionHandler.

king regards. sorry for my english.

kevinchalet commented 5 years ago

Customizing the client authentication logic performed by the OpenIddict server components is not a supported scenario.

in the current behavior the app execute two db queries and fire it's own exception model and don't enter in my GlobalExceptionHandler.

  1. starting with RTM, OpenIddict now comes with a built-in cache to avoid sending multiple queries to retrieve the same object (it's enabled by default)

  2. the OpenIddict server doesn't use exceptions to reject requests that don't pass the client authentication validation logic. Instead, it uses the APIs provided by ASOS - the underlying OIDC server handler. If you want to customize how the error response looks like, you can use the events model for that. E.g:

services.AddOpenIddict()
    .AddCore(options =>
    {
        // ...
    })

    .AddServer(options =>
    {
        // ...
        options.AddEventHandler<OpenIddictServerEvents.ApplyTokenResponse>(
            notification =>
            {
                // When the returned error is an invalid_client error, tweak the default description message:
                var error = notification.Context.Response.Error;
                if (!string.IsNullOrEmpty(error) &&
                     string.Equals(error, OpenIddictConstants.Errors.InvalidClient, StringComparison.Ordinal))
                {
                    notification.Context.Response.ErrorDescription = "Something went bad with authentication.";
                }

                return Task.FromResult(OpenIddictServerEventState.Unhandled);
            });
    })

    .AddValidation(options =>
    {
        // ...
    });
egorpavlikhin commented 4 years ago

Customizing the client authentication logic performed by the OpenIddict server components is not a supported scenario.

This is confusing. How would OpenIddict know what the valid client credentials are? There are also several examples (https://github.com/openiddict/openiddict-core/issues/240#issuecomment-254605982 https://github.com/openiddict/openiddict-samples/tree/master/samples/Aridka/Aridka.Server) in this project for the token endpoint, which explicitly validate client credentials via request.IsClientCredentialsGrantType()

Does this mean client grant types are unsupported? (since in most cases OpenIddict wouldn't know anything about the underlying authentication mechanisms of an application).

kevinchalet commented 4 years ago

There are also several examples (#240 (comment) https://github.com/openiddict/openiddict-samples/tree/master/samples/Aridka/Aridka.Server) in this project for the token endpoint, which explicitly validate client credentials via request.IsClientCredentialsGrantType()

Implementing the client credentials flow doesn't mean you are responsible of validating the client credentials. If you carefully look at the samples, you'll see that their authorization controller doesn't validate the credentials but only provide the claims-based identity used to create the tokens: https://github.com/openiddict/openiddict-samples/blob/a66727e6fd387263c471d690a284398883fa4139/samples/Aridka/Aridka.Server/Controllers/AuthorizationController.cs#L30-L73

Client credentials are validated by OpenIddict itself using its Core APIs (both client_basic and client_post are supported). In 3.0, you can go database-less with the degraded mode and handle the client credentials validation part - among other things - yourself. Read https://kevinchalet.com/2020/02/18/creating-an-openid-connect-server-proxy-with-openiddict-3-0-s-degraded-mode/ for more information.

egorpavlikhin commented 4 years ago

Thanks. Was able to do the same by using EF Core InMemory store and then implementing own ApplicationStore and overwriting hash validation in ApplicationManager, although I've left most methods NotImplemented, since they don't look to be needed in such scenario. I'd post the code, but it seems that will no longer be needed in 3.0 anyway.

"Degraded" should really be called "Upgraded", since it simplifies the dependency graph.

kevinchalet commented 4 years ago

"Degraded" should really be called "Upgraded", since it simplifies the dependency graph.

Not really. The degraded more is not magical, and using it has serious implications that explain why it's called "degraded" and not "upgraded":