How to add custom claim to a token in Duende under Client Credential flow?

588 Views Asked by At

Currently, I'm using a working Client Credential Flow. I'd like to extend the behavior of the IDP and add a claim besides the ones distributed automatically based on the client.

Checking the docs for Client Credential Flow, didn't give me much. What I hoped for, was to implement IProfileService but noticed that it's not being invoked (since it's handling user claims, not client claims). Checking the docs for the other services, I couldn't recognize anything similar to what I need (possibly missing the obvious due to confusion).

Let's assume the scenario that a service accesses the client, passing the correct client ID and secret but also a GUID in the header or in the payload together with the grant type etc. Now, I'd like to issue a JWT with the claims based on the client but with two alternations. Partly, I'd like to add a custom claim (based on the passed GUID). Partly, I'd like to remove one of the provided claims (also based on the passed GUID).

How can I do that?

The efforts gave me mostly hits on Auth0's stuff and some for Curity and others. Duende must have something similar as well, don't they?

There's an answer to that telling me "no" but I feel it's not precise. I don't want to change to the obsolete Resource Owner Flow (deprecation and requirement for user interaction). I feel that it should be possible to pick a custom passed value and somehow horse around with the issued JWT. Another answer suggests that it's (theoretically) possible but they did that in Azure and I host my own authority.

The best shot I've seen is this answer regarding ITokenResponseGenerator. However, both mention something about DI and a factory, which puzzles me, as there's no samples to check out. So I can't try it out, regrettably...

Is that the proper approach and if so, how can I push in my custom implementation of the generator to be applied?

1

There are 1 best solutions below

1
On

We need to extend TokenResponseGenerator class in Duende and override ProcessAuthorizationCodeRequestAsync as below.

internal class CustomTokenResponseGenerator : TokenResponseGenerator
{
    public CustomTokenResponseGenerator(ISystemClock clock, ITokenService tokenService, IRefreshTokenService refreshTokenService, IScopeParser scopeParser, IResourceStore resources, IClientStore clients, ILogger<TokenResponseGenerator> logger) : base(clock, tokenService, refreshTokenService, scopeParser, resources, clients, logger)
    {
    }
    protected override async Task<TokenResponse> ProcessAuthorizationCodeRequestAsync(TokenRequestValidationResult request)
    {
        var result = await base.ProcessAuthorizationCodeRequestAsync(request);

        if (result != null)
        {
            //If you need to get user details you can use below context
            
             var user = request.ValidatedRequest.Subject; 
             var userClaims = user.Claims;  
           
             if (result.Custom == null)
             {
                result.Custom = new Dictionary<string, object>();
             }
             result.Custom.Add("CustomProperty","SomeValue");
        }

        return result;
    }
}

Once we have defined the above implementation we can register to DI

builder.Services.AddTransient<ITokenResponseGenerator, CustomTokenResponseGenerator>();

This will override the default implementation of Duende.