Skip to content
Still using open source IdentityServer4? Upgrading may be easier than you think. Get a FREE assessment

Token Endpoint

The client library for the token endpoint (OAuth 2.0 and OpenID Connect) is provided as a set of extension methods for HttpClient. This allows creating and managing the lifetime of the HttpClient the way you prefer - e.g. statically or via a factory like the Microsoft HttpClientFactory.

The main extension method is called RequestTokenAsync - it has direct support for standard parameters like client ID/secret (or assertion) and grant type, but it also allows setting arbitrary other parameters via a dictionary. All other extensions methods ultimately call this method internally:

var client = new HttpClient();
var response = await client.RequestTokenAsync(new TokenRequest
{
Address = "https://demo.duendesoftware.com/connect/token",
GrantType = "custom",
ClientId = "client",
ClientSecret = "secret",
Parameters =
{
{ "custom_parameter", "custom value"},
{ "scope", "api1" }
}
});

The response is of type TokenResponse and has properties for the standard token response parameters like access_token, expires_in etc. You also have access to the raw response and to a parsed JSON document (via the Raw and Json properties).

Before using the response, you should always check the IsError property to make sure the request was successful:

if (response.IsError) throw new Exception(response.Error);
var token = response.AccessToken;
var custom = response.Json.TryGetString("custom_parameter");

Requesting a token using the client_credentials Grant Type

Section titled “Requesting a token using the client_credentials Grant Type”

The RequestClientCredentialsToken extension method has convenience properties for the client_credentials grant type:

var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = "https://demo.duendesoftware.com/connect/token",
ClientId = "client",
ClientSecret = "secret",
Scope = "api1"
});

Requesting a token using the password Grant Type

Section titled “Requesting a token using the password Grant Type”

The RequestPasswordToken extension method has convenience properties for the password grant type:

var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = "https://demo.duendesoftware.com/connect/token",
ClientId = "client",
ClientSecret = "secret",
Scope = "api1",
UserName = "bob",
Password = "bob"
});

Requesting a token using the authorization_code Grant Type

Section titled “Requesting a token using the authorization_code Grant Type”

The RequestAuthorizationCodeToken extension method has convenience properties for the authorization_code grant type and PKCE:

var response = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
{
Address = IdentityServerPipeline.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
Code = code,
RedirectUri = "https://app.com/callback",
// optional PKCE parameter
CodeVerifier = "xyz"
});

Requesting a token using the refresh_token Grant Type

Section titled “Requesting a token using the refresh_token Grant Type”

The RequestRefreshToken extension method has convenience properties for the refresh_token grant type:

var response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
RefreshToken = "xyz"
});

The RequestDeviceToken extension method has convenience properties for the urn:ietf:params:oauth:grant-type:device_code grant type:

var response = await client.RequestDeviceTokenAsync(new DeviceTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "device",
DeviceCode = authorizeResponse.DeviceCode
});