Remove "oi_prst" and "oi_au_id" claims from access token

Viewed 634

I'm using OpenIddict.AspNetCore version 3.0.0-rc1.20567.82. All access tokens created by OpenIddict are including these claims:

  • oi_au_id
  • oi_prst

How can I configure OpenIddict to not include those claims in access tokens?

Here's an excerpt of the log file showing how the access token is generated:

2020-11-20 11:00:58.803 [VRB] (OpenIddict.Server.OpenIddictServerDispatcher) A new access token was successfully created: eyJhbGciOiJSUzI1NiIsImtpZCI6IkY2RDA3NDIxRUY5MzRDNDA4QzhCRUI0QzkzQTNDMzYwNkI0QjZBMEUiLCJ4NXQiOiI5dEIwSWUtVFRFQ01pLXRNazZQRFlHdExhZzQiLCJ0eXAiOiJhdCtqd3QifQ.eyJzdWIiOiJjYjRhN2MxMWU3Nzk0NGYzYTNlM2RiM2EwODQwYWMyMCIsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJvaV9hdV9pZCI6IjdjZmQyYjE2NjI5YzQ4NDQ5YTFjNzhjMzg0MGExNzVmIiwib2lfcHJzdCI6InRlc3RhcHAiLCJjbGllbnRfaWQiOiJ0ZXN0YXBwIiwic2NvcGUiOiJvcGVuaWQiLCJleHAiOjE2MDU4OTE2NTgsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0LyIsImlhdCI6MTYwNTg4ODA1OH0.AV-A7-fU3pPBhu0DMrzc9TO-2IgWMHQ25y1HbF3BIDZXi9bZQDvxPx0FOemuo2yvbgae4TCUOahVNTm92qNrDyMFEhlFpfHlcjJk1I3ooBuswXw0lnlCji2wrOAdM3UJ2ieF1F2G7YNqCE0usnpiFBHvzpZuHeIc2yj8ZANLs7Jg0FOooUBjdyuXiGmD1WI8Ns_yVeOjqUv1dx6TyWDD3FB2UqpV-x24sauventRXjEdirorMYlR8xlYJR1l64wVu1voCHOrlKn_WcsTYmhz4XH-1Tn5XHEWeAH8AXs8mLbJPDmqoReyHNxaBLyAJLMA6z_xYCXFIvpOknMWetMaQw.

The principal used to create the token contained the following claims: ["sub: cb4a7c11e77944f3a3e3db3a0840ac20","email: test@test.com","email_verified: true","oi_au_id: 7cfd2b16629c48449a1c78c3840a175f","oi_prst: testapp","client_id: testapp"].

2020-11-20 11:00:58.803 [DBG] (OpenIddict.Server.OpenIddictServerDispatcher) The event OpenIddict.Server.OpenIddictServerEvents+ProcessSignInContext was successfully processed by OpenIddict.Server.OpenIddictServerHandlers+GenerateIdentityModelAccessToken.

In the above log statements, notice how the access token includes these claims: "oi_au_id: 7cfd2b16629c48449a1c78c3840a175f","oi_prst: testapp". I don't want the access token to include those claims because they appear to be specific to OpenIddict and my resource servers that don't use OpenIddict won't know what to do with those claims.

The source code for GenerateIdentityModelAccessToken at https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Server/OpenIddictServerHandlers.cs#L2521-L2526 shows it is excluding a few private claims that are specific to OpenIddict, but the list of excluded claims does not include oi_au_id or oi_prst:

// Clone the principal and exclude the private claims mapped to standard JWT claims.
var principal = context.AccessTokenPrincipal.Clone(claim => claim.Type is not (
   Claims.Private.Audience or
   Claims.Private.CreationDate or
   Claims.Private.ExpirationDate or
   Claims.Private.Scope or
   Claims.Private.TokenType));

I also don't see an easy way to configure OpenIddict to exclude the AuthorizationId and Presenter claims without modifying OpenIddict itself.

2 Answers

Thanks to Kévin's answer at https://stackoverflow.com/a/65192219/14676808 I was able to come up with this code that removes the claims:

services.AddOpenIddict()
    .AddServer(options =>
    {
        // ...

        options.AddEventHandler<ProcessSignInContext>(builder =>
        {
            // Make this event handler run just before GenerateIdentityModelAccessToken
            builder.SetOrder(GenerateIdentityModelAccessToken.Descriptor.Order - 1)
                // Only run the event handler if an access token was generated
                .AddFilter<RequireAccessTokenGenerated>()
                .SetType(OpenIddict.Server.OpenIddictServerHandlerType.Custom)
                .UseInlineHandler(context =>
                {
                    // Clone the existing AccessTokenPrincipal without the private OpenIddict claims
                    context.AccessTokenPrincipal = context.AccessTokenPrincipal.Clone(claim => claim.Type is not (
                        Claims.Private.AuthorizationId or
                        Claims.Private.Presenter
                    ));
                    return default;
                });
        });
    });

I don't want the access token to include those claims because they appear to be specific to OpenIddict and my resource servers that don't use OpenIddict won't know what to do with those claims.

I don't recommend removing those claims. The authorization identifier (oi_au_id) binds the token with the authorization used to issue it and is used by things like the introspection endpoint to ensure that the authorization is still valid before returning a valid response.

Standard implementations are expected to ignore claims they don't understand so keeping them shouldn't be a problem.

If you're still 100% convinced removing them is the right thing to do, you can use the events model to remove these claims from the principal before the JWT token is created (the ProcessSignInContext event context is the one you'll need). For more info about the events model, read https://kevinchalet.com/2020/02/18/creating-an-openid-connect-server-proxy-with-openiddict-3-0-s-degraded-mode/.

Related