Skip to content
We just launched Duende IdentityServer v7.2.0 and BFF v3.0. Check it out!

Backchannel Authentication Endpoint

The backchannel authentication endpoint is used by a client to initiate a CIBA request.

Clients must be configured with the "urn:openid:params:grant-type:ciba" grant type to use this endpoint. You can use the OidcConstants.GrantTypes.Ciba constant rather than hard coding the value for the CIBA grant type.

  • scope

    one or more registered scopes

  • login_hint

    hint for the end user to be authenticated. the value used is implementation specific.

  • id_token_hint

    a previously issued id_token for the end user to be authenticated

  • login_hint_token

    a token containing information for the end user to be authenticated. the details are implementation specific.

  • binding_message

    identifier or message intended to be displayed on both the consumption device and the authentication device

  • user_code

    a secret code, such as a password or pin, that is known only to the user but verifiable by the OP

  • requested_expiry

    a positive integer allowing the client to request the expires_in value for the auth_req_id the server will return. if not present, then the optional CibaLifetime property on the Client is used, and if that is not present, then the DefaultLifetime on the CibaOptions will be used.

  • acr_values

    allows passing in additional authentication related information - IdentityServer special cases the following proprietary acr_values:

    • idp:name_of_idp

      bypasses the login/home realm screen and forwards the user directly to the selected identity provider (if allowed per client configuration)

    • tenant:name_of_tenant

      can be used to pass a tenant name to the login UI

  • resource

    resource indicator identifying the ApiResource for which the access token should be restricted to

  • request

    instead of providing all parameters as individual parameters, you can provide all them as a JWT

POST /connect/ciba
client_id=client1&
client_secret=secret&
scope=openid api1&
login_hint=alice

And a successful response will look something like:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"auth_req_id": "1C266114A1BE42528AD104986C5B9AC1",
"expires_in": 600,
"interval": 5
}

You can use the Duende IdentityModel client library to programmatically interact with the protocol endpoint from .NET code.

using Duende.IdentityModel.Client;
var client = new HttpClient();
var cibaResponse = await client.RequestBackchannelAuthenticationAsync(new BackchannelAuthenticationRequest
{
Address = "https://demo.duendesoftware.com/connect/ciba",
ClientId = "client1",
ClientSecret = "secret",
Scope = "openid api1",
LoginHint = "alice",
});

And with a successful response, it can be used to poll the token endpoint:

while (true)
{
var response = await client.RequestBackchannelAuthenticationTokenAsync(new BackchannelAuthenticationTokenRequest
{
Address = "https://demo.duendesoftware.com/connect/token",
ClientId = "client1",
ClientSecret = "secret",
AuthenticationRequestId = cibaResponse.AuthenticationRequestId
});
if (response.IsError)
{
if (response.Error == OidcConstants.TokenErrors.AuthorizationPending || response.Error == OidcConstants.TokenErrors.SlowDown)
{
await Task.Delay(cibaResponse.Interval.Value * 1000);
}
else
{
throw new Exception(response.Error);
}
}
else
{
// success! use response.IdentityToken, response.AccessToken, and response.RefreshToken (if requested)
}
}