Uncategorized

Azure AD v2 endpoint – How to use custom scopes for admin consent

In my early post I explained about administrator consent (admin consent) in Azure AD v2 endpoint. The admin consent is very useful and needed for the various scenarios, such as app permissions (application-level privilege without interactive sign-in UI), granting entire employees without individual user consents, or on-behalf-of flow in your web api.

For the use of admin consent, you must pre-define the permissions in portal UI (App Registration Portal). But, in this UI, you can set the scopes only for Microsoft Graph (see the following screenshot), and some ISV folks ask me “how to use admin consent for legacy APIs (Outlook Rest API, etc), 3rd party apps, or your own custom apps ?”.

The answer is “edit manifest by your own !”

In this post I show you how to configure this custom settings in Azure AD v2 endpoint with application manifest step-by-step.

Permissions in Azure AD v2 endpoint – Under the hood

Now let’s take a look at predefined scopes in v2 endpoint.

For the sake of scenarios such as application permissions (application-level privilege without interactive sign-in UI), granting entire employees without individual user consents (delegated permissions) etc, you can pre-define the needed scopes to the application within App Registration Portal.

Note !  For the usual user consent, you don’t need to pre-define scopes in Azure AD v2 endpoint and you can set scopes dynamically (on the fly) when you authenticate.
This pre-defined permission is needed for admin consent.

These settings are all written in the application manifest, and you can edit the manifest directly with “Edit Application Manifest” button (see below) in App Registration Portal.

For example, when you set “offline_access” scope and “openid” scope in your app, these are written in the manifest as follows.

{
  "id": "678806b7-adee-4f4e-b548-947e10512e00",
  "appId": "c471620b-73a3-4a88-a926-eda184e6fde9",
  "name": "testapp01",
  "oauth2AllowImplicitFlow": false,
  "requiredResourceAccess": [
    {
      "resourceAppId": "00000003-0000-0000-c000-000000000000",
      "resourceAccess": [
        {
          "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
          "type": "Scope"
        },
        {
          "id": "37f7f235-527c-4136-accd-4a02d197296e",
          "type": "Scope"
        }
      ]
    }
  ],
  ...
  
}

As you can see, the app’s ID and scope’s ID is used for settings. For example, 00000003-0000-0000-c000-000000000000 means “Microsoft Graph” application and 7427e0e9-2fba-42fe-b0c0-848c9e6a8182 means “offline_access” scope.
The following is the list of IDs for the familiar scopes. (All scopes are in “Microsoft Graph” application.)

openid 37f7f235-527c-4136-accd-4a02d197296e
email 64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0
profile 37f7f235-527c-4136-accd-4a02d197296e
offline_access 7427e0e9-2fba-42fe-b0c0-848c9e6a8182

In conclusion, you just edit the manifest by your own, when you need to add custom scopes except for Microsoft Graph application.
The next concern is : How to get (look for) the app’s id and scope’s id ?

Use permissions for other APIs

When you want to use Outlook REST API, OneDrive API, Azure AD Graph API, Power BI REST API, etc, etc …, first you should go to Azure Active Directory settings in Azure Portal.
In this settings, you can set these APIs for required permissions and you can see the app’s id and scope’s id in the manifest text as follows. (The following is the sample for https://outlook.office.com/mail.read scope.)

You can use same ID in v2 endpoint and can set these scopes using the manifest editor in App Registration Portal as follows.

{
  "id": "678806b7-adee-4f4e-b548-947e10512e00",
  "appId": "c471620b-73a3-4a88-a926-eda184e6fde9",
  "name": "testapp01",
  "oauth2AllowImplicitFlow": false,
  "requiredResourceAccess": [
    {
      "resourceAppId": "00000003-0000-0000-c000-000000000000",
      "resourceAccess": [
        {
          "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
          "type": "Scope"
        },
        {
          "id": "37f7f235-527c-4136-accd-4a02d197296e",
          "type": "Scope"
        }
      ]
    },
    {
      "resourceAppId": "00000002-0000-0ff1-ce00-000000000000",
      "resourceAccess": [
        {
          "id": "185758ba-798d-4b72-9e54-429a413a2510",
          "type": "Scope"
        }
      ]
    }
  ],
  ...
  
}

Now let’s access the following admin consent url in v2 endpoint with your browser. (Change testdirectory.onmicrosoft.com, c471620b-73a3-4a88-a926-eda184e6fde9, and https://localhost/testapp01 for your appropriate values.)

https://login.microsoftonline.com/testdirectory.onmicrosoft.com/adminconsent?client_id=c471620b-73a3-4a88-a926-eda184e6fde9&state=12345&redirect_uri=https%3a%2f%2flocalhost%2ftestapp01

After you logged-in by the administrator account, the following consent screen is displayed. Note that this Mail.Read scope is not in Microsoft Graph, but in Outlook REST API. Therefore when you get your own e-mails in your inbox, you must access https://outlook.office365.com/api/{version}/me/messages instead of using https://graph.microsoft.com/{version}/me/messages. (You cannot use https://graph.microsoft.com/{version}/me/messages with this consent.)

Use permissions for your own custom applications

As I mentioned in my early post “Build your own Web API protected by Azure AD v2.0 endpoint with custom scopes“, you can define your own custom scopes for your api applications in App Registration Portal.

For example, we assume that 2 scopes in our api application are defined as the following screenshot in App Registration Portal.

These scopes will be written in the manifest as follows.
In this case, the app’s ID is c4894da7-0070-486e-af4c-e1c2ba5e24ae, and the scope’s IDs are 223e6396-1b01-4a16-bb2f-03eaed9f31a8 and 658e7fa5-bb32-4ed1-93eb-b040ebc6bfec.

{
  "id": "2cd5c8e0-6a6c-4e8d-870c-46c08f3be3d9",
  "appId": "c4894da7-0070-486e-af4c-e1c2ba5e24ae",
  "identifierUris": [
    "api://c4894da7-0070-486e-af4c-e1c2ba5e24ae"
  ],
  "oauth2Permissions": [
    {
      "adminConsentDescription": "Allow the client to write your data with myapi01 on behalf of the signed-in user.",
      "adminConsentDisplayName": "Write data with myapi",
      "id": "223e6396-1b01-4a16-bb2f-03eaed9f31a8",
      "isEnabled": true,
      "lang": null,
      "origin": "Application",
      "type": "User",
      "userConsentDescription": "Allow the client to write your data with myapi01 on your behalf.",
      "userConsentDisplayName": "Write data with myapi",
      "value": "write_as_user"
    },
    {
      "adminConsentDescription": "Allow the client to read your data with myapi01 on behalf of the signed-in user.",
      "adminConsentDisplayName": "Read data with myapi",
      "id": "658e7fa5-bb32-4ed1-93eb-b040ebc6bfec",
      "isEnabled": true,
      "lang": null,
      "origin": "Application",
      "type": "User",
      "userConsentDescription": "Allow the client to read your data with myapi01 on your behalf.",
      "userConsentDisplayName": "Read data with myapi",
      "value": "read_as_user"
    }
  ],
  ...
  
}

Therefore, on the client side, you can set these scopes of the api application using the manifest editor as follows.

{
  "id": "678806b7-adee-4f4e-b548-947e10512e00",
  "appId": "c471620b-73a3-4a88-a926-eda184e6fde9",
  "name": "testapp01",
  "oauth2AllowImplicitFlow": false,
  "requiredResourceAccess": [
    {
      "resourceAppId": "00000003-0000-0000-c000-000000000000",
      "resourceAccess": [
        {
          "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
          "type": "Scope"
        },
        {
          "id": "37f7f235-527c-4136-accd-4a02d197296e",
          "type": "Scope"
        }
      ]
    },
    {
      "resourceAppId": "c4894da7-0070-486e-af4c-e1c2ba5e24ae",
      "resourceAccess": [
        {
          "id": "658e7fa5-bb32-4ed1-93eb-b040ebc6bfec",
          "type": "Scope"
        }
      ]
    }
  ],
  ...
  
}

First the user (administrator) must subscribe the api application before using this api’s permission in the client application.
Let’s access the following url, in which c4894da7-0070-486e-af4c-e1c2ba5e24ae is the app’s ID of the api application. (See my early post “Build your own Web API protected by Azure AD v2.0 endpoint with custom scopes” for details.)

https://login.microsoftonline.com/testdirectory.onmicrosoft.com/adminconsent?client_id=c4894da7-0070-486e-af4c-e1c2ba5e24ae&state=12345&redirect_uri=https%3a%2f%2flocalhost%2fmyapi01

After you’ve subscribed the api application, now let’s access the following admin consent url for the client application, in which c471620b-73a3-4a88-a926-eda184e6fde9 is the app’s ID of the client side.

https://login.microsoftonline.com/testdirectory.onmicrosoft.com/adminconsent?client_id=c471620b-73a3-4a88-a926-eda184e6fde9&state=12345&redirect_uri=https%3a%2f%2flocalhost%2ftestapp01

After you logged-in with the administrator account, you can find that the following consent screen is displayed.

Advertisements

Categories: Uncategorized

Tagged as: ,

2 replies »

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s