Search code examples
identityserver4

How to add grant type into access token in IdentityServer4?


I need to know the client's grant type (or OAuth Flow type) in my API protected by IdentitySrever4, but not sure how to do that. I am assuming that I need to add the grant type to the access token. Can someone help me by pointing me to instructions/documentations or sample code?

UPDATE

Under standard IdentityServer4 EF model, my SQL Server data store has a ClientGrantTypes table and a ClientClaims table (see screenshot below). I am assuming that I need to create a ClientClaims record that ties into ClientGrantTypes. If it is SQL, you can just join the tables on ClientID, but how do you implement it here to get the Grant Type into access token?

enter image description here


Solution

  • It would be easier to find the answer if you explained the purpose for the requirement.
    From my experience one common task is to distinguish authorization_code and client_credentials flow use for the same client, but that's easy: the second one does not contain user information (sub and sid claims).
    Also don't forget about restricted auth flow combinations in Identityserver (for instance you can't allow both implicit and authorization_code flow for the same client), so one client is usually bound to the only user interactive flow.
    Finally, the auth flow is generally not about API. It's only about interaction among IdP and Client. API usually use scopes as general information about clients, so... when you have two clients -- one with implicit grant and the other with authorization_code, you can distinguish which one is in use by setting different scopes.
    Isn't that enough?

    A check for a particular grant type could be performed in Identityserver the following way:

    public class ExtendedClaimsService : DefaultClaimsService{
        public override async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(
                ClaimsPrincipal subject,
                ResourceValidationResult resourceResult,
                ValidatedRequest request)
        {
            var outputClaims = (await base.GetAccessTokenClaimsAsync(subject, resourceResult, request)).ToList();
    
            //if (request.Secret.Type == "NoSecret") //this is more or less the same
            if ((request as ValidatedTokenRequest)?.GrantType != "client_credentials")
                {
                    //filter out server-side-only scopes here
                    //or add any custom claim you like
                }
    
            return outputClaims;
        }
    }
    

    Registration: services.AddTransient<IClaimsService, ExtendedClaimsService>(); after services.AddIdentityServer() in your Startup