Skip to content

Commit 74058e5

Browse files
committed
Polish gh-1376
1 parent ef6b1ac commit 74058e5

File tree

5 files changed

+67
-68
lines changed

5 files changed

+67
-68
lines changed

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

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,24 @@ To enable, add the following configuration:
2323
include::{examples-dir}/main/java/sample/registration/SecurityConfig.java[]
2424
----
2525

26-
<1> Enable the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration Endpoint] with client registration endpoint authentication providers for providing custom metadata. Providing custom metadata is optional.
26+
<1> Enable the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration Endpoint] with the default configuration.
27+
<2> Optionally, customize the default ``AuthenticationProvider``'s to support custom client metadata parameters.
2728

28-
In order to accept custom client metadata when registering a client, a few additional implementation details
29-
are necessary.
29+
In order to support custom client metadata parameters when registering a client, a few additional implementation details are required.
3030

31-
[NOTE]
32-
====
33-
The following example depicts custom metadata `logo_uri` (string type) and `contacts` (string array type)
34-
====
35-
36-
Create a set of custom `Converter` classes in order to retain custom client claims.
31+
The following example shows a sample implementation of ``Converter``'s that support custom client metadata parameters (`logo_uri` and `contacts`) and are configured in `OidcClientRegistrationAuthenticationProvider` and `OidcClientConfigurationAuthenticationProvider`.
3732

38-
[[sample.CustomMetadataConfig]]
33+
[[sample.CustomClientMetadataConfig]]
3934
[source,java]
4035
----
41-
include::{examples-dir}/main/java/sample/registration/CustomMetadataConfig.java[]
36+
include::{examples-dir}/main/java/sample/registration/CustomClientMetadataConfig.java[]
4237
----
4338

44-
<1> Create a `Consumer<List<AuthenticationProvider>>` implementation.
45-
<2> Identify custom fields that should be accepted during client registration.
46-
<3> Filter for `OidcClientRegistrationAuthenticationProvider` and `OidcClientConfigurationAuthenticationProvider` instances.
47-
<4> Add a custom registered client `Converter` (implementation in #7)
48-
<5> Add a custom client registration `Converter` to `OidcClientRegistrationAuthenticationProvider` (implementation in #8)
49-
<6> Add a custom client registration `Converter` to `OidcClientConfigurationAuthenticationProvider` (implementation in #8)
50-
<7> Custom registered client `Converter` implementation that adds custom claims to registered client settings.
51-
<8> Custom client registration `Converter` implementation that modifies client registration claims with custom metadata.
39+
<1> Define a `Consumer<List<AuthenticationProvider>>` providing the ability to customize the default ``AuthenticationProvider``'s.
40+
<2> Define custom client metadata parameters that are supported for client registration.
41+
<3> Configure `OidcClientRegistrationAuthenticationProvider.setRegisteredClientConverter()` with a `CustomRegisteredClientConverter`.
42+
<4> Configure `OidcClientRegistrationAuthenticationProvider.setClientRegistrationConverter()` with a `CustomClientRegistrationConverter`.
43+
<5> Configure `OidcClientConfigurationAuthenticationProvider.setClientRegistrationConverter()` with a `CustomClientRegistrationConverter`.
5244

5345
[[configure-client-registrar]]
5446
== Configure client registrar
@@ -114,8 +106,8 @@ After the client is registered, the access token is invalidated.
114106
include::{examples-dir}/main/java/sample/registration/ClientRegistrar.java[]
115107
----
116108

117-
<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]. This example request contains custom metadata fields `logo_uri` and `contacts`.
118-
<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]. This example response contains custom metadata fields `logo_uri` and `contacts`.
109+
<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]. This example request contains custom client metadata parameters `logo_uri` and `contacts`.
110+
<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]. This example response contains custom client metadata parameters `logo_uri` and `contacts`.
119111
<3> Example demonstrating client registration and client retrieval.
120112
<4> A sample client registration request object.
121113
<5> Register the client using the "initial" access token and client registration request object.

docs/src/main/java/sample/registration/ClientRegistrar.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public void exampleRegistration(String initialAccessToken) { // <3>
7878
assert (clientRegistrationResponse.redirectUris().contains("https://client.example.org/callback2"));
7979
assert (!clientRegistrationResponse.registrationAccessToken().isEmpty());
8080
assert (!clientRegistrationResponse.registrationClientUri().isEmpty());
81-
assert (clientRegistrationResponse.logoUri().contentEquals("https://client.example.org/logo")); // <6>
81+
assert (clientRegistrationResponse.logoUri().contentEquals("https://client.example.org/logo"));
8282
assert (clientRegistrationResponse.contacts().size() == 2);
8383
assert (clientRegistrationResponse.contacts().contains("contact-1"));
8484
assert (clientRegistrationResponse.contacts().contains("contact-2"));

docs/src/main/java/sample/registration/CustomMetadataConfig.java renamed to docs/src/main/java/sample/registration/CustomClientMetadataConfig.java

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
*/
1616
package sample.registration;
1717

18+
import java.util.HashMap;
19+
import java.util.List;
20+
import java.util.Map;
21+
import java.util.function.Consumer;
22+
import java.util.function.Function;
23+
import java.util.stream.Collectors;
24+
1825
import org.springframework.core.convert.converter.Converter;
1926
import org.springframework.security.authentication.AuthenticationProvider;
2027
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@@ -26,84 +33,84 @@
2633
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
2734
import org.springframework.util.CollectionUtils;
2835

29-
import java.util.HashMap;
30-
import java.util.List;
31-
import java.util.Map;
32-
import java.util.function.Consumer;
33-
import java.util.function.Function;
34-
import java.util.stream.Collectors;
36+
public class CustomClientMetadataConfig {
3537

36-
public class CustomMetadataConfig {
37-
public static Consumer<List<AuthenticationProvider>> registeredClientConverters() {
38-
List<String> customClientMetadata = List.of("logo_uri", "contacts"); // <1>
38+
public static Consumer<List<AuthenticationProvider>> configureCustomClientMetadataConverters() { // <1>
39+
List<String> customClientMetadata = List.of("logo_uri", "contacts"); // <2>
3940

40-
return authenticationProviders -> // <2>
41-
{
42-
CustomRegisteredClientConverter registeredClientConverter = new CustomRegisteredClientConverter(customClientMetadata);
43-
CustomClientRegistrationConverter clientRegistrationConverter = new CustomClientRegistrationConverter(customClientMetadata);
41+
return (authenticationProviders) -> {
42+
CustomRegisteredClientConverter registeredClientConverter =
43+
new CustomRegisteredClientConverter(customClientMetadata);
44+
CustomClientRegistrationConverter clientRegistrationConverter =
45+
new CustomClientRegistrationConverter(customClientMetadata);
4446

45-
authenticationProviders.forEach(authenticationProvider -> {
46-
if (authenticationProvider instanceof OidcClientRegistrationAuthenticationProvider provider) { // <3>
47-
provider.setRegisteredClientConverter(registeredClientConverter); // <4>
48-
provider.setClientRegistrationConverter(clientRegistrationConverter); // <5>
47+
authenticationProviders.forEach((authenticationProvider) -> {
48+
if (authenticationProvider instanceof OidcClientRegistrationAuthenticationProvider provider) {
49+
provider.setRegisteredClientConverter(registeredClientConverter); // <3>
50+
provider.setClientRegistrationConverter(clientRegistrationConverter); // <4>
4951
}
50-
5152
if (authenticationProvider instanceof OidcClientConfigurationAuthenticationProvider provider) {
52-
provider.setClientRegistrationConverter(clientRegistrationConverter); // <6>
53+
provider.setClientRegistrationConverter(clientRegistrationConverter); // <5>
5354
}
5455
});
5556
};
5657
}
5758

58-
static class CustomRegisteredClientConverter implements Converter<OidcClientRegistration, RegisteredClient> { // <7>
59-
private final List<String> customMetadata;
59+
private static class CustomRegisteredClientConverter
60+
implements Converter<OidcClientRegistration, RegisteredClient> {
6061

62+
private final List<String> customClientMetadata;
6163
private final OidcClientRegistrationRegisteredClientConverter delegate;
6264

63-
CustomRegisteredClientConverter(List<String> customMetadata) {
64-
this.customMetadata = customMetadata;
65+
private CustomRegisteredClientConverter(List<String> customClientMetadata) {
66+
this.customClientMetadata = customClientMetadata;
6567
this.delegate = new OidcClientRegistrationRegisteredClientConverter();
6668
}
6769

70+
@Override
6871
public RegisteredClient convert(OidcClientRegistration clientRegistration) {
69-
RegisteredClient convertedClient = delegate.convert(clientRegistration);
70-
ClientSettings.Builder clientSettingsBuilder = ClientSettings
71-
.withSettings(convertedClient.getClientSettings().getSettings());
72-
73-
if (!CollectionUtils.isEmpty(this.customMetadata)) {
72+
RegisteredClient registeredClient = this.delegate.convert(clientRegistration);
73+
ClientSettings.Builder clientSettingsBuilder = ClientSettings.withSettings(
74+
registeredClient.getClientSettings().getSettings());
75+
if (!CollectionUtils.isEmpty(this.customClientMetadata)) {
7476
clientRegistration.getClaims().forEach((claim, value) -> {
75-
if (this.customMetadata.contains(claim)) {
77+
if (this.customClientMetadata.contains(claim)) {
7678
clientSettingsBuilder.setting(claim, value);
7779
}
7880
});
7981
}
8082

81-
return RegisteredClient.from(convertedClient).clientSettings(clientSettingsBuilder.build()).build();
83+
return RegisteredClient.from(registeredClient)
84+
.clientSettings(clientSettingsBuilder.build())
85+
.build();
8286
}
8387
}
8488

85-
static class CustomClientRegistrationConverter implements Converter<RegisteredClient, OidcClientRegistration> { // <8>
86-
private final List<String> customMetadata;
89+
private static class CustomClientRegistrationConverter
90+
implements Converter<RegisteredClient, OidcClientRegistration> {
8791

92+
private final List<String> customClientMetadata;
8893
private final RegisteredClientOidcClientRegistrationConverter delegate;
8994

90-
CustomClientRegistrationConverter(List<String> customMetadata) {
91-
this.customMetadata = customMetadata;
95+
private CustomClientRegistrationConverter(List<String> customClientMetadata) {
96+
this.customClientMetadata = customClientMetadata;
9297
this.delegate = new RegisteredClientOidcClientRegistrationConverter();
9398
}
9499

100+
@Override
95101
public OidcClientRegistration convert(RegisteredClient registeredClient) {
96-
var clientRegistration = delegate.convert(registeredClient);
102+
OidcClientRegistration clientRegistration = this.delegate.convert(registeredClient);
97103
Map<String, Object> claims = new HashMap<>(clientRegistration.getClaims());
98-
if (!CollectionUtils.isEmpty(customMetadata)) {
104+
if (!CollectionUtils.isEmpty(this.customClientMetadata)) {
99105
ClientSettings clientSettings = registeredClient.getClientSettings();
100-
101-
claims.putAll(customMetadata.stream()
102-
.filter(metadatum -> clientSettings.getSetting(metadatum) != null)
106+
claims.putAll(this.customClientMetadata.stream()
107+
.filter(metadata -> clientSettings.getSetting(metadata) != null)
103108
.collect(Collectors.toMap(Function.identity(), clientSettings::getSetting)));
104109
}
110+
105111
return OidcClientRegistration.withClaims(claims).build();
106112
}
113+
107114
}
108115

109116
}

docs/src/main/java/sample/registration/SecurityConfig.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
2525
import org.springframework.security.web.SecurityFilterChain;
2626

27-
import static sample.registration.CustomMetadataConfig.registeredClientConverters;
27+
import static sample.registration.CustomClientMetadataConfig.configureCustomClientMetadataConverters;
2828

2929
@Configuration
3030
@EnableWebSecurity
@@ -33,13 +33,13 @@ public class SecurityConfig {
3333
@Bean
3434
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
3535
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
36-
3736
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
38-
.oidc(oidc -> oidc.clientRegistrationEndpoint(endpoint -> {
39-
endpoint.authenticationProviders(registeredClientConverters()); // <1>
37+
.oidc(oidc -> oidc.clientRegistrationEndpoint(clientRegistrationEndpoint -> { // <1>
38+
clientRegistrationEndpoint
39+
.authenticationProviders(configureCustomClientMetadataConverters()); // <2>
4040
}));
41-
42-
http.oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer.jwt(Customizer.withDefaults()));
41+
http.oauth2ResourceServer(oauth2ResourceServer ->
42+
oauth2ResourceServer.jwt(Customizer.withDefaults()));
4343

4444
return http.build();
4545
}

docs/src/test/java/sample/registration/DynamicClientRegistrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class DynamicClientRegistrationTests {
5656
private String port;
5757

5858
@Test
59-
public void dynamicallyRegisterClientWithCustomMetadata() throws Exception {
59+
public void dynamicallyRegisterClientWithCustomClientMetadata() throws Exception {
6060
MockHttpServletResponse tokenResponse = this.mvc.perform(post("/oauth2/token")
6161
.with(httpBasic("registrar-client", "secret"))
6262
.param(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())

0 commit comments

Comments
 (0)