Configure an OpenID Connect Provider to accept client registration requests
The client registration endpoint is an administrator managed service used to register, update, delete, and retrieve information about an OpenID Connect Relying Party that intends to use the OpenID Connect Provider. In turn, the registration process can provide information for the Relying Party to use it, including the OAuth 2.0 Client ID and Client Secret, if not specified.
The client registration service operates in one of two modes: non-persistent or persistent. These modes are determined by how the Liberty server configures its client store, whether clients are defined with the oauthProvider localStore attributes (non-persistent) in server.xml or are configured with a database store or a custom store (persistent).
In a non-persistent configuration, the client registration service is limited to only retrieving OpenID Connect Relying Party information. We can modify server.xml to add more operations to register, update, or delete an OpenID Connect Relying Party.
In a persistent configuration, there is no limitation on the client registration service and all operations are functional through the REST interface.
Note: A Liberty server must not configure its client store with a combination of local store, database store, and custom store. Choose only one configuration route.
The client registration endpoint is a protected administration endpoint with the clientManager role. To access this endpoint, the user must be granted the clientManager role by the administrator.
The clientManager role is one of the oauth-roles defined for an oauthProvider. The following is a sample configuration that shows a grant of the clientManager role to the user Alice or members in the clientAdministrator group.
<oauth-roles> <authenticated> <special-subject type="ALL_AUTHENTICATED_USERS" /> </authenticated> <clientManager> <group name="clientAdministrator" /> <user name="Alice" /> </clientManager> </oauth-roles>
Client registration information about an OpenID Connect Relying Party is largely used to define the usage scenario constraints of the client. Additionally, other operations of the OP that are opaque to the client use the client registration metadata to make authorization decisions.
The following example assumes that the Liberty OP is configured with SSL on port 443.
https://server.example.com:443/oidc/endpoint/<provider_name>/registration
The previous example also assumes that server.xml is configured with a user name: clientAdmin and password: clientAdminPassword, that uses the oauth-role: clientManager.
The client registration metadata consists of the following parameters:
| Attribute Name | Data Type | Required/Optional | Description |
|---|---|---|---|
| client_id | Input/Output | Optional | The client identifier being registered with the OP. Unless specified, this parameter value is generated during registration by default. This is a string. |
| client_secret | Input/Output | Optional | The client secret being registered with the OP. Unless specified, this parameter value is generated during registration by default. This is a string. During an update operation, the parameter value '*' preserves the existing value. A blank parameter value generates a new client_secret. A non-blank parameter value overrides the existing value with the newly specified value. |
| client_name | Input/Output | Optional | A description for the client being registered with the OP. Unless specified, this parameter is set to the client_id parameter value by default. This is a string. |
| redirect_uris | Input | Optional | The array of redirect URIs to which the client is constrained to. This array is a JSON array. |
| scope | Input | Optional | The space-delimited scope values to which the client is constrained. This data type is a string. If the client is allowed to request any scope, a value of ALL_SCOPES can be used. |
| grant_types | Input | Optional | The grant type constraints used by this client. Unless specified, the default value is authorization_code.
This is a JSON array. For example, the possible values are:
|
| response_types | Input | Optional | The response type constraints used by this client. Unless specified, the default value is code.
This array is a JSON array. For example, possible values are:
For a specific response_type, the corresponding grant_types must be specified. See response_types at the Client Metadata website. |
| token_endpoint_auth_method | Input | Optional | The token endpoint authentication method constraint
used by the client. Unless specified, the default value is client_secret_basic.
This data type is a string. For example, possible values are:
|
| preauthorized_scope | Input | Optional | The space delimited scope values that the client is preauthorizing that does not require user consent. This is a string. |
| allow_regexp_redirects | Input | Optional | This Boolean parameter indicates whether regular expressions are allowed in redirect URLs. |
| application_type | Input | Optional | The application type that describes the client.
Unless specified, the default value is web. This is a string. For example, possible values:
|
| functional_user_groupIds | Input | Optional | A list of group IDs to associate with access
tokens that are obtained by this client using the client credentials grant
type. The value is a list of group IDs to which the functional user is a member, where the group IDs are case-sensitive strings. The strings
are defined by the authorization server. If the value contains multiple group IDs, their order does not matter. If the list is empty, the claim is omitted. When this client metadata parameter is specified,
the value is returned in the functional_user_groupIds response
parameter from the introspection endpoint for access tokens. The access tokens are issued to this client with a client credentials grant. If the functional_user_id parameter
is not used, this parameter is ignored.
Note: Authorization Servers must not trust the client to self-assert this parameter. |
| functional_user_id | Input | Optional | This parameter indicates which user ID to associate with a request made on behalf of a client in a client_credentials grant type. This data type is a string. |
| introspect_tokens | Input | Optional | A parameter value that indicates whether the specified client has the privilege to introspect an access token that is issued by the OP. This is a Boolean value. |
| post_logout_redirect_uris | Input | Optional | The array of post logout redirect URIs to which the client is constrained. This is a JSON array. |
| subject_type | Input | Optional | The subject type constraint described by the client. This data type is a string. For example, possible values are:
|
| trusted_uri_prefixes | Input | Optional | The array of trusted URI prefixes that the client has deemed safe for sending access tokens. This array is a JSON array. |
| registration_client_uri | Output only | N/A | A parameter that is returned in a response with the value that indicates the unique URL for a registered client. This is a string. |
| client_secret_expires_at | Output only | N/A | A parameter that is returned in a response with the value that indicates the number of seconds from 1970-01- 01T0:0:0Z as measured in UTC, at which the client secret expires. The value 0 indicates no expiration time. |
| client_id_issued_at | Output only | N/A | A parameter that is returned in a response with the value that indicates the number of seconds from 1970-01- 01T0:0:0Z as measured in UTC, at which the client ID was issued. The value 0 indicates that no client ID issue time was identified. |
- Register a client, as shown in the following example:
Request Headers:
POST https://server.example.com:443/oidc/endpoint/<provider_name>/registration Accept: application/json Content-Type: application/json Authorization: Basic Y2xpZW50QWRtaW46Y2xpZW50QWRtaW5QYXNzd29yZA==
Request Payload:
{ "token_endpoint_auth_method":"client_secret_basic", "scope":"openid profile email general", "grant_types":[ "authorization_code", "client_credentials", "implicit", "refresh_token", "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "response_types":[ "code", "token", "id_token token" ], "application_type":"web", "subject_type":"public", "post_logout_redirect_uris":[ "https://server.example.com:9000/logout/", "https://server.example.com:9001/exit/" ], "preauthorized_scope":"openid profile email general", "introspect_tokens":true, "trusted_uri_prefixes":[ "https://server.example.com:9000/trusted/" ], "redirect_uris":[ "https://server.example.com:443/resource/redirect1", "https://server.example.com:9000/resource/redirect2" ] }Response Headers:
Status: 201 Cache-Control: private ETag: "1B2M2Y8AsgTpgAmY7PhCfg==" Content-Type: application/json
Response Body:
{ "client_id_issued_at":1401776782, "registration_client_uri":"https://server.example.com:8020/oidc/endpoint/OIDC/registration/b0a376ec4b694b67b6baeb0604a312d8", "client_secret_expires_at":0, "token_endpoint_auth_method":"client_secret_basic", "scope":"openid profile email general", "grant_types":[ "authorization_code", "client_credentials", "implicit", "refresh_token", "urn:ietf:params:oauth:grant-type:jwt-bearer" ], "response_types":[ "code", "token", "id_token token" ], "application_type":"web", "subject_type":"public", "post_logout_redirect_uris":[ "https://server.example.com:9000/logout/", "https://server.example.com:9001/exit/" ], "preauthorized_scope":"openid profile email general", "introspect_tokens":true, "trusted_uri_prefixes":[ "https://server.example.com:9000/trusted/" ], "client_id":"b0a376ec4b694b67b6baeb0604a312d8", "client_secret":"nmrOQ20CrMdwd4pjqaimutZTcbQPzIoYgItjaccb9Wk33rKarhM3WDLmWIoE", "client_name":"b0a376ec4b694b67b6baeb0604a312d8", "redirect_uris":[ "https://server.example.com:443/resource/redirect1", "https://server.example.com:9000/resource/redirect2" ] } - Update a client, as shown in the following example:
Request Headers:
PUT https://server.example.com:443/oidc/endpoint/<provider_name>/registration/b0a376ec4b694b67b6baeb0604a312d8 Accept: application/json Content-Type: application/json Authorization: Basic Y2xpZW50QWRtaW46Y2xpZW50QWRtaW5QYXNzd29yZA==
Request Payload:
{ "token_endpoint_auth_method":"client_secret_basic", "scope":"openid profile", "grant_types":[ "authorization_code" ], "response_types":[ "code" ], "application_type":"native", "subject_type":"public", "post_logout_redirect_uris":[ "https://server.example.com:9000/logout/" ], "preauthorized_scope":"openid", "introspect_tokens":false, "trusted_uri_prefixes":[ "https://server.example.com:9003/trusted/" ], "client_id":"b0a376ec4b694b67b6baeb0604a312d8", "client_secret":"*", "client_name":"updated client", "redirect_uris":[ "https://server.example.com:443/resource/redirect1" ] }Response Headers:
Status: 200 ETag: "3DD7affTGS91mfhPZ83B39Y==" Content-Type: application/json
Response Body:
{ "client_id_issued_at":1401776782, "registration_client_uri":"https://server.example.com:8020/oidc/endpoint/OIDC/registration/b0a376ec4b694b67b6baeb0604a312d8", "client_secret_expires_at":0, "token_endpoint_auth_method":"client_secret_basic", "scope":"openid profile", "grant_types":[ "authorization_code" ], "response_types":[ "code" ], "application_type":"native", "subject_type":"public", "post_logout_redirect_uris":[ "https://server.example.com:9000/logout/" ], "preauthorized_scope":"openid", "introspect_tokens":false, "trusted_uri_prefixes":[ "https://server.example.com:9003/trusted/" ], "client_id":"b0a376ec4b694b67b6baeb0604a312d8", "client_secret":"*", "client_name":"updated client", "redirect_uris":[ "https://server.example.com:443/resource/redirect1" ] } - Retrieve a client, as shown in the following example:
Request Headers:
GET https://server.example.com:443/oidc/endpoint/<provider_name>/registration/b0a376ec4b694b67b6baeb0604a312d8 Accept: application/json Authorization: Basic Y2xpZW50QWRtaW46Y2xpZW50QWRtaW5QYXNzd29yZA==
Response Headers:
Status: 200 Cache-Control: private ETag: "3DD7affTGS91mfhPZ83B39Y==" Content-Type: application/json
Response Body:
{ "client_id_issued_at":1401776782, "registration_client_uri":"https://server.example.com:8020/oidc/endpoint/OIDC/registration/b0a376ec4b694b67b6baeb0604a312d8", "client_secret_expires_at":0, "token_endpoint_auth_method":"client_secret_basic", "scope":"openid profile", "grant_types":[ "authorization_code" ], "response_types":[ "code" ], "application_type":"native", "subject_type":"public", "post_logout_redirect_uris":[ "https://server.example.com:9000/logout/" ], "preauthorized_scope":"openid", "introspect_tokens":false, "trusted_uri_prefixes":[ "https://server.example.com:9003/trusted/" ], "client_id":"b0a376ec4b694b67b6baeb0604a312d8", "client_secret":"*", "client_name":"updated client", "redirect_uris":[ "https://server.example.com:443/resource/redirect1" ] } - Retrieve a client (head request), as shown in the following example:
Request Headers:
HEAD https://server.example.com:443/oidc/endpoint/<provider_name>/registration/b0a376ec4b694b67b6baeb0604a312d8 Accept: application/json Authorization: Basic Y2xpZW50QWRtaW46Y2xpZW50QWRtaW5QYXNzd29yZA==
Response Headers:
Status: 200 Cache-Control: private, no-cache=set-cookie ETag: "3DD7affTGS91mfhPZ83B39Y==" Content-Type: application/json
- Delete a client, as shown in the following example:
Request Headers:
DELETE https://server.example.com:443/oidc/endpoint/<provider_name>/registration/b0a376ec4b694b67b6baeb0604a312d8 Authorization: Basic Y2xpZW50QWRtaW46Y2xpZW50QWRtaW5QYXNzd29yZA==
Response Headers:
Status: 204 Content-Length: 0 Content-Language: en-US
Note that the information in this topic also applies to client registration services of OAuth 2.0 clients, and OpenID Connect Relying parties.