Problem
Openididct v4 started declining the PKCE's Access Token request (RFC 7636, when the client exchanges the authorization code) if the client passes scopes
(ref to the line in the code enforcing it). It wasn't the case for v3.x
However, the MSAL.js implementation has what they call "hybrid flow" (docs) that mixes the implicit grant with the authorization code flow, and it sends scopes
in when exchanging the authorization code. 😟
Example
Request from MSAL.js:
curl --location 'https://localhost:5003/connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded;charset=utf-8' \
--data 'client_id=XXX&redirect_uri=https%3A%2F%2Flocalhost:5003&scope=openid%20profile&code={THE_CODE}&x-client-SKU=msal.js.browser&x-client-VER=2.21.0&x-client-OS=&x-client-CPU=&x-ms-lib-capability=retry-after, h429&x-client-current-telemetry=5|865,0,,,|,&x-client-last-telemetry=5|0|865,33365111-6e2e-4707-946c-e93b095f6c1e|invalid_request|1,0&code_verifier=jJdT8dsU&grant_type=authorization_code&client_info=1&client-request-id=99933333-cdd4-4991-8dcb-1a28f3a0669d'
Response from Openiddict:
{
"error": "invalid_request",
"error_description": "The 'scope' parameter is not valid in this context.",
"error_uri": "https://documentation.openiddict.com/errors/ID2074"
}
Question
Is there a way of relaxing this particular check?
IMHO, the Openiddict rejection, in this case, is too rigid behaviour, where a warning would suffice.
The controversial check for scopes
when exchanging the authorization code was added in OpenIdDict v4 (link to the commit). As you can see from the code:
EventHandler
that makes it easy to add/remove from the pipeline (and yes, it's added in Exchange.DefaultHandlers
, so it's ON by default).Hence, it's safe to remove the handler by adding this line to AddServer()
:
options.RemoveEventHandler(OpenIddictServerHandlers.Exchange.ValidateScopeParameter.Descriptor)
Here's an example of what the registration of the OpenIddict token server services in the DI container may look like (see more in my GitHub example):
// Register the OpenIddict services
services.AddOpenIddict()
// Register the OpenIddict server components.
.AddServer(options =>
{
// Enable the authorization and token endpoints
options
.SetTokenEndpointUris("/connect/token")
.SetAuthorizationEndpointUris("/connect/authorize")
.AllowAuthorizationCodeFlow()
.RequireProofKeyForCodeExchange()
.AllowRefreshTokenFlow()
// Remove a default guard that rejects auth code requests that contain a "scope" parameter
.RemoveEventHandler(OpenIddictServerHandlers.Exchange.ValidateScopeParameter.Descriptor);
// Other settings go here
// Register the ASP.NET Core host and configure the ASP.NET Core-specific options.
.UseAspNetCore();
})