The process where a user is asked to confirm the release of the scopes and claims that a client requests, is called user consent gathering. Once agreed, the scopes and claims can be bound to the delegation when issuing token. In case the user decides that the requested scopes and claims are invalid, you can enable the option to let a user select which requested scopes and claims are allowed before giving its permission to proceed with issuing the token.
In this tutorial, you will be guided through the process of setting up Curity for user consent gathering. This includes creating new and required scopes and make requests like a client would to see the user experience. Finally we’ll look at customizing the template that renders the form that the user interacts with, as well as internationalizing the scope and claim names that are presented to the user.
We’ll be using the Admin UI to make small configuration updates, but will also use the CLI so you can copy/paste configuration commands from the tutorial directly.
This tutorial builds on the configuration setup described in the “First Configuration” and the “Configure an Authenticator” steps under the menu “Getting Started”. 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.
You will also need a client capable of user interaction. If you follow the code flow tutorial, you will have a client called
www that will use clone in this example.
The first step is to clone the
www client from the code flow tutorial. You can also setup a new client if you prefer.
Visit the Profiles screen and click the Token Service. On the right select Clients.
www client and click Duplicate in the edit menu. Name the new client
We want two scopes in this example.
read. Make sure both are configured on the client by scrolling down to OAuth/OpenID Settings.
If you don’t have a read scope, you can create it by clicking New Scope.
Scroll down to the User Consent section and enable User Consent. If you want the user to be able to deselect scopes while consenting, go ahead and also enable Allow Deselection. Note however that the client may get fewer scopes and claims than it requested.
During the consent process the user will be presented with a consent screen. It is possible to set the logo, name and description for the application on the client. This can be helpful to show the user what it is consenting to. These options are found in the top of the client configuration page.
Scroll to the Client Application Settings and click Advanced to find these settings.
Make sure to remember to commit the changes in the Changes -> Commit menu.
Now, with the client configured with user consent enabled, you can make a request using the Code Flow to ask for tokens. We include the
openid+read scope to have a consentable scope.
To start the flow visit the following urlhttps://localhost:8443/oauth/v2/oauth-authorize?response_type=code&client_id=third-party&scope=openid+read&state=abc123&redirect_uri=https://localhost/callback
After authenticating, the following screen will be shown, where the user is asked to provide its consent to authorizing the client to get a token on its behalf:
Go ahead, allow the tokens to be issued, and you will be redirected back to the client’s redirect uri with the authorization code as usual. To get the tokens continue with the second part of the code flow.
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=third-party&client_secret=THE_SECRET&code=THE_AUTHORIZATION_CODE&redirect_uri=https%3A%2F%2Flocalhost%2Fcallback'
Complete the flowThe code flow will not persist the consented scopes until the second part of the flow has executed.
Now that a delegation that is bound to the user as well as to the consented-to scope
openid is issued, it will be
known to Curity that the user has consented to releasing access to this scope. Given the previous step has resulted
in the issuance of a token after you consented to the request, try to make a new request for a token by the client for
the same scope. You can use the exact same url to initiate the second request (remember it’s good practice to make the
state unique for each request)
You can see now that both SSO as well as re-use of user consent kicks in, and the response to this request will be a newly issued code.
If the admin doesn’t configure the client to force consent as we did above, the client can still tell the server to show the consent screen using the
In case you want the user to consent to requested claims, regardless of pre-existing delegations, you can make that
same request, but include the parameter
prompt=consent in the querystring, like:
Notice how, after authenticating, possibly through SSO, the consent screen is being shown as a result of this request.
Try and hit
Cancel. The response will now be a redirect back to the client that includes an error in the fragment.
This will inform the client with the reason why the response did not contain a token, as was requested.
When a request to authorize a token is being made, the client typically includes scopes or claims, to represent the type of
access it desires. It is good practice to ask for the minimal set of scopes, in which case the client needs all scopes
to be able to perform the tasks it intends to perform using the token. Some scopes or claims can be optional however.
An example would be the
firstname claim - a client would like to know this, but if it does not have access to it, it
might still be able to carry on with its work. In this case, the user may be given the choice to deselect access to
particular requested claims.
We configured the client to allow scope deselection, but alternatively, the client can indicate on a per-request basis whether scope deselection is allowed.
If you make the request again, and deselect the
read scope the client will now be issued a code that when exchanged for tokens will contain only the
If the client doesn’t have Allow Deselection enabled, it can still enable it on it’s own. This is done using the
prompt parameter again with the value
So far, we’ve been making requests using the scopes
read, both of which are configured as non-required
scopes. Sometimes we have scopes we know the client will always need in order to be able to call the APIs.
Let’s add a new scope, and enable it on the client. This scope should be marked as required which will enforce that the client must request it and get it for a successful flow.
Visit the Scopes page in the Token Service and click Add Scope.
Give it the name important-scope and slide the Required toggle to on.
Visit the Clients page and edit the
third-party client. Scroll down to the OAuth / OpenID Settings and add the scope
important-scope from the list.
Make sure to remember to commit the changes in the Changes -> Commit menu.
Now try the a new request with the
important-scope included. This time you can notice that the new scope is present but is not de-selectable. In fact, if the client makes a request without this scope, the request will fail.
The resulting screen will have the
To perform simple database management, you can use the
hsqltool that is included in the
bin/ directory of the
installation directory. In case the server is running, connect to the database as a server (instead of pointing to the
files and requiring a lock on them). Delete all issued tokens and delegations by issuing the following command from
bin/hsqltool --inlineRc=url=jdbc:hsqldb:hsql://localhost:9001/db,user=sa,password= --sql "DELETE FROM \"tokens\"; DELETE FROM \"delegations\";"