Reputation: 75
In my application in Azure Active Directory I have added one of the Admin's consent required permission to the Graph API, let say Group.Read.All
. I've clicked Grant Admin Consent for ...
. If I hit /authorize
endpoint as a User with the query parameter prompt=consent
, I'll get the view that I need admin approval. If I hit the endpoint without any prompt
parameter, everything works fine - I'm able to get a token with a proper scope. In the documentation I've read that prompt
parameter determines only the visibility of the consent. Why it works like that?
Upvotes: 4
Views: 12407
Reputation: 14336
Regarding prompt=consent
, OpenID Connect says:
The Authorization Server SHOULD prompt the End-User for consent before returning information to the Client. If it cannot obtain consent, it MUST return an error, typically
consent_required
.
In the Microsoft Identity platform, this means that the end user will be required to provide consent, even if consent has been granted previously by the user or (in the case of work or school accounts, by an administrator on behalf of the user).
If the user is not authorized to consent to the requested permissions (e.g. because user consent is disabled or restricted), using prompt=consent
will always result in a hard block for the user.
In most cases, using prompt=consent
is not the best approach. There are typically three scenarios prompt=consent
is considered:
When the requested permissions are defined dynamically
On the v2.0 endpoint, the scope
parameter can be used to dynamically request a list of delegated permissions. For example, to request the read
and export
delegated permissions of the API identified by https://api.example.com
:
scope=openid https://api.example.com/read
Azure AD will ensure that all the requested permissions have been granted, and attempt to prompt for consent for any permissions which have not yet been granted (and only for those). If the requested permissions have all been granted, the issued token will include all granted permissions (even if they were not specifically requested).
Generally speaking, when making use of the incremental consent capability of the v2.0 endpoint, prompt=consent
should not be used. Azure AD will take care of prompting for incremental consent if needed.
When the requested permissions are defined statically
An app can also identify only the resource (i.e. the API) for which it is requesting an access token, the specific permissions being defined statically for the app. Using the v2.0 endpoint, this is done in the scope
parameter, making use of the special .default
permission value:
scope=openid https://api.example.com/.default
In the v1.0 endpoint, this was achieved using the resource
parameter:
resource=https://api.example.com
The list of required permissions is configured in a static list on the app registration. In the Azure portal, this list is under Configured permissions in Azure AD > App registrations > API permissions. In the unerlying Application entity in Microsoft Graph (and in the app manifest), this is stoerd in the requiredResourceAccess
property.
On receiving a request of this type (on either the v1 or v2 endpoint), Azure AD will check which permissions have been granted for the requested resource:
prompt=consent
is used, Azure AD will attempt to prompt for all the required permissions from the statically-defined list. This will include permissions for other APIs, if any are configured.scopes
parameter of the response will include the list of permissions included in the access token.Applications relying on statically-defined required permissions (i.e. /.default
on v2 or resource
on v1) should not use prompt=consent
for every sign-in request. Instead, the application should:
prompt=consent
.scope
parameter of the response:
prompt=consent
.This strategy ensures that users can sign in to an app when an administrator has consented on their behalf (e.g. because they aren't authorized to consent on their own), and only forces the consent prompt (or an escalation to an admin to consent on their behalf) when a new permission has been configured.
Using prompt=consent
is not a good approach if the goal is to only inform the user of which permissions the application has been authorized to exercise (either by the user previously, or by an administrator on the user's behalf).
Instead, an application can use the scope
parameter of the token response to construct the desired interrupt experience (e.g. after the user has been redirected back to the app and the token has been retrieved, but before continuing), informing the user of which permissions it has been granted.
There may exist very specific cases when an application requires user consent for the requested permissions, and wishes to not accept consent granted on behalf of the user by an administrator.
In this case, using prompt=consent
in all sign-ins could be used, but there are important caveats to consider:
prompt=consent
(and if consent was already previously granted, they will not be prompted for consent).In this case, it may be better the app to implement a separate consent-granting experience after the user has signed in (similar to the "inform" scenario described earlier), separating the app's additional consent requirements from the consent experience provided by the Microsoft identity platform.
Upvotes: 3
Reputation: 20067
prompt=consent
triggers the OAuth consent dialog after the user signs in, asking the user to grant permissions to the app.
Individuals accessing an app that requires at least one permission that is outside their scope of authority.
Admins will see the same prompt show the permission and will see an additional control on the traditional consent prompt that will allow them consent on behalf of the entire tenant.
Users will be blocked from granting consent to the application, and they will be told to ask their admin for access to the app.
For more details, you could refer to this article.
Upvotes: 1