How to use the OAuth Dynamic Client Registration

Using Dynamic Client Registration

On this page

Dynamic client registration (DCR) allows new clients to be registered using a standard API. For more details about the architectural structure of dynamic client registration, see Dynamic Client Registration Overview. This article illustrates how to implement dynamic client registration and uses the Curity Identity Server as an example.

Initial Access Token

Dynamic client registration is usually protected using OAuth. This means that the client typically needs to present an initial access token in its registration request. With the Curity Identity Server, the initial access token is a one-time token with the dcr scope. Other vendors have similar requirements.

There are multiple ways to obtain an initial access token. The Curity Identity Server supports the client credentials flow or a user interactive flow such as the code flow. Other vendors may offer similar methods or even out-of-band mechanisms to provide the application with the initial access token.

This overview does not explain in detail how to obtain the token but focuses on how to register the client once it has obtained the token.

Client Registration Request

Using dynamic client registration, the client sends an API call to the client registration endpoint at the authorization server. As mentioned before, this endpoint is typically protected and requires the client to include an access token in the request, e.g., in the Authorization request header using the bearer authentication scheme (per RFC 6750).

To register a client, the request must contain all metadata for that client. Which metadata to include depends on the context, like the client's capabilities. OAuth authorization servers usually support common client metadata and request parameters. Note though, their vendors may also have proprietary interpretations of certain parameters. The following list describe the characteristics of the client registration request.

  • Method: POST
  • Agent: Backend
  • Content Type: application/json
  • Response Type: application/json

The body of the request is a JSON document, as indicated by the content type. The following section provides a non-exhaustive overview of the parameters to include in that document.

Request Parameters

Primary Parameters

ParameterValueMandatoryDescription
scopeStringnoA string containing the scope values the client may use, separated by space.
grant_typesArraynoA list of grant types that the client supports. If omitted, the default value is authorization_code.
redirect_urisArrayyes*A list of the client's callback URLs. *Required if the client registers for a flow that uses redirects, such as the code flow.
response_typesArraynoA list of response types. Only used for browser-based flows. If omitted, the default value is code.
token_endpoint_auth_methodStringnoA string describing the authentication method this client intends to use when authenticating at the authorization server. If omitted, the default value is client_secret_basic.

Additional Parameters

ParameterValueMandatoryDescription
client_nameStringnoA human-readable name of the client.
client_uriURLnoURL of the home page of the client.
logo_uriURLnoA link to the logo representing the client.
tos_uriURLnoA link to the terms of service for the client.
policy_uriURLnoA link to the policy for profile data for the client.
software_statementJWTnoA signed JWT containing the client's metadata. Usually the same across multiple clients that are associated with the same application.
software_idStringnoA string identifying the application the client is associated with. Multiple clients (client instances) can share the same software ID.

OpenID Connect Related Parameters

ParameterValueMandatoryDescription
default_acr_valuesArraynoA list of ACR values to use by default when authenticating the user for requests from the registered client.
default_max_ageIntegernoA default value in seconds for the maximum age of the authentication. If the session is older than the given value, the authorization server must re-authenticate the user.
sector_identifier_uriURLnoA URL to calculate Pairwise Pseudonym Identifiers (PPID) for this client.
subject_typepairwise or publicnoWhether the subject in the ID token should be unique for the client (pairwise) or whether it is the same for all clients (public).
frontchannel_logout_uriURLnoURL that the authorization server can render in an iframe to log the user out from the client.
backchannel_logout_uriURLnoURL that the authorization server can call to log the user out from the client.

Parameters Related to Request Objects

ParameterValueMandatoryDescription
require_signed_request_objectBooleannoIndicates whether the client uses signed request objects in its authorization request. The authorization server must reject authorization requests without signed request objects. If omitted, the default value is false.
request_object_signing_algStringnoThe JWS algorithm that the client uses to sign its request object. The authorization server must reject any signed request objects that do not use the given algorithm.
require_pushed_authorization_requestBooleannoIndicates whether the client uses PAR to initiate authorization requests. If omitted, the default value is false.

Parameters Related to Client-Initiated Backchannel Authentication (CIBA)

The client can indicate its support for CIBA by including the grant type urn:openid:params:grant-type:ciba. In addition, the registration request also needs to contain the following parameters.

ParameterValueMandatoryDescription
backchannel_token_delivery_modepoll, ping or pushyesSpecifies how the client wants to retrieve authentication results.
backchannel_client_notification_endpointURLyes*A URL that the authorization server should call when the authentication results are available. *Required if the delivery method is ping or push.
backchannel_user_code_parameterBooleannoIndicates whether the client supports user codes. If omitted, the default value is false.

Extension Parameters

The registration request may contain any other request parameters not specified in any official standard document. For example, the Curity Identity Server also supports the following proprietary parameters.

ParameterValueMandatoryDescription
allowed_originsArraynoList of origins that should be allowed to frame the application.
application_urlURLnoA link to redirect the user to if the session times out.
authenticator_filtersArraynoA list of IDs of the authenticator filters to apply to the authenticator selection.
disallowed_proof_key_challenge_methodsArraynoList of PKCE challenge methods to disable for the client.
requires_consentBooleannoIndicates whether the client wants the authorization server to prompt users with consent screens. If omitted, the default value is false.
require_proof_keyBooleannoIndicates whether the client uses PKCE. If omitted, the default value is false.
access_token_ttlIntegernoThe time-to-live in seconds for the access token.
If omitted, the Curity Identity Server uses a configurable default value.
id_token_ttlIntegernoThe time-to-live in seconds for the ID token.
If omitted, the Curity Identity Server uses a configurable default value.
refresh_token_ttlIntegernoThe time-to-live in seconds for the refresh token.
If omitted, the Curity Identity Server uses a configurable default value.

Client Authentication Methods

The following is a non-exhaustive list of valid values for the token_endpoint_auth_method parameter.

MethodDescription
noneThe client is a public client that does not support any authentication method.
client_secret_basicThe client uses the HTTP Basic authentication scheme to send its client ID and client secret.
private_key_jwtThe client authenticates with a self-signed JWT.
tls_client_authThe client authenticates using mutual TLS.

Grant Types and Flows

The following is a non-exhaustive list of valid values to include in the grant_types parameter.

Grant TypeDescription
authorization_codeThe authorization code flow.
implicitThe implicit flow.
passwordThe resource owner password flow.
client_credentialsThe client credentials flow.
urn:ietf:params:oauth:grant-type:device_codeThe device authorization flow.
urn:openid:params:grant-type:cibaClient initiated backchannel authentication flow.
urn:ietf:params:oauth:grant-type:token-exchangeToken exchange flow.

Response Types

The following is a non-exhaustive list of valid values to include in the response_types parameter.

Response TypeDescription
codeThe authorization code flow
tokenThe implicit flow
id_tokenThe implicit openid flow or the hybrid flow (together with code and token)

Example Request

The following listing shows an example request.

http
123456789101112131415
POST /dcr HTTP/1.1
Host: localhost:8443
Authorization: Bearer 9e565e0b-a487-4092-a4af-461add3155f2
Content-Type: application/javascript
{
"scope": "openid read foo test_scope_1",
"redirect_uris": [ "https://localhost:9000/cb" ],
"grant_types": [ "authorization_code" ],
"response_types": "code",
"client_name": "monkey",
"client_uri": "https://localhost:9000/",
"tos_uri": "https://localhost:9000/tos",
"default_max_age": 44
}

Registration Response

The response from the client registration endpoint is a JSON document that reflects the accepted values.

Example

javascript
12345678910111213141516171819202122232425262728
{
"grant_types": [
"authorization_code",
"refresh_token",
"implicit",
"password"
],
"subject_type": "public",
"redirect_uris": [
"https://localhost/client-one/cb1",
"https://localhost/client-one/cb2"
],
"client_id": "5bc6f48b-b3c4-413d-a374-20a77ffd1d59",
"token_endpoint_auth_method": "client_secret_basic",
"software_id": "client-one",
"client_secret_expires_at": 0,
"scope": "openid",
"client_secret": "E4wYA0LOU7hQd-DDh6W2rrqP-OnSsj3pAk243a-j-oE",
"client_id_issued_at": 1503067741,
"client_name": "client-one",
"response_types": [
"code",
"token",
"id_token"
],
"refresh_token_ttl": 3600,
"id_token_signed_response_alg": "RS256"
}

Registration Using a Template Client

In some use cases, such as when you use DCR for mobile clients you want multiple registered clients to use almost identical settings. With the Curity Identity Server, you can use a template client to share settings between dynamically registered clients. This approach simplifies client registration because it only requires a single request parameter, the software_id. This ID (as defined in RFC 7591) is the client ID of the template client.

Templatized Request

  • Method: POST
  • Agent: Backend
  • Content Type: application/json
  • Response Type: application/json

Request Parameters

ParameterValueMandatoryDescription
software_idStringyesThe ID of the template client to instantiate a new client from.

If a registration request contains a software_id and if its value matches the client ID of a template client, the Curity Identity Server uses the settings from the corresponding template. If such a request contains other parameters next to the software_id, the Curity Identity Server ignores them. The settings from a template always take precedence.

Example Request Using Template Client

The following listing shows an example of a templatized request.

http
123456
POST /dcr HTTP/1.1
Host: localhost:8443
Authorization: Bearer 9e565e0b-a487-4092-a4af-461add3155f2
Content-Type: application/javascript
 
{ "software_id": "webapp-client" }

The Curity Identity Server returns the values in the response according to the configuration in the template.

Conclusion

Dynamic client registration is a powerful way of managing OAuth clients when static configuration is not suitable. A registration request includes similar properties to those that you would set in an admin user interface for static clients. The authorization server sets the final client properties and returns them to the client in the registration response. When you use a template client, you can use the Admin UI to create all common client properties in advance of any registration requests.

Photo of Jacob Ideskog

Jacob Ideskog

Identity Specialist and CTO at Curity

Newsletter

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Newsletter

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial