How to register an OAuth 2.0 / OpenID Connect client

1. Why sign-up clients?

Client applications need to be signed up with the Connect2id server before they can login end-users with OpenID Connect or request OAuth 2.0 access tokens.

What kind of client information is typically registered?

  • The methods, or grant types in OAuth jargon, which the client application is going to use to obtain the end-user's authorisation and tokens.

  • Additional required parameters or options for the chosen grant types, for example the redirection URIs for the client application.

  • Metadata, such as the application's name, logo and terms of service, to be displayed in the login / consent UI. That data is not mandatory, but it's good to have for best overall user experience.

For each successfully registered client the Connect2id server will provision

  • A unique client ID;

  • A client secret (or password). It is used to authenticate client requests to the server, and must therefore be securely stored and not shared with third parties;

  • A special registration access token to enable the client application to read, update or delete its registration, or to refresh the client secret. Must also be kept safe.

2. The client registration endpoint

Clients register at a RESTful endpoint advertised in the Connect2id server metadata. Its URL has the following form:

https://[connect2id-server-base-url]/client-reg/

3. Controlling access to the registration endpoint

Unless open registration is permitted by the server, an access token is required to sign up a new client. This can be the configured master access token for the client registration endpoint, or a specially provisioned one-time access token.

Even with enabled open registration, an access token is still required to sign up a client for certain OAuth 2.0 grant types (such as password), or to set the scope registration parameter.

The access token, of type bearer, must be passed with the Authorization header of the HTTP request:

Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

If you fail to pass an access token and open registration is disabled, the server will respond with the following error:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

Here's the error for an invalid token:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", error_description="Invalid access token"

4. Examples

Let's now sign up a few example clients with the demo Connect2id server, which permits open registration and has its client registration endpoint at

Endpoint URL https://demo.c2id.com/c2id/client-reg

4.1 Minimal registration

To sign up an OpenID Connect client for the default code flow it suffices to specify the redirection URL where the client expects to receive logged-in end-users with the authorisation code generated by the Connect2id server.

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json

{
  "redirect_uris" : ["https://client.example.org/callback" ]
}

With curl:

curl -s -XPOST -H"Content-Type:application/json" \
-d '{"redirect_uris":["https://client.example.org/callback"]}' \
https://demo.c2id.com/c2id/client-reg

Successful registration is indicated by a 200 or 201 HTTP status. The response body will contain a JSON object with the registered and provisioned parameters for the client.

As mentioned in the beginning, the server will provision the following important parameters for your client, which must be kept safe:

  • The client_id and client_secret credentials to authenticate the client in future login and token requests.

  • The registration URI and access token to read, modify or delete the client registration later, in a RESTful manner.

Some parameters will assume the following default values it not explicitly specified in the registration request:

  • The client will be registered for the OAuth 2.0 authorization_code grant type and the code response type.

  • The client authentication method at the token endpoint will be client_secret_basic.

  • ID tokens issued to the client will be signed using the server's public RSA JSON Web Key (JWK) using the RS256 algorithm.

The other parameters matter less; you can read about them in the OpenID Connect spec.

The response will also confirm the registered redirection URL. Note that you may register more than one if required by your app.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "client_id"                    : "5def774h6caci",
  "client_id_issued_at"          : 1412671298,
  "client_secret"                : "AITXP49gecnFP83u1Mjot9xz7Hgu4u4lYBrTxvNtq1k",
  "client_secret_expires_at"     : 0,
  "registration_client_uri"      : "https://demo.c2id.com/c2id/client-reg/5def774h6caci",
  "registration_access_token"    : "jZNmlyJeo3V2j14fynmDthWjbizNYe2fc5pYW27fReo",
  "grant_types"                  : [ "authorization_code" ],
  "response_types"               : [ "code" ],
  "redirect_uris"                : [ "https://client.example.org/callback" ],
  "token_endpoint_auth_method"   : "client_secret_basic",
  "application_type"             : "web",
  "subject_type"                 : "public",
  "id_token_signed_response_alg" : "RS256",
  "require_auth_time"            : false
}

If some part of the request is invalid or malformed, you will get a 400 Bad Request error:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "error"             : "invalid_redirect_uri",
  "error_description" : "Invalid redirection URI(s): Redirection URIs must have a schema"
}

4.2 Specifying client app details for display to end-users

When browsers get redirected to the Connect2id server to sign-in an end-user it's nice to be able to display the application's name, logo and other helpful information.

The client registration specs define several parameters for that:

  • client_name -- The name of the client app. This parameter should always be provided.

  • logo_uri -- The logo or icon URL of the client. Must point to a suitable image to be displayed in the browser. Also good to have.

  • client_uri -- Link to the home page of the client.

  • policy_uri -- Link to the privacy policy document.

  • tos_uri-- Link to the terms-of-service document.

To cater for international audiences the client details can be provided in multiple locales, by appending language tags to the parameter names:

"client_name#en" : "My Express Shop",
"client_name#es" : "Mi Tienda Exprés"

Let's now sign up another client, and provide its name, logo and other details:

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json

{
  "redirect_uris" : [ "https://client.example.org/callback" ],
  "client_name"   : "My Example App",
  "logo_uri"      : "http://client.example.org/logo.png",
  "client_uri"    : "http://client.example.org",
  "policy_uri"    : "http://client.example.org/privacy-policy.html",
  "tos_uri"       : "http://client.example.org/terms-of-service.html"
}

The server response with the registration confirmation:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "client_id"                    : "ug2sb5zkcmpsi",
  "client_id_issued_at"          : 1412692755,
  "client_secret"                : "DUdXNieQ8fwF07surrra8htYc5f_yED0MxuM21yw7W8",
  "client_secret_expires_at"     : 0,
  "registration_client_uri"      : "https://demo.c2id.com/c2id/client-reg/ug2sb5zkcmpsi",
  "registration_access_token"    : "5YHead_Ir8rNQP2KYW31XZHvca7Xk0qi6HKoS-OoTZg",
  "grant_types"                  : [ "authorization_code" ],
  "response_types"               : [ "code" ],
  "redirect_uris"                : [ "https://client.example.org/callback" ],
  "token_endpoint_auth_method"   : "client_secret_basic",
  "client_name"                  : "My Example App",
  "logo_uri"                     : "http://client.example.org/logo.png",
  "client_uri"                   : "http://client.example.org",
  "policy_uri"                   : "http://client.example.org/privacy-policy.html",
  "tos_uri"                      : "http://client.example.org/terms-of-service.html",
  "application_type"             : "web",
  "subject_type"                 : "public",
  "id_token_signed_response_alg" : "RS256",
  "require_auth_time"            : false
}

4.3 How to register for specific OAuth 2.0 grant types or response types

If the sign up request doesn't specify explicit OAuth 2.0 grant types the assumed value is authorization_code. As for the response types, they default to the single code value.

Clients may sign up for other grant / response types, provided the Connect2id server is prepared to handle them. This can be established by checking the advertised provider metadata, which the demo server has published at

https://demo.c2id.com/c2id/.well-known/openid-configuration

Let's register an OpenID Connect client for the implicit grant. This grant provides a simplified authorisation flow and is intended for clients implemented in a browser with scripting language such as JavaScript. Matching response types for the implicit grant type are id_token and id_token token:

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json

{
  "redirect_uris"  : [ "https://client.example.org/callback" ],
  "grant_types"    : [ "implicit" ],
  "response_types" : [ "id_token", "token id_token" ]
}

You can also register a combination of several grant and response types. A special algorithm in the Connect2id server will ensure that the grant and response types are consistent with each other; those that are not will be automatically stripped.

To sign up a client for the authorization_code, implicit and refresh_token grants:

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json

{
  "redirect_uris"  : [ "https://client.example.org/callback" ],
  "grant_types"    : [ "authorization_code", "implicit", "refresh_token" ],
  "response_types" : [ "code", "id_token", "token id_token" ]
}

4.4 How to register a client for the password grant

Use of the password grant carries higher security risks and thefore to sign up a client for it an access token is always required. This can be the configured master access token for the client registration endpoint, or a specially provisioned one-time access token.

Minimal sign up request for the password grant:

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

{
  "grant_types" : [ "password" ]
}

The scope parameter can be used to convey special information to the password grant handler, e.g. the range of scope values that the client is authorised to use:

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

{
  "grant_types" : [ "password" ],
  "scope"       : "openid email app:read app:write"
}

4.5 How to register a client for the client credentials grant

The client credentials grant is intended for clients that act on their own behalf (the client is also the resource owner), as opposed to the general case (on behalf of an end-user).

An access token is also always required here.

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

{
  "grant_types" : [ "client_credentials" ]
}

As with the password grant client, the scope parameter may be required by the grant handler, e.g. to bound the scope values that the client is authorised to use:

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

{
  "grant_types" : [ "client_credentials" ],
  "scope"       : "myapi:post myapi:get myapi:delete"
}

4.6 How to register a grant-less client

The Connect2id server also supports registration of special "grant-less" clients that will not be using the standard token endpoint; instead, they will be issued tokens via the direct authorisation endpoint.

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

{
  "grant_types"    : [ ],
  "response_types" : [ ]
}

4.7 How to register a client with a preset client_id and / or client_secret

When the Connect2id server registers a new client it generates a random client_id for it. If the chosen client authentication method, ID token JWS algorithm or UserInfo JWS algorithm require it, it also generates a secret of the appropriate length.

This is the standard behaviour and fine for most situations. You may however want to preset the client identifier and / or secret to a specific value, if migrating existing clients to the Connect2id server for example.

To do that make a registration request with the master API access token using the following non-standard parameters to specify the desired values:

  • preferred_client_id to preset the client identifier
  • preferred_client_secret to preset the client secret

For example, to register a client with a preset client_id and client_secret for the password grant:

POST /c2id/client-reg HTTP/1.1
Host: demo.c2id.com
Content-Type: application/json
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6

{
  "grant_types"             : [ "password" ],
  "preferred_client_id"     : "123456",
  "preferred_client_secret" : "ahL7AhthchiNg6beAo5HeijeThae3deiChab7ajiVuip2eodesoBie0ufohtiiK4"
}

The server will then register the client under the preferred identifier and secret, provided there's no collision with an existing client and the secret is not too short.

In case the client_id is already taken you will get a standard invalid_client_metadata error:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
 "error"             : "invalid_client_metadata",
 "error_description" : "Invalid client metadata field: The preferred client_id is already in use"
}

In case the secret is to short for the chosen client authentication method, ID token JWS algorithm or UserInfo JWS algorithm, the Connect2id server will return the following error:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
 "error"             : "invalid_client_metadata",
 "error_description" : "Invalid client metadata field: The preferred secret must be at least 256 bits"
}

This feature has been added in Connect2id server version 2.2 (2.5 for the preferred client secret).

5. References

Client registration is defined in three specs: