Divyesh Jesadiya
Divyesh Jesadiya

Reputation: 957

Could not use Graph API and Exchange scope in one auth flow of microsoft graph API

In my Laravel app, I am using https://github.com/dcblogdev/laravel-microsoft-graph package to Log in with M365. It was working fine till I changed the scopes in config/msgraph.php file. The default file is

<?PHP

return [

    /*
    * the clientId is set from the Microsoft portal to identify the application
    * https://apps.dev.microsoft.com
    */
    'clientId' => env('MSGRAPH_CLIENT_ID'),

    /*
    * set the tenant id
    */
    'tenantId' => env('MSGRAPH_TENANT_ID'),

    /*
    * set the application secret id
    */

    'clientSecret' => env('MSGRAPH_SECRET_ID'),

    /*
    * Set the url to trigger the oauth process this url should call return MsGraph::connect();
    */
    'redirectUri' => env('MSGRAPH_OAUTH_URL', 'connect'),

    /*
    * set the url to be redirected to once the token has been saved
    */

    'msgraphLandingUri'  => env('MSGRAPH_LANDING_URL'),

    /*
    set the tenant authorize URL
    */

    'tenantUrlAuthorize' => env('MSGRAPH_TENANT_AUTHORIZE'),

    /*
    set the tenant token URL
    */
    'tenantUrlAccessToken' => env('MSGRAPH_TENANT_TOKEN', 'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token'),

    /*
    set the authorize URL
    */
    'urlAuthorize' => 'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize',

    /*
    set the token URL
    */
    'urlAccessToken' => 'https://login.microsoftonline.com/'.env('MSGRAPH_TENANT_ID', 'common').'/oauth2/v2.0/token',

    /*
    set the scopes to be used, Microsoft Graph API will accept up to 20 scopes
    */

    'scopes' => 'offline_access openid AuditLog.Read.All DeviceManagementConfiguration.Read.All Directory.Read.All IdentityRiskyUser.Read.All Policy.Read.All RoleAssignmentSchedule.Read.Directory RoleManagement.Read.Directory RoleManagement.Read.All SecurityEvents.Read.All User.Read.All Reports.Read.All SharePointTenantSettings.Read.All Sites.Read.All Application.Read.All',

    /*
    The default timezone is set to Europe/London this option allows you to set your prefered timetime
    */
    'preferTimezone' => env('MSGRAPH_PREFER_TIMEZONE', 'outlook.timezone="India Standard Time"'),

    /*
    set the database connection
    */
    'dbConnection' => env('MSGRAPH_DB_CONNECTION', 'mysql'),
];

I am using clientId and clientSecret of an app that registered in my tenant and it is multi tenant app. above example is working and I can ask for consent of other tenant and after consent granting I can successfully fetch information of that tenant. But now, I need to also add Exchange.ManageAsApp in scope to connect ExchangeOnline and when I add it to scope like

'scopes' => 'offline_access openid AuditLog.Read.All DeviceManagementConfiguration.Read.All Directory.Read.All IdentityRiskyUser.Read.All Policy.Read.All RoleAssignmentSchedule.Read.Directory RoleManagement.Read.Directory RoleManagement.Read.All SecurityEvents.Read.All User.Read.All Reports.Read.All SharePointTenantSettings.Read.All Sites.Read.All Application.Read.All Exchange.ManageAsApp',

It is giving me could not log in error or went in to loop. I found that Graph API and Exchange have different auth flow. So, Any how can I generate one access token that have Graph API and Exchange access?

Upvotes: 1

Views: 208

Answers (1)

Nikolay
Nikolay

Reputation: 12245

The Azure AD does not support mixing scopes from different applications. You either need to make two authentication calls, or use "on behalf of" call to get the Exchange token from the Graph token you get first (or vice versa)

Meaning, you CANNOT generate a token that would support both Graph API and Exchange API, you will need two separate tokens for this. You make the first call to get the Graph token using graph-only scopes, and then you make the second call to get the Exchange token using exchange-only scopes.

See more on on-behalf-of flow here (automatically getting one token from another): https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-on-behalf-of-flow

I am not sure if the library you mention supports this scenario out of the box though, usually, it's referred to as "OBO" or "on behalf of" flow. Basically all you need to do to get the second token from the first one is just make one single call to Azure AD with proper parameters.

Upvotes: 3

Related Questions