[[_client_registration]]
== Client Registration

In order for an application or service to utilize {{book.project.name}} it has to register a client in {{book.project.name}}.
An admin can do this through the admin console (or admin REST endpoints), but clients can also register themselves through the {{book.project.name}} client
registration service.

The Client Registration Service provides built-in support for {{book.project.name}} Client Representations, OpenID Connect Client Meta Data and SAML Entity Descriptors.
The Client Registration Service endpoint is `/realms/<realm>/clients-registrations/<provider>`.

The built-in supported `providers` are: 

* default - {{book.project.name}} Client Representation (JSON)
* install - {{book.project.name}} Adapter Configuration (JSON)
* openid-connect - OpenID Connect Client Metadata Description (JSON)
* saml2-entity-descriptor - SAML Entity Descriptor (XML)

The following sections will describe how to use the different providers. 

=== Authentication

To invoke the Client Registration Services you need a token. The token can be a bearer token, an initial access token or a registration access token.

==== Bearer Token

The bearer token can be issued on behalf of a user or a Service Account. The following permissions are required to invoke the endpoints (see link:{{book.adminguide.link}}[{{book.adminguide.name}}] for more details):

* create-client or manage-client - To create clients
* view-client or manage-client - To view clients
* manage-client - To update or delete client

If you are using a bearer token to create clients it's recommend to use a token from a Service Account with only the `create-client` role (see link:{{book.adminguide.link}}[{{book.adminguide.name}}] for more details).

==== Initial Access Token

The recommended approach to registering new clients is by using initial access tokens.
An initial access token can only be used to create clients and has a configurable expiration as well as a configurable limit on how many clients can be created. 

An initial access token can be created through the admin console.
To create a new initial access token first select the realm in the admin console, then click on `Realm Settings` in the menu on the left, followed by `Initial Access Tokens` in the tabs displayed in the page. 

You will now be able to see any existing initial access tokens. If you have access you can delete tokens that are no longer required. You can only retrieve the
value of the token when you are creating it. To create a new token click on `Create`. You can now optionally add how long the token should be valid, also how
many clients can be created using the token. After you click on `Save` the token value is displayed.

It is important that you copy/paste this token now as you won't be able to retrieve it later. If you forget to copy/paste it, then delete the token and create another one.

The token value is used as a standard bearer token when invoking the Client Registration Services, by adding it to the Authorization header in the request.
For example: 

[source]
----
Authorization: bearer eyJhbGciOiJSUz...
----            

==== Registration Access Token

When you create a client through the Client Registration Service the response will include a registration access token.
The registration access token provides access to retrieve the client configuration later, but also to update or delete the client.
The registration access token is included with the request in the same way as a bearer token or initial access token.
Registration access tokens are only valid once when it's used the response will include a new token. 

If a client was created outside of the Client Registration Service it won't have a registration access token associated with it.
You can create one through the admin console. This can also be useful if you loose the token for a particular client.
To create a new token find the client in the admin console and click on `Credentials`. Then click on `Generate registration access token`.

=== {{book.project.name}} Representations

The `default` client registration provider can be used to create, retrieve, update and delete a client.
It uses {{book.project.name}} Client Representation format which provides support for configuring clients exactly as they can be configured through the admin
console, including for example configuring protocol mappers.

To create a client create a Client Representation (JSON) then do a HTTP POST to `/realms/<realm>/clients-registrations/default`.

It will return a Client Representation that also includes the registration access token.
You should save the registration access token somewhere if you want to retrieve the config, update or delete the client later. 

To retrieve the Client Representation then do a HTTP GET to `/realms/<realm>/clients-registrations/default/<client id>`.

It will also return a new registration access token. 

To update the Client Representation then do a HTTP PUT to with the updated Client Representation to:
`/realms/<realm>/clients-registrations/default/<client id>`.

It will also return a new registration access token. 

To delete the Client Representation then do a HTTP DELETE to:
`/realms/<realm>/clients-registrations/default/<client id>`

=== {{book.project.name}} Adapter Configuration

The `installation` client registration provider can be used to retrieve the adapter configuration for a client.
In addition to token authentication you can also authenticate with client credentials using HTTP basic authentication.
To do this include the following header in the request: 

[source]
----
Authorization: basic BASE64(client-id + ':' + client-secret)
----        

To retrieve the Adapter Configuration then do a HTTP GET to `/realms/<realm>/clients-registrations/install/<client id>`.

No authentication is required for public clients.
This means that for the JavaScript adapter you can load the client configuration directly from {{book.project.name}} using the above URL.

=== OpenID Connect Dynamic Client Registration

{{book.project.name}} implements https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration], which extends https://tools.ietf.org/html/rfc7591[OAuth 2.0 Dynamic Client Registration Protocol] and https://tools.ietf.org/html/rfc7592[OAuth 2.0 Dynamic Client Registration Management Protocol].

The endpoint to use these specifications to register clients in {{book.project.name}} is `/realms/<realm>/clients-registrations/openid-connect[/<client id>]`.

This endpoints can also be found in the OpenID Connect Discovery endpoint for the realm, `/realms/<realm>/.well-known/openid-configuration`.

=== SAML Entity Descriptors

The SAML Entity Descriptor endpoint only supports using SAML v2 Entity Descriptors to create clients.
It doesn't support retrieving, updating or deleting clients.
For those operations the {{book.project.name}} representation endpoints should be used.
When creating a client a {{book.project.name}} Client Representation is returned with details about the created client, including a registration access token.

To create a client do a HTTP POST with the SAML Entity Descriptor to `/realms/<realm>/clients-registrations/saml2-entity-descriptor`.

=== Example using CURL

The following example creates a client with the clientId `myclient` using CURL. You need to replace `eyJhbGciOiJSUz...` with a proper initial access token or
bearer token.

[source,bash]
----
curl -X POST \
    -d '{ "clientId": "myclient" }' \
    -H "Content-Type:application/json" \
    -H "Authorization: bearer eyJhbGciOiJSUz..." \
    http://localhost:8080/auth/realms/master/clients-registrations/default
----

=== Example using Java Client Registration API

The Client Registration Java API makes it easy to use the Client Registration Service using Java.
To use include the dependency `org.keycloak:keycloak-client-registration-api:>VERSION<` from Maven. 

For full instructions on using the Client Registration refer to the JavaDocs.
Below is an example of creating a client. You need to replace `eyJhbGciOiJSUz...` with a proper initial access token or bearer token.

[source,java]
----
String token = "eyJhbGciOiJSUz...";

ClientRepresentation client = new ClientRepresentation();
client.setClientId(CLIENT_ID);

ClientRegistration reg = ClientRegistration.create()
    .url("http://localhost:8080/auth", "myrealm")
    .build();

reg.auth(Auth.token(token));

client = reg.create(client);

String registrationAccessToken = client.getRegistrationAccessToken();
----        
