Reputation: 80
I am writing a web app using the Security API within Microsoft Graph and I'm authenticating with Azure AD, but the permissions needed to access the API require admin consent for every tenant that uses my app.
How can I check if the tenant admin has given consent to my app? That way I know whether to send the user to the regular login flow or to the admin consent flow.
Is it possible to make a REST call to Azure AD for this information? I’ve tried using oAuth2PermissionGrant
but that only seems to work with the Object ID and I only have my app/client ID.
Edit:
I was confused about which scopes were needed in my app, but it turns out that when I add the admin only delegated permissions like SecurityEvents.Read.All
and SecurityEvents.ReadWrite.All
to just the Application Registraion Portal and only use the User.Read
permission in my app to request the users basic info. There are two different outcomes when requesting an access token;
User.Read
scope. User.Read
, SecurityEvents.Read.All
, and SecurityEvents.ReadWrite.All
delegated scopes. Even though my app only requests User.Read
.I found that I can use this to determine if the admin has given consent to my app by checking the access token scopes. If it contains SecurityEvents.Read.All
, or SecurityEvents.ReadWrite.All
then the user can continue in the app. But if those delegated permissions are not in the scope then I can prompt the https://login.microsoftonline.com/common/adminconsent?client_id=<APP ID>&state=12345&redirect_uri=http://localhost/myapp/permissions
admin consent flow to request the permissions to be added to the tenant.
Thank you @marc-lafleur, I was using the admin account to play with the oAuth2PermissionGrant
in Graph Explorer and I didn't catch the chicken vs. egg scenario until you pointed it out.
Upvotes: 4
Views: 2803
Reputation: 1323
Replacing the values of this link with the values of your app will take you to the authorization page.
https://login.microsoftonline.com/common/adminconsent?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&state=12345&redirect_uri=http://localhost/myapp/permissions
You can also use
https://login.microsoftonline.com/<Tenant_Id>/oauth2/authorize?client_id=<App Id>&response_type=code&redirect_uri=x-msauth-com-microsoft-testApp://com.microsoft.testApp&prompt=admin_consent
It wi;; take you to a page where the app can be authorized or let you know the status if you don't have admin privileges.
Upvotes: 0
Reputation: 33094
When you execute Admin Consent, it appends the following query parameters to your redirect_uri
:
tenant={id}&admin_consent={bool}
tenant
- This is the globally unique Id for the tenant that just executed Admin Consent.admin_consent
- This is a boolean value that tells if you Admin Consent was granted (true
) or rejected (false
).Typically you would capture and store these values. When you need to determine if Admin Consent needs to be requested, you can look them up from within your application.
It is also a good idea to store the date/time as well. This will allow you to re-request consent if your registered scopes have changed since they originally consented to them.
As to a Graph endpoint, this wouldn't help you very much. Since you need to have a valid token in order to call into the Graph, and you need Admin Consent before you can obtain that token, locking it within Graph itself would be present a Chicken vs. Egg scenario; you wouldn't be able to check if they had consented until they consented.
That said, you can determine consent using the servicePrincipal
and oAuth2PermissionGrant
resources:
First, you need to find the id
for your app's servicePrinipal
using your appId
.
/beta/servicePrincipals?$filter=appId eq '{appId}'
From the response to the previous query, grab the id
and use that to retrieve the oAuth2PermissionGrants
for your application.
/beta/oauth2PermissionGrants?$filter=resourceId eq '{servicePrincipal.id}'
Please note that these are /beta
endpoints and not suitable for production use.
Upvotes: 5