OpenID Connect client registration and management
Client applications (also called relying parties) must be registered with an OpenID provider before they can authenticate users with it.
A standard RESTful API is devised to facilitate the registration of clients and the subsequent management of their data:
- OpenID Connect Dynamic Client Registration 1.0 -- defines a protocol and metadata for registering and querying OpenID Connect relying parties;
- OAuth 2.0 Dynamic Client Registration Management Protocol (RFC 7592) -- defines additional UPDATE and DELETE operation for managing a client's existing registration.
Depending on the OpenID Connect provider policy, access to the registration endpoint can be open, require pre-approval, or it may even be hidden behind some developer portal. The Connect2id server requires a master API token to register clients, unless some other access method is configured.
Registering a new OpenID Connect client
Example request to register a client for the code grant (flow):
import com.nimbusds.oauth2.sdk.*;
import com.nimbusds.oauth2.sdk.client.*;
import com.nimbusds.oauth2.sdk.http.*;
import com.nimbusds.oauth2.sdk.token.*;
import com.nimbusds.openid.connect.rp.*;
// The client registration endpoint
URI clientsEndpoint = new URI("https://demo.c2id.com/c2id/clients");
// Master API token for the clients endpoint
BearerAccessToken masterToken = new BearerAccessToken("ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6");
// We want to register a client for the code grant
OIDCClientMetadata clientMetadata = new OIDCClientMetadata();
clientMetadata.setGrantTypes(Collections.singleton(GrantType.AUTHORIZATION_CODE));
clientMetadata.setRedirectionURI(URI.create("https://example.com/cb"));
clientMetadata.setName("My Client App");
OIDCClientRegistrationRequest regRequest = new OIDCClientRegistrationRequest(
clientsEndpoint,
clientMetadata,
masterToken
);
HTTPResponse httpResponse = regRequest.toHTTPRequest().send();
ClientRegistrationResponse regResponse = OIDCClientRegistrationResponseParser.parse(httpResponse);
if (! regResponse.indicatesSuccess()) {
// We have an error
ClientRegistrationErrorResponse errorResponse = (ClientRegistrationErrorResponse)regResponse;
System.err.println(errorResponse.getErrorObject());
return;
}
// Successful registration
OIDCClientInformationResponse successResponse = (OIDCClientInformationResponse)regResponse;
OIDCClientInformation clientInfo = successResponse.getOIDCClientInformation();
// The client credentials - store them:
// The client_id
System.out.println("Client ID: " + clientInfo.getID());
// The client_secret
System.out.println("Client secret: " + clientInfo.getSecret().getValue());
// The client's registration resource
System.out.println("Client registration URI: " + clientInfo.getRegistrationURI());
// The token for accessing the client's registration (for update, etc)
System.out.println("Client reg access token: " + clientInfo.getRegistrationAccessToken());
// Print the remaining client metadata
System.out.println("Client metadata: " + clientInfo.getMetadata().toJSONObject());
Querying a client's registration
Once the client is registered, its details can always be
queried
at the URL for its resource, e.g. https://demo.c2id.com/c2id/clients/b5noxshmay5xw
using the provided registration access token:
ClientReadRequest readRequest = new ClientReadRequest(
clientInfo.getRegistrationURI(),
clientInfo.getRegistrationAccessToken()
);
httpResponse = readRequest.toHTTPRequest().send();
regResponse = OIDCClientRegistrationResponseParser.parse(httpResponse);
if (! regResponse.indicatesSuccess()) {
// We have an error
ClientRegistrationErrorResponse errorResponse = (ClientRegistrationErrorResponse)regResponse;
System.err.println(errorResponse.getErrorObject());
return;
}
// Success
successResponse = (OIDCClientInformationResponse)regResponse;
System.out.println("Client registration data: " + successResponse.getClientInformation().toJSONObject());
Updating a client's registration
The details of the client registration can also be updated. Here is an example request to update the name of the client that the OAuth 2.0 server displays to the end-user during consent:
// Update client name
clientMetadata = clientInfo.getOIDCMetadata();
clientMetadata.setName("My app has a new name");
// Send request
ClientUpdateRequest updateRequest = new ClientUpdateRequest(
clientInfo.getRegistrationURI(),
clientInfo.getID(),
clientInfo.getRegistrationAccessToken(),
clientMetadata,
clientInfo.getSecret()
);
httpResponse = updateRequest.toHTTPRequest().send();
regResponse = OIDCClientRegistrationResponseParser.parse(httpResponse);
if (! regResponse.indicatesSuccess()) {
// We have an error
ClientRegistrationErrorResponse errorResponse = (ClientRegistrationErrorResponse)regResponse;
System.err.println(errorResponse.getErrorObject());
return;
}
// Success
successResponse = (OIDCClientInformationResponse)regResponse;
// Ensure the client name has been updated
clientInfo = successResponse.getOIDCClientInformation();
System.out.println("Client name: " + clientInfo.getMetadata().getName());
Deleting a client's registration
Finally, the client can request to have its registration deleted:
ClientDeleteRequest deleteRequest = new ClientDeleteRequest(
clientInfo.getRegistrationURI(),
clientInfo.getRegistrationAccessToken()
);
httpResponse = deleteRequest.toHTTPRequest().send();
if (! httpResponse.indicatesSuccess()) {
// We have an error
System.err.println(ClientRegistrationErrorResponse.parse(httpResponse).getErrorObject());
return;
}
// Success: nothing returned