Configuring an OpenID Connect Provider to accept client registration requests

The client registration endpoint is an administrator managed service that is 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.

Before you begin

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 the server.xml file 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. You can modify the server.xml file 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>

About this task

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 the server.xml file 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:

Table 1. Client registration parameters
Attribute Name Data Type Required/Optional Description
client_id Input/Output Optional The client identifier that is 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 that is 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 that is 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 that are used by this client. Unless specified, the default value is authorization_code. This is a JSON array. For example, the possible values are:
  • <an empty value is valid>
  • authorization_code
  • implicit
  • refresh_token
  • client_credentials
  • urn:ietf:params:oauth:grant-type:jwtbearer
  • password
response_types Input Optional The response type constraints that are used by this client. Unless specified, the default value is code. This array is a JSON array. For example, possible values are:
  • <an empty value is valid>
  • code
  • token
  • id_token token (order reversible)

For a specific response_type, the corresponding grant_types must be specified. For more information, see response_types at the Client Metadata website.

token_endpoint_auth_method Input Optional The token endpoint authentication method constraint that is used by the client. Unless specified, the default value is client_secret_basic. This data type is a string. For example, possible values are:
  • <an empty value is valid>
  • client_secret_basic
  • client_secret_post
  • none
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:
  • <an empty value is valid>
  • web
  • native
functional_user_groupIds Input Optional A list of group IDs to associate with access tokens that are obtained by this client by 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 that is described by the client. This data type is a string. For example, possible values are:
  • <an empty value is valid>
  • public
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.

Procedure

  1. 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"
       ]
    }
  2. 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"
       ]
    }
  3. 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"
       ]
    }
  4. 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
  5. 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: The information in this topic also applies to client registration services of OAuth 2.0 clients, and OpenID Connect Relying parties.