How-to: Register a client dynamically

本指南介绍了如何在 Spring 授权服务器中配置 OpenID Connect 动态客户端注册,并逐一介绍了如何注册客户端示例。Spring 授权服务器实现了 OpenID Connect Dynamic Client Registration 1.0规范,提供了动态注册和检索 OpenID Connect 客户端的功能。

Enable Dynamic Client Registration

默认情况下,动态客户端注册功能在 Spring Authorization Server 中被禁用。若要启用,请添加以下配置:

link:{examples-dir}/main/java/sample/registration/SecurityConfig.java[role=include]
1 使用默认配置启用 OpenID Connect 1.0 Client Registration Endpoint
2 可以选择自定义默认的 AuthenticationProvider 来支持自定义客户端元数据参数。

为了在注册客户端时支持自定义客户端元数据参数,需要一些额外的实现细节。

以下示例展示了支持自定义客户端元数据参数(logo_uricontacts)的 Converter 样例实现,它们在 OidcClientRegistrationAuthenticationProviderOidcClientConfigurationAuthenticationProvider 中进行了配置。

link:{examples-dir}/main/java/sample/registration/CustomClientMetadataConfig.java[role=include]
1 定义一个 Consumer<List<AuthenticationProvider>>,提供自定义默认 AuthenticationProvider 的能力。
2 定义在客户端注册中支持的自定义客户端元数据参数。
3 使用 CustomRegisteredClientConverter 配置 OidcClientRegistrationAuthenticationProvider.setRegisteredClientConverter()
4 使用 CustomClientRegistrationConverter 配置 OidcClientRegistrationAuthenticationProvider.setClientRegistrationConverter()
5 使用 CustomClientRegistrationConverter 配置 OidcClientConfigurationAuthenticationProvider.setClientRegistrationConverter()

Configure client registrar

现有客户端用于向授权服务器注册新客户端。该客户端必须配置为具有范围 client.create,以及用于注册客户端和检索客户端的 client.read(可选)。以下列表展示了一个客户端示例:

link:{examples-dir}/main/java/sample/registration/ClientConfig.java[role=include]
1 client_credentials 授予类型被配置为直接获取访问令牌。
2 client.create 范围被配置为允许客户端注册新客户端。
3 client.read 范围被配置为允许客户端检索已注册的客户端。

Obtain initial access token

客户端注册请求需要一个“初始”访问令牌。访问令牌请求*必须*仅包含 scope 参数值 client.create

POST /oauth2/token HTTP/1.1
Authorization: Basic <base64-encoded-credentials>
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=client.create

客户端注册请求需要一个具有单一范围 client.create 的访问令牌。如果访问令牌包含其他范围,客户端注册请求将被拒绝。

若要获取上述请求的编码凭据,请以 <clientId>:<clientSecret> 格式对客户端凭据进行 base64 编码。以下是本指南中示例的编码操作。

echo -n "registrar-client:secret" | base64

Register a client

使用从上一步中获取的访问令牌,现在可以动态注册客户端。

“初始”访问令牌仅能使用一次。在注册客户端后,访问令牌将失效。

link:{examples-dir}/main/java/sample/registration/ClientRegistrar.java[role=include]
1 客户端注册请求的简单表示。可以根据 Client Registration Request 添加额外的客户端元数据参数。此示例请求包含自定义客户端元数据参数 logo_uricontacts
2 客户端注册响应的简单表示。可以根据 Client Registration Response 添加额外的客户端元数据参数。此示例响应包含自定义客户端元数据参数 logo_uricontacts
3 演示客户端注册和客户端检索的示例。
4 示例客户端注册请求对象。
5 使用“初始”访问令牌和客户端注册请求对象注册客户端。
6 注册成功后,断言响应中应填充的客户端元数据参数。
7 提取 registration_access_tokenregistration_client_uri 响应参数,用于检索新注册的客户端。
8 使用 registration_access_tokenregistration_client_uri 检索客户端。
9 客户端检索后,断言响应中应该填充的客户端元数据参数。
10 使用 WebClient 的示例 Client Registration Request
11 使用 WebClient 的示例 Client Read Request

Client Read Response应包含与 Client Registration Response相同的客户端元数据参数,但`registration_access_token`参数除外。