Skip to content

Commit 3eb951f

Browse files
committed
Polish gh-1320
1 parent 3386b1e commit 3eb951f

File tree

6 files changed

+147
-206
lines changed

6 files changed

+147
-206
lines changed

docs/modules/ROOT/pages/guides/how-to-dynamic-client-registration.adoc

Lines changed: 45 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,60 +3,50 @@
33
:index-link: ../how-to.html
44
:docs-dir: ..
55

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.
6+
This guide shows how to configure OpenID Connect Dynamic Client Registration in Spring Authorization Server and walks through an example of how to register a client.
7+
Spring Authorization Server implements the https://openid.net/specs/openid-connect-registration-1_0.html[OpenID Connect Dynamic Client Registration 1.0] specification, providing the capability to dynamically register and retrieve OpenID Connect clients.
98

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]
9+
* xref:guides/how-to-dynamic-client-registration.adoc#enable-dynamic-client-registration[Enable Dynamic Client Registration]
10+
* xref:guides/how-to-dynamic-client-registration.adoc#configure-client-registrar[Configure client registrar]
11+
* xref:guides/how-to-dynamic-client-registration.adoc#obtain-initial-access-token[Obtain initial access token]
12+
* xref:guides/how-to-dynamic-client-registration.adoc#register-client[Register a client]
1413

15-
[[enable]]
14+
[[enable-dynamic-client-registration]]
1615
== Enable Dynamic Client Registration
1716

1817
By default, dynamic client registration functionality is disabled in Spring Authorization Server.
1918
To enable, add the following configuration:
2019

21-
[[sample.dcrAuthServerConfig]]
20+
[[sample.SecurityConfig]]
2221
[source,java]
2322
----
24-
include::{examples-dir}/main/java/sample/dcr/DcrConfiguration.java[]
23+
include::{examples-dir}/main/java/sample/registration/SecurityConfig.java[]
2524
----
2625

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.
26+
<1> Enable the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration Endpoint] with the default configuration.
3027

31-
Please refer to xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[Client Registration Endpoint docs] for in-depth configuration details.
28+
[[configure-client-registrar]]
29+
== Configure client registrar
3230

33-
[[configure-initial-client]]
34-
== Configure initial client
31+
An existing client is used to register new clients with the authorization server.
32+
The client must be configured with scopes `client.create` and optionally `client.read` for registering clients and retrieving clients, respectively.
33+
The following listing shows an example client:
3534

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]]
35+
[[sample.ClientConfig]]
4136
[source,java]
4237
----
43-
include::{examples-dir}/main/java/sample/dcr/RegisteredClientConfiguration.java[]
38+
include::{examples-dir}/main/java/sample/registration/ClientConfig.java[]
4439
----
4540

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.
41+
<1> `client_credentials` grant type is configured to obtain access tokens directly.
42+
<2> `client.create` scope is configured to allow the client to register a new client.
43+
<3> `client.read` scope is configured to allow the client to retrieve a registered client.
5444

5545
[[obtain-initial-access-token]]
5646
== Obtain initial access token
5747

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.
48+
An "initial" access token is required for the client registration request.
49+
The access token request *MUST* contain the `scope` parameter value `client.create` only.
6050

6151
[source,httprequest]
6252
----
@@ -69,18 +59,18 @@ grant_type=client_credentials&scope=client.create
6959

7060
[WARNING]
7161
====
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`
62+
The client registration request requires an access token with a single scope of `client.create`.
63+
If the access token contains additional scope, the client registration request will be denied.
7464
====
7565

7666
[TIP]
7767
====
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.
68+
To obtain encoded credentials for the above request, `base64` encode the client credentials in the format of `<clientId>:<clientSecret>`.
69+
Below is an encoding operation for the example in this guide.
8070
8171
[source,console]
8272
----
83-
echo -n "initial-app:secret" | base64
73+
echo -n "registrar-client:secret" | base64
8474
----
8575
====
8676

@@ -90,30 +80,26 @@ echo -n "initial-app:secret" | base64
9080
With an access token obtained from the previous step, a client can now be dynamically registered.
9181

9282
[NOTE]
93-
The access token can only be used once. After a single registration request, the access token is invalidated.
83+
The "initial" access token can only be used once.
84+
After the client is registered, the access token is invalidated.
9485

95-
[[sample.dcrClientRegistration]]
86+
[[sample.ClientRegistrar]]
9687
[source,java]
9788
----
98-
include::{examples-dir}/main/java/sample/dcr/DcrClient.java[]
89+
include::{examples-dir}/main/java/sample/registration/ClientRegistrar.java[]
9990
----
10091

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.
92+
<1> A minimal representation of a client registration request. You may add additional client metadata parameters as per https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration Request].
93+
<2> A minimal representation of a client registration response. You may add additional client metadata parameters as per https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[Client Registration Response].
94+
<3> Example demonstrating client registration and client retrieval.
95+
<4> A sample client registration request object.
96+
<5> Register the client using the "initial" access token and client registration request object.
97+
<6> After successful registration, assert on the client metadata parameters that should be populated in the response.
98+
<7> Extract `registration_access_token` and `registration_client_uri` response parameters, for use in retrieval of the newly registered client.
99+
<8> Retrieve the client using the `registration_access_token` and `registration_client_uri`.
100+
<9> After client retrieval, assert on the client metadata parameters that should be populated in the response.
101+
<10> Sample https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration Request] using `WebClient`.
102+
<11> Sample https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read Request] using `WebClient`.
103+
104+
[NOTE]
105+
The https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse[Client Read Response] should contain the same client metadata parameters as the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[Client Registration Response], except the `registration_access_token` parameter.

docs/src/main/java/sample/dcr/DcrConfiguration.java

Lines changed: 0 additions & 96 deletions
This file was deleted.

docs/src/main/java/sample/dcr/RegisteredClientConfiguration.java renamed to docs/src/main/java/sample/registration/ClientConfig.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package sample.dcr;
16+
package sample.registration;
17+
18+
import java.util.UUID;
1719

1820
import org.springframework.context.annotation.Bean;
1921
import org.springframework.context.annotation.Configuration;
@@ -23,21 +25,21 @@
2325
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
2426
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
2527

26-
import java.util.UUID;
27-
2828
@Configuration
29-
public class RegisteredClientConfiguration {
30-
@Bean // <1>
29+
public class ClientConfig {
30+
31+
@Bean
3132
public RegisteredClientRepository registeredClientRepository() {
32-
RegisteredClient initialClient = RegisteredClient.withId(UUID.randomUUID().toString())
33-
.clientId("dcr-client") // <2>
33+
RegisteredClient registrarClient = RegisteredClient.withId(UUID.randomUUID().toString())
34+
.clientId("registrar-client")
3435
.clientSecret("{noop}secret")
3536
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
36-
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) // <3>
37-
.scope("client.create") // <4>
38-
.scope("client.read") // <5>
37+
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) // <1>
38+
.scope("client.create") // <2>
39+
.scope("client.read") // <3>
3940
.build();
4041

41-
return new InMemoryRegisteredClientRepository(initialClient); // <6>
42+
return new InMemoryRegisteredClientRepository(registrarClient);
4243
}
44+
4345
}

0 commit comments

Comments
 (0)