user1574598
user1574598

Reputation: 3881

Extension Grants - Invalid Grant Type Delegation - Identity Server 4 .NET Core 2.2

I am trying to figure out how to implement a delegation grant type in conjunction with client credentials, by following the tutorial from HERE, which is literally one page, since I have and API1 resource calling another API2 resource.

I've implemented the IExtensionGrantValidator and copied the code from the docs using the class name they provided, and added the client with grant type delegation. However, I am not sure where and how to call this method below, at first I was calling it from the client and tried passing the JWT I initially got to call API1 to the DelegateAsync method but I kept getting a bad request

In API 1 you can now construct the HTTP payload yourself, or use the IdentityModel helper library:

    public async Task<TokenResponse> DelegateAsync(string userToken)
    {
        var payload = new
        {
            token = userToken
        };

        // create token client
        var client = new TokenClient(disco.TokenEndpoint, "api1.client", "secret");

        // send custom grant to token endpoint, return response
        return await client.RequestCustomGrantAsync("delegation", "api2", payload);
    }

So, I tried from API1 requesting a token in a method called GetAPI2Response which attempts to call a method in API2:

        [HttpGet]
        [Route("getapi2response")]
        public async Task<string> GetApi2Response()
        {
            var client = new HttpClient();

            var tokenResponse = await client.RequestTokenAsync(new TokenRequest
            {
                Address = "http://localhost:5005/connect/token",
                GrantType = "delegation",
                ClientId = "api1_client",
                ClientSecret = "74c4148e-70f4-4fd9-b444-03002b177937",

                Parameters = { { "scope", "stateapi" } }
            });

            var apiClient = new HttpClient();
            apiClient.SetBearerToken(tokenResponse.AccessToken);

            var response = await apiClient.GetAsync("http://localhost:6050/api/values");

            if (!response.IsSuccessStatusCode)
            {
                Debug.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();

                return content;
            }
            return "failed";
        }

However, this returns when debugging an invalid grant type. Strangely, I noticed when running IDSRV the code in the IExtensionGrantValidator method does not get hit, until you click the link for the discovery docs then it appears as a grant type

I'm obviously doing something wrong since I am not including the aforementioned DelegateAsync method from the docs, as its not clear to me where it goes.

Upvotes: 4

Views: 2434

Answers (1)

d_f
d_f

Reputation: 4859

The docs seem to be a bit outdated. With the actual extension methods there must be something like:

var tokenResponse = await client.RequestTokenAsync(new TokenRequest
{
    Address = "http://localhost:5005/connect/token",
    GrantType = "delegation",
    ClientId = "api1_client",
    ClientSecret = "74c4148e-70f4-4fd9-b444-03002b177937",
    Parameters = new Dictionary<string, string>{{ "token", userToken }, { "scope", "stateapi" } }
})

you already implemented it, but forgot to add the initial token. When you extract it from the GetApi2Response() it can become your DelegateAsync.

Then your client configuration in Identityserver has to contain the delegation GrantType for the api1_client. Also don't forget the registration:

services.AddIdentityServer().AddExtensionGrantValidator<YourIExtensionGrantValidatorImpl>()

Upvotes: 3

Related Questions