On this page
Request user consent
This guide explains how to configure an Okta-hosted user consent dialog for OAuth 2.0 or OpenID Connect authentication flows.
Learning outcomes
Implement an Okta-hosted user consent dialog.
What you need
- Okta Integrator Free Plan org (opens new window)
- OpenID Connect client app (opens new window) created in your Okta org with at least one user assigned to it (opens new window)
- A custom authorization server in your org. You can use the
default
authorization server.
Note: If you have a new Okta Integrator Free Plan org and plan to use the
default
custom authorization server, check that it has an access policy. Add an access policy if it's not there. See Create access policies (opens new window).
About the user consent dialog
When configured, the Okta-hosted user consent dialog for OAuth 2.0 or OpenID Connect authentication flows enables users to acknowledge and accept that they’re giving an app access to some of their data. With the correct configuration, Okta displays a consent dialog that shows which app is asking for access to what data. The dialog displays the app logo that you specify and also provides details about what data is shared if the user consents.
The value of consent
User consent dialogs are important when an app requests access to user data, especially for third-party apps. These dialogs allow users to explicitly grant or deny permissions, which aligns with data privacy regulations like GDPR and provides transparency about how the user's information is used.
Third-party app access
When a user signs in to a third-party app, that app needs to access user data (like profile info or email) or perform actions on the user's behalf (like posting on their behalf). The consent dialog appears and informs the user about the specific data the app is requesting and allows the user to grant or deny access.
This is especially important for OAuth 2.0 and OpenID Connect flows where apps request access to protected resources.
Specific data access
Even within a single app, you might want to implement consent dialogs for specific data access points. For example, an app might ask for consent to access a user's calendar data or location information only when those features are used. This granular approach gives users more control over their data.
Granular access control
The Okta consent framework allows for fine-grained control over which apps and users can access specific resources. You can define scopes (read:profile
, write:calendar
) and require consent for each scope individually. This allows you to customize the consent experience based on the specific needs of your apps and users.
User consent and tokens
User consent represents a user's explicit permission to allow an app to access resources protected by scopes. Consent grants are different from tokens. This is because a consent can outlast a token. There can also be multiple tokens with varying sets of scopes derived from a single consent.
You can configure which scopes aren't required, which are optional, and which are required.
When an app needs to get a new access token from an authorization server, the user isn't prompted for consent if they already consented to the specified scopes. Consent grants remain valid until the user or admin manually revokes them, or until the user, app, authorization server, or scope is deactivated or deleted.
Note: The user only has to grant consent once for a scope per authorization server.
When a consent dialog appears depends on the values of three elements:
prompt
: a query parameter (opens new window) that's used in requests to/oauth2/{authorizationServerId}/v1/authorize
(custom authorization server)consent_method
: an app property listed in the Settings table (opens new window) in the Apps API doc. This property allows you to determine whether a client is fully trusted (for example, a first-party app) or requires consent (for example, a third-party app).consent
: a scope property listed in the parameter details (opens new window) for authorization server scopes. This property allows you to enable or disable user consent for an individual scope.
Enable consent for scopes
Use the following steps to display the user consent dialog as part of an OpenID Connect or OAuth 2.0 request.
Note: Currently OAuth consent works only with custom authorization servers. See Authorization servers for more information on the types of authorization servers available to you and what you can use them for.
Note: The Okta Integrator Free Plan org makes most key developer features available by default for testing purposes. Okta's API Access Management product — a requirement to use Custom Authorization Servers — is an optional add-on in production environments.
In the Admin Console, go to Applications > Applications.
Select the OpenID Connect app that you want to require user consent for.
On the General tab, scroll down to the User Consent section and verify that the Require consent checkbox is selected. If it isn't, click Edit and select Require consent.
For this use case, use the Implicit flow for testing purposes. In the Grant type section, click Advanced, and then select Implicit.
Select both Allow ID Token with implicit grant type and Allow Access Token with implicit grant type below Implicit.
Note: If you're using Classic Engine, select Implicit (hybrid) in the Grant type section.
For the Authorization Code flow, the response type is
code
. You can exchange an authorization code for an ID token and/or an access token using the/token
endpoint.Click Save.
To enable consent for scopes (opens new window), select Security > API.
On the Authorization Servers tab, select default (custom authorization server) in the table. In this example, you are enabling consent for a default custom authorization server scope.
Select the Scopes tab.
Click the edit icon for the phone scope. The Edit Scope dialog appears.
For this use case example, select Required in the User consent section. Required indicates that the user must grant the app access to the information (scope) or they can't sign in to the app. The other options available include:
Note: When you create apps using the Apps endpoint (/api/v1/apps), the consent method default is
TRUSTED
. When you create an app using Dynamic Client Registration (/oauth2/v1/clients
), the consent method default isREQUIRED
.- Implicit: Indicates that the user doesn't have to grant the app access to the information. User consent is implied.
- Optional: Indicates that the user can skip granting the app access to the information (scope). Scopes that the user skips aren't included in the authorization response. After a user skips a scope, the next time that they sign in, Okta doesn't prompt them for it. If you later make the scope required for the app, the user is then prompted to grant the app access to that scope.
Note: When you include
prompt=consent
in the authorization request, the user is prompted for all consent-enabled scopes. This includes scopes that are required or optional, even when the user has already given consent for a scope or skipped a scope. The user can also skip scopes that were changed from required to optional.When you select User consent as Required or Optional, the Block services from requesting this scope checkbox is automatically selected.
The Block services from requesting this scope checkbox strictly enforces user consent for the scope. When you select this checkbox, if a service using the Client Credentials grant flow makes a request that contains this scope, the authorization server returns an error. This occurs because there's no user involved in a Client Credentials grant flow. If you want to allow service-to-service interactions to request this scope, clear the checkbox. See the Authorization Servers API (opens new window) for more information on consent options.
Click Save.
Enable consent using the APIs
The following section provides example requests for enabling the consent dialog using the APIs. The first step is to verify that the consent_method
property is set to REQUIRED
and then enable consent for the scope.
Update the consent method for an app
Verify that the
consent_method
parameter for the app is set toREQUIRED
:- Do a List apps (opens new window) to locate the
applicationId
of the app. - Do a Get app (opens new window) using the
applicationId
and verify that theconsent_method
parameter is set toREQUIRED
.
- Do a List apps (opens new window) to locate the
If the
consent_method
is set toTRUSTED
, you need to update that parameter. The following example shows the JSON body of a PUT request to an existing OpenID Connect app (https://{yourOktaDomain}/api/v1/apps/{applicationId}
). The request updates theconsent_method
parameter fromTRUSTED
toREQUIRED
. The value that you specify forconsent_method
depends on the values forprompt
andconsent
.Note: Check the Settings table (opens new window) of the Apps API reference for information on these properties. Usually,
REQUIRED
is the correct value.{ "id": "0oaosna3ilNxgPTmk0h7", "name": "oidc_client", "label": "ConsentWebApp", "status": "ACTIVE", "signOnMode": "OPENID_CONNECT", "credentials": { "userNameTemplate": { "template": "{source.login}", "type": "BUILT_IN" }, "signing": { "kid": "5gbe0HpzAYj2rsWSLxx1fYHdh-SzWqyKqwmfJ6qDk5g" }, "oauthClient": { "autoKeyRotation": true, "client_id": "0oaosna3ilNxgPTmk0h7", "token_endpoint_auth_method": "client_secret_basic" } }, "settings": { "app": {}, "notifications": { "vpn": { "network": { "connection": "DISABLED" }, "message": null, "helpUrl": null } }, "oauthClient": { "client_uri": null, "logo_uri": null, "redirect_uris": [ "https://{yourOktaDomain}/authorization-code/callback" ], "response_types": [ "code", "token", "id_token" ], "grant_types": [ "authorization_code", "implicit" ], "initiate_login_uri": "https://{yourOktaDomain}/authorization-code/callback", "application_type": "web", "consent_method": "REQUIRED", "issuer_mode": "CUSTOM_URL" } } }
Update scope consent
To enable consent for a scope, you need to update the appropriate scope (opens new window) by updating the consent
property for the scope from IMPLICIT
(the default) to either REQUIRED
or FLEXIBLE
. In this example, set consent
to REQUIRED
.
To make consent of a scope optional, set the consent
property to either REQUIRED
or FLEXIBLE
and include "optional": true
in the request.
Note: See the Authorization Servers API (opens new window) for more information on scope properties and how to use them.
This example shows the JSON body for a PUT request to the default custom authorization server (https://{yourOktaDomain}/api/v1/authorizationServers/{authorizationServerId}/scopes/{scopeId}
) to update the phone
scope. You need the following information for the request:
authorizationServerId
: Do a List authorization servers (opens new window) to locate the appropriate ID.scopeId
: Do a List scopes (opens new window) to locate the appropriate ID.
{
"id": "scpixa2zmc8Eumvjb0h7",
"name": "phone",
"displayName": "phone",
"description": "Allows this application to access your phone number.",
"system": true,
"metadataPublish": "ALL_CLIENTS",
"consent": "REQUIRED",
"default": false
}
To update scope consent to OPTIONAL
, set consent
to REQUIRED
and include the optional
parameter set to true
:
{
"id": "scpixa2zmc8Eumvjb0h7",
"name": "phone",
"displayName": "phone",
"description": "Allows this application to access your phone number.",
"system": true,
"metadataPublish": "ALL_CLIENTS",
"consent": "REQUIRED",
"optional": true,
"default": false
}
Build the request
After you define the scopes that you want to require consent for, prepare an authentication or authorization request with the correct values.
Obtain the following values from your OpenID Connect app, both of which you can find on the app's General tab:
- Client ID
- Redirect URI
Use the default custom authorization server's authorization endpoint, for example,
https://{yourOktaDomain}/oauth2/default/v1/authorize
.Note: See Authorization servers for more information on the types of authorization servers available to you and what you can use them for.
Add the following query parameters to the URL:
- Your OpenID Connect app's
client_id
andredirect_uri
- The
openid
scope and the scopes that you want to require consent for. In this example, you configured thephone
scope in the previous section. - The response type, which for an ID token is
id_token
and an access token istoken
Note: The examples in this guide use the Implicit flow, which streamlines authentication by returning tokens without introducing extra steps. This makes it easier to test your configuration. For the Authorization Code flow, the response type is
code
. You can then exchange an authorization code for an ID token and/or an access token using the/token
endpoint.Values for
state
andnonce
, which can be anythingOptional. The
prompt
parameter. The standard behavior (if you don't includeprompt
in the request) is to prompt the user for consent if they haven't already given consent for the scopes. When you includeprompt=consent
in the request, the user is prompted for consent every time, even if they have already given consent. You must set theconsent_method
and the consent for the scopes (opens new window) toREQUIRED
. See the parameter details (opens new window) for the/authorize
endpoint.
Note: The property values are fully documented in the
/authorize
endpoint (opens new window) section of the OpenID Connect & OAuth 2.0 API reference.The resulting URL to request an access token looks something like this:
curl -X GET "https://{yourOktaDomain}/oauth2/{authorizationServerId}/v1/authorize?client_id=examplefa39J4jXdcCwWA &response_type=token &scope=openid%20phone &redirect_uri=https%3A%2F%2FyourRedirectUriHere.com &state=myState &nonce={myNonceValue}"
Example with the
prompt
parameter included:curl -X GET "https://{yourOktaDomain}/oauth2/{authorizationServerId}/v1/authorize?client_id=examplefa39J4jXdcCwWA &response_type=token &scope=openid%20phone &prompt=consent &redirect_uri=https%3A%2F%2FyourRedirectUriHere.com &state=myState &nonce={myNonceValue}"
Note: The
response_type
for an ID token looks like this:&response_type=id_token
.- Your OpenID Connect app's
Paste the request URL into a browser. The User Consent dialog appears. Click Allow to create the grant.
Note: The user only has to grant consent once for a scope per authorization server.
Verification
There are several ways to verify that you've successfully created a user grant:
Check the ID token payload if you requested an ID token. To check the ID token payload, you can copy the token value and paste it into any JWT decoder (opens new window). The payload should look similar to this. No scopes are returned in an ID token:
{ "sub": "00uixa271s6x7qt8I0h7", "ver": 1, "iss": "https://{yourOktaDomain}/oauth2/default", "aud": "0oaosna3ilNxgPTmk0h7", "iat": 1575931097, "exp": 1575934697, "jti": "ID.67UFdLqtzyqtWEcO4GJPVBE6MMe-guCdXwzuv11p-eE", "amr": [ "mfa", "pwd", "kba" ], "idp": "00oixa26ycdNcX0VT0h7", "nonce": "UBGW", "phone_number": "7206685241", "auth_time": 1575929999 }
Check the access token if you requested one. To check the access token payload, you can copy the token value and paste it into any JWT decoder. The payload should look something like this:
{ "ver": 1, "jti": "AT.xtjhr8FeMkyMfgLiFzVYOYPbgqWdd6ONULT3ffeK7d4", "iss": "https://{yourOktaDomain}/oauth2/default", "aud": "api://default", "iat": 1575929637, "exp": 1575933237, "cid": "0oaosna3ilNxgPTmk0h7", "uid": "00uixa271s6x7qt8I0h7", "scp": [ "openid", "phone" ], "sub": "joe.smith@okta.com" }
You can verify that a grant was created by listing the grants given to a specific user:
curl -v -X GET \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: SSWS {api_token} \ "https://{yourOktaDomain}/api/v1/users/{userId}/grants"
The response should contain the
scopeId
for the grant that you created when you clicked Allow in the previous step.[ { "id": "oaggjy8vxJwKeiMx20h6", "status": "ACTIVE", "created": "2019-12-09T17:36:12.000Z", "createdBy": { "id": "00uixa271s6x7qt8I0h7", "type": "User" }, "lastUpdated": "2019-12-09T17:36:12.000Z", "issuer": "https://{yourOktaDomain}/oauth2/default", "clientId": "0oaosna3ilNxgPTmk0h7", "userId": "00uixa271s6x7qt8I0h7", "scopeId": "scpixa2zmc8Eumvjb0h7", "source": "END_USER", "_links": { "app": { "href": "https://{yourOktaDomain}/api/v1/apps/0oaosna3ilNxgPTmk0h7", "title": "ConsentWebApp" }, "authorizationServer": { "href": "https://{yourOktaDomain}/api/v1/authorizationServers/default", "title": "default" }, "scope": { "href": "https://{yourOktaDomain}/api/v1/authorizationServers/default/scopes/scpixa2zmc8Eumvjb0h7", "title": "phone" }, "self": { "href": "https://{yourOktaDomain}/api/v1/users/00uixa271s6x7qt8I0h7/grants/oaggjy8vxJwKeiMx20h6", "hints": { "allow": [ "GET", "DELETE" ] } }, "client": { "href": "https://{yourOktaDomain}/oauth2/v1/clients/0oaosna3ilNxgPTmk0h7", "title": "ConsentWebApp" }, "user": { "href": "https://{yourOktaDomain}/api/v1/users/00uixa271s6x7qt8I0h7", "title": "Joe Smith" } } } ]
Revoke consent for a user
To revoke consent for a user, you can revoke one consent that is granted or all consents that are granted. Before you begin, you need the following:
userId
: The user that you want to revoke a grant for. Use the List all Users (opens new window) endpoint to locate the user and theuserId
that you need.grantId
: The grant that you want to revoke. Use the List all User Grants (opens new window) endpoint with theuserId
to locate thegrantID
that you need.
Revoke one grant
To revoke one grant for a user (opens new window), use the grantId
that you want to revoke for a user in a DELETE request:
Example request
curl -v -X DELETE \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS {api_token}" \
"https://{yourOktaDomain}/api/v1/users/{userId}/grants/{grantId}"
Revoke all grants
To revoke all grants for a user (opens new window), use the userId
for the user in a DELETE request:
Example request
curl -v -X DELETE \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: SSWS {api_token}" \
"https://{yourOktaDomain}/api/v1/users/{userId}/grants"
Troubleshoot
If you don't see the consent prompt when expected:
- Verify that you haven't already provided consent for that combination of app and scopes. Use the
/grants
endpoint (opens new window) to see which grants have been given and to revoke grants. - Check the settings for
prompt
,consent
, andconsent_method
in the Apps API table (opens new window). - Make sure that in your app configuration, the
redirect_uri
is an absolute URI and that it's allowed by specifying it in Trusted Origins (opens new window). - If you aren't using the
default
authorization server, check that you've created at least one policy with one rule that applies to any scope or the scopes in your test. - Check the System Log (opens new window) to see what went wrong.