|
| 1 | +[[how-to-dynamic-client-registration]] |
| 2 | += How-to: Register a client dynamically |
| 3 | +:index-link: ../how-to.html |
| 4 | +:docs-dir: .. |
| 5 | + |
| 6 | +This guide shows how to configure OpenID Connect Dynamic Client Registration 1.0 in Spring Authorization Server and walks through an example of how to register a client. |
| 7 | +Spring Authorization Server implements https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration 1.0] |
| 8 | +specification, gaining the ability to dynamically register and retrieve OpenID clients. |
| 9 | + |
| 10 | +- xref:guides/how-to-dynamic-client-registration.adoc#enable[Enable Dynamic Client Registration] |
| 11 | +- xref:guides/how-to-dynamic-client-registration.adoc#configure-initial-client[Configure initial client] |
| 12 | +- xref:guides/how-to-dynamic-client-registration.adoc#obtain-initial-access-token[Obtain initial access token] |
| 13 | +- xref:guides/how-to-dynamic-client-registration.adoc#register-client[Register a client] |
| 14 | + |
| 15 | +[[enable]] |
| 16 | +== Enable Dynamic Client Registration |
| 17 | + |
| 18 | +By default, dynamic client registration functionality is disabled in Spring Authorization Server. |
| 19 | +To enable, add the following configuration: |
| 20 | + |
| 21 | +[[sample.dcrAuthServerConfig]] |
| 22 | +[source,java] |
| 23 | +---- |
| 24 | +include::{examples-dir}/main/java/sample/dcr/DcrConfiguration.java[] |
| 25 | +---- |
| 26 | + |
| 27 | +<1> Add a `SecurityFilterChain` `@Bean` that registers an `OAuth2AuthorizationServerConfigurer` |
| 28 | +<2> In the configurer, apply OIDC client registration endpoint customizer with default values. |
| 29 | +This enables dynamic client registration functionality. |
| 30 | + |
| 31 | +Please refer to xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[Client Registration Endpoint docs] for in-depth configuration details. |
| 32 | + |
| 33 | +[[configure-initial-client]] |
| 34 | +== Configure initial client |
| 35 | + |
| 36 | +An initial client is required in order to register new clients in the authorization server. |
| 37 | +The client must be configured with scopes `client.create` and optionally `client.read` for creating clients and reading clients, respectively. |
| 38 | +A programmatic example of such a client is below. |
| 39 | + |
| 40 | +[[sample.dcrRegisteredClientConfig]] |
| 41 | +[source,java] |
| 42 | +---- |
| 43 | +include::{examples-dir}/main/java/sample/dcr/RegisteredClientConfiguration.java[] |
| 44 | +---- |
| 45 | + |
| 46 | +<1> A `RegisteredClientRepository` `@Bean` is configured with a set of clients. |
| 47 | +<2> An initial client with client id `dcr-client` is configured. |
| 48 | +<3> `client_credentials` grant type is set to fetch access tokens directly. |
| 49 | +<4> `client.create` scope is configured for the client to ensure they are able to create clients. |
| 50 | +<5> `client.read` scope is configured for the client to ensure they are able to fetch and read clients. |
| 51 | +<6> The initial client is saved into the data store. |
| 52 | + |
| 53 | +After configuring the above, run the authorization server in your preferred environment. |
| 54 | + |
| 55 | +[[obtain-initial-access-token]] |
| 56 | +== Obtain initial access token |
| 57 | + |
| 58 | +An initial access token is required to be able to create client registration requests. |
| 59 | +The token request must contain a request for scope `client.create` only. |
| 60 | + |
| 61 | +[source,httprequest] |
| 62 | +---- |
| 63 | +POST /oauth2/token HTTP/1.1 |
| 64 | +Authorization: Basic <base64-encoded-credentials> |
| 65 | +Content-Type: application/x-www-form-urlencoded |
| 66 | +
|
| 67 | +grant_type=client_credentials&scope=client.create |
| 68 | +---- |
| 69 | + |
| 70 | +[WARNING] |
| 71 | +==== |
| 72 | +If you provide more than one scope in the request, you will not be able to register a client. |
| 73 | +The client creation request requires an access token with a single scope of `client.create` |
| 74 | +==== |
| 75 | + |
| 76 | +[TIP] |
| 77 | +==== |
| 78 | +To obtain encoded credentials for the above request, `base64` encode the client credentials in the format of |
| 79 | +`<clientId>:<clientSecret>`. Below is an encoding operation for the example in this guide. |
| 80 | +
|
| 81 | +[source,console] |
| 82 | +---- |
| 83 | +echo -n "initial-app:secret" | base64 |
| 84 | +---- |
| 85 | +==== |
| 86 | + |
| 87 | +[[register-client]] |
| 88 | +== Register a client |
| 89 | + |
| 90 | +With an access token obtained from the previous step, a client can now be dynamically registered. |
| 91 | + |
| 92 | +[NOTE] |
| 93 | +The access token can only be used once. After a single registration request, the access token is invalidated. |
| 94 | + |
| 95 | +[[sample.dcrClientRegistration]] |
| 96 | +[source,java] |
| 97 | +---- |
| 98 | +include::{examples-dir}/main/java/sample/dcr/DcrClient.java[] |
| 99 | +---- |
| 100 | + |
| 101 | +<1> A minimal client registration request object. |
| 102 | +You may add additional fields as per https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[OpenID Connect Dynamic Client Registration 1.0 spec - Client Registration Request]. |
| 103 | +<2> A minimal client registration response object. |
| 104 | +You may add additional response fields as per https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[OpenID Connect Dynamic Client Registration 1.0 spec - Client Registration Response]. |
| 105 | +<3> A sample client registration request object which will be used to register a sample client. |
| 106 | +<4> Example dynamic client registration procedure, demonstrating dynamic registration and client retrieval. |
| 107 | +<5> Register a client using sample request from step 2, using initial access token from previous step. |
| 108 | +Skip to step 10 for implementation. |
| 109 | +<6> After registration, assert on the fields that should be populated in the response upon successful registration. |
| 110 | +<7> Extract `registration_access_token` and `registration_client_uri` fields, for use in retrieval of the newly registered client. |
| 111 | +<8> Retrieve client. Skip to step 11 for implementation. |
| 112 | +<9> After client retrieval, assert on the fields that should be populated in the response. |
| 113 | +<10> Sample client registration procedure using Spring WebFlux's `WebClient`. |
| 114 | +Note that the `WebClient` must have `baseUrl` of the authorization server configured. |
| 115 | +<11> Sample client retrieval procedure using Spring WebFlux's `WebClient`. |
| 116 | +Note that the `WebClient` must have `baseUrl` of the authorization server configured. |
| 117 | + |
| 118 | +The retrieve client response should contain the same information about the client as seen when the client was first |
| 119 | +registered, except for `registration_access_token` field. |
0 commit comments