Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the guids of Graph API permissions programmatically for an Azure AD application?

I am trying to add required permissions to an Azure AD application. I already know how to replicate information from a downloaded manifest through a PATCH REST call, e.g.

"requiredResourceAccess": [
{
  "resourceAppId": "00000003-0000-0000-c000-000000000000",
  "resourceAccess": [
    {
      "id": "7b9103a5-4610-446b-9670-80643382c1fa",
      "type": "Scope"
    },
    {
      "id": "5df07973-7d5d-46ed-9847-1271055cbd51",
      "type": "Scope"
    }
  ]
}
]          

As explained by Christer Ljung on his blog http://www.redbaronofazure.com/?page_id=181.

But the mystery remains how I can "convert" human-readable scopes such as Mail.Read to these obscure guids. I have read the following blog of Sahil Malik's at http://blah.winsmarts.com/2015-1-Programmatically_register_native_apps_in_Azure_AD_or_Office_365.aspx that explains how to get a list of available guids for a particular ServicePrincipal. E.g. through an http get to https://graph.windows.net/<tenant-id>/servicePrincipals()?api-version=1.6&$filter=appId%20eq%20'00000002-0000-0ff1-ce00-000000000000'> (Exchange) but when I try to get the list of available scopes of ServicePrincipal 00000003-0000-0000-c000-000000000000 (I believe the one for Graph API) the return value is just empty.

Interestingly, with Fiddler I was able to capture an http post request which contains all the guids when adding the permissions through Azure Portal.

Anyone any clue how I can do this programmatically?

like image 474
Carl in 't Veld Avatar asked Jan 30 '17 22:01

Carl in 't Veld


People also ask

How do I check Azure Permissions API?

Select Azure Active Directory > App registrations, and then select your client application. Select API permissions > Add a permission > Microsoft Graph > Application permissions.


2 Answers

After investigation, I discover a way to get permission guid using azure-cli. Share here in case anyone is finding this:

  1. get all permisson and their GUID of a certain service principal by display-name, app-id or object-id. (Note that display-name is not unique and can maps multiple service principal)
$ az ad sp list --filter "displayName eq 'Microsoft Graph'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table
Value                                                    Id                                    UserConsentDisplayName
-------------------------------------------------------  ------------------------------------  -----------------------------------------------------------------------------------------
ServiceHealth.Read.All                                   55896846-df78-47a7-aa94-8d3d4442ca7f  Read service health
ServiceMessage.Read.All                                  eda39fa6-f8cf-4c3c-a909-432c683e4c9b  Read service messages
TermStore.ReadWrite.All                                  6c37c71d-f50f-4bff-8fd3-8a41da390140  Read and write term store data
TermStore.Read.All                                       297f747b-0005-475b-8fef-c890f5152b38  Read term store data
TeamMember.ReadWriteNonOwnerRole.All                     2104a4db-3a2f-4ea0-9dba-143d457dc666  Add and remove members with non-owner role for all teams
Team.Create                                              7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0  Create teams
TeamsAppInstallation.ReadWriteForUser                    093f8818-d05f-49b8-95bc-9d2a73e9a43c  Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser                207e0cb1-3ce7-4922-b991-5a760c346ebc  Allow the Teams app to manage itself for you
...

$ az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query '[].oauth2Permissions[].{Value:value, Id:id, UserConsentDisplayName:userConsentDisplayName}' -o table | head
Value                                                    Id                                    UserConsentDisplayName
-------------------------------------------------------  ------------------------------------  -----------------------------------------------------------------------------------------
ServiceHealth.Read.All                                   55896846-df78-47a7-aa94-8d3d4442ca7f  Read service health
ServiceMessage.Read.All                                  eda39fa6-f8cf-4c3c-a909-432c683e4c9b  Read service messages
TermStore.ReadWrite.All                                  6c37c71d-f50f-4bff-8fd3-8a41da390140  Read and write term store data
TermStore.Read.All                                       297f747b-0005-475b-8fef-c890f5152b38  Read term store data
TeamMember.ReadWriteNonOwnerRole.All                     2104a4db-3a2f-4ea0-9dba-143d457dc666  Add and remove members with non-owner role for all teams
Team.Create                                              7825d5d6-6049-4ce7-bdf6-3b8d53f4bcd0  Create teams
TeamsAppInstallation.ReadWriteForUser                    093f8818-d05f-49b8-95bc-9d2a73e9a43c  Manage your installed Teams apps
TeamsAppInstallation.ReadWriteSelfForUser                207e0cb1-3ce7-4922-b991-5a760c346ebc  Allow the Teams app to manage itself for you
...
  1. Run the below command to get full information of certain service principal including its oauth2Permissions and servicePrincipalNames, etc.
az ad sp show --id 00000003-0000-0000-c000-000000000000 >microsoft_graph_permission_list.json

# microsoft_graph_permission_list.json
{
  ...
  "appDisplayName": "Microsoft Graph",
  "appId": "00000003-0000-0000-c000-000000000000",
  "objectId": "b19d498e-6687-4156-869a-2e8a95a9d659",
  "servicePrincipalNames": [
    "https://dod-graph.microsoft.us",
    "https://graph.microsoft.com/",
    "https://graph.microsoft.us",
    "00000003-0000-0000-c000-000000000000/ags.windows.net",
    "00000003-0000-0000-c000-000000000000",
    "https://canary.graph.microsoft.com",
    "https://graph.microsoft.com",
    "https://ags.windows.net"
  ],
  "appRoles": [...],
  "oauth2Permissions": [
    {
      "adminConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
      "adminConsentDisplayName": "Read and write all users' full profiles",
      "id": "204e0828-b5ca-4ad8-b9f3-f32a958e7cc4",
      "isEnabled": true,
      "type": "Admin",
      "userConsentDescription": "Allows the app to read and write the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
      "userConsentDisplayName": "Read and write all users' full profiles",
      "value": "User.ReadWrite.All"
    },
    {
      "adminConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on behalf of the signed-in user.",
      "adminConsentDisplayName": "Read all users' full profiles",
      "id": "a154be20-db9c-4678-8ab7-66f6cc099a59",
      "isEnabled": true,
      "type": "Admin",
      "userConsentDescription": "Allows the app to read the full set of profile properties, reports, and managers of other users in your organization, on your behalf.",
      "userConsentDisplayName": "Read all users' full profiles",
      "value": "User.Read.All"
    },
    ...
  ]
  ...
}
like image 144
binaryDi Avatar answered Sep 21 '22 12:09

binaryDi


Few things to say about this topic.

First, it is important to note that all of the OAuth2Permission Scopes are registered on the main Application Object in the developer's tenant. Thus, in general, you would not have access to that information, since it would be in a tenant where you are not a user. So as an external developer, these permission scopes are not discoverable via our APIs.

Second, you are able to see that the Azure Portal has access to this information because it has elevated access to query the OAuth2Permissions for all resources in all tenants. This is how our UX is able to populate all the permissions for all the various external and internal resources that you want to use in your tenant. The portal will first check which service principals are in your tenant (service principals get provisioned most commonly once you consent to use the application), then it will look up the Application Object that corresponds to that service principal, and find all the permission scopes. This behavior will hopefully allow you to only see the resource applications which are relevant to you, rather than populating your screen with all possible resources.

Finally, moving forward we are looking to take a step back from having to statically register permissions that clients require to call resource applications. Instead we will be pushing a new Incremental and Dynamic Consent framework. You will note that here that we are taking a dependency on the scope names, rather than the ObjectID GUIDs of those permissions as we did in the past. But still, I agree with you in general that the discoverability of the scopes that resources expose is very heavily dependent their own public documentation. I imagine in the future there might be an endpoint which exposes all the scopes available on a particular resource, but I know of no such work to do this in the near future.

Let me know if this helps!

like image 28
Shawn Tabrizi Avatar answered Sep 17 '22 12:09

Shawn Tabrizi