openiddict token expires_in

发布时间 2023-05-15 09:51:19作者: dreamw

How can I add custom claims to be returned when requesting a token using OpenIddict?

4

I'm building ASP.NET Core 1.1 app (cross platform) and trying (using this sample) to add custom claims to the returned access_token when requesting /connect/token endpoint.
What I need is to not only return the claims serialized in the access_token but to return them in the response like this:

{
 "token_type": "Bearer",
 "access_token": "...",
 "expires_in": 1799,
 "custom_claim": "..."
}

What I found on internet that I have to use AspNet.Security.OpenIdConnect.Server and write my provider in order to be able to do what I want.
Isn't there a simple way using the first sample ?
I'm using OAUth 2.0, grant type Password and no JWT.
Not a requirement to not use JWT, it's just I used to OAuth in ASP.NET 4.5

  •  
    Is there a specific reason you need it in that format? Deserializing the payload portion of the returned token is very simple even in javascript? Just curios as to why you would want them like in your example.   Nov 9, 2016 at 9:47
  •  
    @LouisLewis I'm not using JWT, so deserializing is not applicable as I think, even if I used JWT i'm not able to return the custom claims in the token. 
    – Dabbas
     Nov 9, 2016 at 10:00 

3 Answers

5
 

What I need is to not only return the claims serialized in the access_token but to return them in the response like this:

While I encourage you to store these claims in identity tokens - so that they can be easily read by the client in a completely standard way, it's possible in OpenIddict 1.0 and 2.0 RTM. For that, you have 2 options:

Using a special "public" property (in your authorization controller, where authentication tickets are created):

ticket.SetProperty("custom_claim" + OpenIddictConstants.PropertyTypes.String, user.Id);

Note: OpenIddictConstants.PropertyTypes.String is a special suffix indicating the authentication property added to the ticket can be exposed as part of the token response. Other constants are available if you prefer returning your claim as a JSON number or a more complex JSON structure.

Using the events model (in Startup.cs):

services.AddOpenIddict()

    // Register the OpenIddict core services.
    .AddCore(options =>
    {
        // ...
    })

    // Register the OpenIddict server handler.
    .AddServer(options =>
    {
        // ...

        options.AddEventHandler<OpenIddictServerEvents.ApplyTokenResponse>(
            notification =>
            {
                if (string.IsNullOrEmpty(notification.Context.Error))
                {
                    var principal = notification.Context.Ticket.Principal;
                    var response = notification.Context.Response;
                    response["custom_claim"] = principal.FindFirst("your_claim_attached_to_the_principal").Value;
                }

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

    // Register the OpenIddict validation handler.
    .AddValidation();
  •  
    Hello Kevin, I am new to oppeniddict, In the latest version 3.0.1 of oppeniddict this code is obsolete, can you please, show us how to pass custom claims in the current version. I have tried this but it doesn't work: options.AddEventHandler<ApplyTokenResponseContext>(builder => { builder.UseInlineHandler(context => { if (string.IsNullOrEmpty(context.Error)) { var principal = context.Principal; var response = context.Response; response.AddParameter("custom_claim", "test"); } return default; }); }); The custom claim is not recieved by the client app.   Feb 10, 2021 at 23:04
  •  
    @user2507201 hi. What you have is fine and should work (and works on my machine). Not sure what's going on.   Feb 10, 2021 at 23:20
  •  
    You are right, it works perfectly, my mistake. Thank you.   Feb 11, 2021 at 8:51
2

Well, we did it by using the Events property of the OpenIdConnectOptions in the Configure method of the Startup class when you add the Open Id Connect middleware, like this for instance:

            Events = new OpenIdConnectEvents
            {
                OnTicketReceived = n =>
                {
                    //TODO Your logic here to add custom claims via n.Principal.Identities.First().AddClaims();

                    return Task.CompletedTask;
                }
            }

Is that an option for your use case?

0

As an answer from @Pinpoint in his repository of openiddict-samples I followed this article (in the Implementing the Connect/Token Endpoint section)..
I figured out from his answer that what I'm trying to do is not standard, that's why it's not so obvious and easy to do.
You need to use JWT and add the custom claims to it so that the client can decode it and get the claims, not send them through the response it self.

  • 1
    Note: don't use JWT as the access token format if you only want to share claims between your authorization server and your client application. Instead, attach the OpenIdConnectConstants.Destinations.IdentityToken destination to your claims and add scope=openid to retrieve an identity token (necessarily a JWT by definition) you'll be able to introspect to retrieve the claims you need.   Nov 9, 2016 at 13:19
  •  
    @Pinpoint I want to return the access_token along with claims. 
    – Dabbas
     Nov 9, 2016 at 13:23
  •  
    The identity token is a separate token (id_token).   Nov 9, 2016 at 13:25
  •  
    @Pinpoint sorry I'm not expert in JWT and OAuth, but what's wrong with using JWT ? 
    – Dabbas
     Nov 9, 2016 at 13:26
  • 1
    There's nothing wrong. What's wrong is trying to read an access token from the client code (which is not supposed to do that, because it's not the intended audience of the token).   Nov 9, 2016 at 13:27
 
 
------>https://github.com/openiddict/openiddict-samples/issues/16