When using only an authorization code flow in OpenIddict library, it is not required to implement a token endpoint, as the library natively handles the exchange of authorization code for access token. But once you implement an additional token grant type, e.g. client credentials, how do you defer the authorization code grant type to the base library rather than re-doing the claims?
For example, the Aridka sample has this:
[HttpPost("~/connect/token"), IgnoreAntiforgeryToken, Produces("application/json")]
public async Task<IActionResult> Exchange()
{
var request = HttpContext.GetOpenIddictServerRequest();
if (request.IsClientCredentialsGrantType())
{
// <snip> set some claims ...
return SignIn(new ClaimsPrincipal(identity), OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
}
if (request.IsAuthorizationCodeGrantType())
{
//TODO: how to defer to underlying library in this case?
return new OkResult();
}
}
Is there a way to make the authorization code exchange work like before we added .EnableTokenEndpointPassthrough()
without re-implementing claims/principal building?
A simple hack is to do this:
if (request.IsAuthorizationCodeGrantType())
{
var result = await HttpContext.AuthenticateAsync( OpenIddictServerAspNetCoreDefaults.AuthenticationScheme );
return SignIn( result.Principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme );
}
But, based on all the samples, there seems to be a lot of useful validation being skipped when using that approach.
But, based on all the samples, there seems to be a lot of useful validation being skipped when using that approach.
There are two types of validation:
Basic protocol validation: for instance, ensuring the authorization code wasn't tampered with, hasn't expired, is sent by a legit client (called "presenter" in OpenIddict) or isn't marked as revoked in the database. This logic is enforced by OpenIddict itself whether you're using the pass-through mode or not.
Additional, user-specific validation: for instance, refreshing the claims or ensuring the user is still allowed to log in. Since OpenIddict is completely disconnected from your membership stack (e.g ASP.NET Core Identity), it's not checks it will perform for you, whether you decide to use the pass-through mode or let it handle the grant_type=authorization_code
requests automatically.
A simple hack is to do this:
if (request.IsAuthorizationCodeGrantType()) { var result = await HttpContext.AuthenticateAsync( OpenIddictServerAspNetCoreDefaults.AuthenticationScheme ); return SignIn( result.Principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme ); }
When you don't use the pass-through mode, this is exactly the logic used by OpenIddict to handle grant_type=authorization_code
and grant_type=refresh_token
requests: reusing the claims initially stored in the authorization code/refresh token as-is to create new tokens.
If you don't want to refresh claims or enforce additional checks, just using this snippet is perfectly fine.