Non-Templatized Dynamic Client Registration

Non-Templatized Dynamic Client Registration

operate

Non-Templatized Dynamic Client Registration

This tutorial shows step by step how to enable Dynamic Client Registration with Non-Templatized clients in Curity. It is recommended to get an understanding on how DCR works by reading Dynamic Client Registration Explained and Using Dynamic Client Registration.

Pre-requisites

This tutorial builds on the configuration setup in the "Setup and Getting Started" section and the "Setup a Username Authenticator". If you haven't done those steps yet you can visit those guides here:

It's possible to run this tutorial on a custom setup also, but the URLs may be different, as well as the capabilities configured in the profiles.

We will also need the client credentials client from the Client Credentials Tutorial

Overview

Non templatized DCR allows the registrating client to define all parameters of the new client. In contrast to Templatized DCR where the client instantiates a clone of a pre-defined template in Curity.

In order to be able to register a new client we need an Initial Access Token. This is a token obtained by requesting the scope dcr. Clients configured for dynamic client registration can obtain this scope.

This tutorial will use the Client Credentials flow to obtain the Initial Access Token. It is also possible to use a user interactive flow, where the user needs to be authenticated in order to register a new client. It is also possible to register clients without any form of authentication. This is not covered in this tutorial.

Setup in Curity

  • WEBUI
  • CLI

Visit the Profiles screen and click the Token Service.

Enable Non Templatized DCR

On the general page scroll down to Dynamic Client Registration

Toggle on Dynamic Client Registration

Toggle on Non Templatized

Select the token-datasource or default-datasource as the Client Data Source depending on what was setup in the initial wizard.

If Templatized is enabled it's ok to leave that on, both methods can be used at the same time.

Enable DCR

Set Allowed Capabilities

What types of clients should we be able to register. Select the code capability for this example.

Capabilities

Select Allowed Scopes

Select the scopes the client should be allowed to register for. This can either be all or selected. Go ahead and use selected and add the scope openid

Select Scopes

User Authentication

Select the allowed authenticators that these clients can use. Either all or selected. The client can restrict this further when registering, but if nothing is done, the user is presented with a choice of authenticators when logging in.

Select all.

User Authentication

Registration Authentication

How should we authenticate to get an initial access token for registration. Choose authenticate-client-by and to the right select the server client.

Registration Authentication

Commit

Make sure to remember to commit the changes in the Changes -> Commit menu.

Start the shell and enter configuration mode

$IDSVR_HOME/bin/idsh
configure

Add Non Templatized DCR

edit profiles profile token-service oauth-service settings authorization-server

edit dynamic-client-registration

set client-data-source token-datasource
set non-templatized authenticate-client-by [ server ]
set non-templatized capabilities code
set non-templatized scopes scope openid
set non-templatized authenticators all

commit
exit
exit


Registering a new Client

Now that we have the configured the setup we can register a new client.

Before we do that, we must obtain an initial access token. To do that we will use the server client like before. The only scope we will request now is dcr. This scope is not visible in the configuration, but is added to that client when we selected it to be used for registration of the template.

Obtain initial access token

  • CURL
  • HTTP

curl -X POST \
  https://localhost:8443/oauth/v2/oauth-token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&client_id=server&client_secret=THE_SECRET&scope=dcr'

POST /oauth/v2/oauth-token HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=server&client_secret=THE_SECRET&scope=dcr

This will result in a response like this:

{
    "access_token": "87f72f27-67a5-4bdd-b878-615b958c50b0",
    "scope": "dcr",
    "token_type": "bearer",
    "expires_in": 300
}

One time token

The Initial Access Token with the dcr scope can only be used once, if your request fails for some reason you need to request a new access token before trying again.

Register a Client

Now we can use the token from the previous request to register a new client.

We need to provide some parameters to toggle the new client to be a code flow client. Since code flow is the default if no grant_types are sent, it's enough to specify the additions to that.

  • redirect_uri: where the callback of the client is
  • scope: what scopes the client should be able to request

  • CURL
  • HTTP

curl -X POST \
  https://localhost:8443/oauth/v2/oauth-dynamic-client-registration \
  -H 'Authorization: Bearer 87f72f27-67a5-4bdd-b878-615b958c50b0' \
  -H 'Content-Type: application/json' \
  -d '{
    "redirect_uris": ["https://localhost/callback"],
    "scope" : "openid"
}'

POST /oauth/v2/oauth-dynamic-client-registration HTTP/1.1
Host: localhost
Content-Type: application/json
Authorization: Bearer 87f72f27-67a5-4bdd-b878-615b958c50b0
{
    "redirect_uris": ["https://localhost/callback"],
    "scope" : "openid"
}

The response will be a json document with the following content:

{
    "grant_types": [
        "authorization_code",
        "refresh_token"
    ],
    "subject_type": "public",
    "default_acr_values": [
        "urn:se:curity:authentication:html-form:username-password"
    ],
    "redirect_uris": [
        "https://localhost/callback"
    ],
    "client_id": "9806e2ff-60e6-4e83-96c6-4c4814b244c3",
    "token_endpoint_auth_method": "client_secret_basic",
    "client_secret_expires_at": 0,
    "scope": "openid",
    "client_id_issued_at": 1560330939,
    "client_secret": "rUgOmkacJZDvkAB00XO9G07UsszntRt5YipAU4QTn_E",
    "id_token_signed_response_alg": "RS256",
    "response_types": [
        "code",
        "id_token"
    ],
    "refresh_token_ttl": 3600
}

This is all the necessary metadata the client need in order to start making requests.

The important fields are the client_id and client_secret.

Run the code flow with the new client

If you need a refresh of the code flow see the Code Flow Overview or the Code Flow Tutorial.

Call the authorize endpoint:

https://localhost:8443/oauth/v2/oauth-authorize?response_type=code&client_id=9806e2ff-60e6-4e83-96c6-4c4814b244c3&scope=openid&redirect_uri=https://localhost/callback

With the resulting code call the token endpoint:

curl -X POST \
  https://localhost:8443/oauth/v2/oauth-token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code&client_id=9806e2ff-60e6-4e83-96c6-4c4814b244c3&client_secret=rUgOmkacJZDvkAB00XO9G07UsszntRt5YipAU4QTn_E&code=gPsQ97Al9K5vsVdlc7JRK2DbbwDKVNR2&redirect_uri=https%3A%2F%2Flocalhost%2Fcallback'

Conclusion

Using non-templatized clients gives you more fine grained control of what to register. However it also means the application developer needs to know more details when starting.

Was this page helpful?