Authentication flow Service to Service Microsoft Graph and Bookings API

645 Views Asked by At

I am building a custom mobile application that has a client, custom backend server (I'm building) and interacts with numerous other api's. One of these api's is Microsoft bookings.

The problem I'm facing is I need to be authenticated via server to server, with a shared client secret. I'm aware of the numerous docs from MS but have yet to find a solution. I'm wondering if Server to server is even possible with Bookings.

I am able to get an access_token server to server with these permissions. (I have granted 'all permissions' to this app in Azure AD already).

"roles": [
"Calls.JoinGroupCall.All",
"OnlineMeetings.Read.All",
"OnlineMeetings.ReadWrite.All",
"Application.ReadWrite.OwnedBy",
"Calendars.Read",
"People.Read.All",
"Application.ReadWrite.All",
"Calls.InitiateGroupCall.All",
"Directory.ReadWrite.All",
"Calls.JoinGroupCallAsGuest.All",
"Sites.Read.All",
"Sites.ReadWrite.All",
"Sites.Manage.All",
"Files.ReadWrite.All",
"Directory.Read.All",
"User.Read.All",
"Calendars.ReadWrite",
"Mail.Send",
"ProgramControl.Read.All",
"ProgramControl.ReadWrite.All",
"Calls.Initiate.All"

],

Those are the permissions from the decoded token. When I go to make calls to the Bookings api I receive 401. enter image description here

I can however use this token to access different graph endpoints no problem.

I will note, that I am able to make successful calls to the bookings api through Graph Explorer with my account, not related to this 'Application in Azure AD'.

Does this resource in Azure AD need a bookings License? Is this even possible S2S?

Are there any other ways to bypass this without user credentials?

Thanks.

2

There are 2 best solutions below

2
On

Microsoft Bookings API doesn't seem to support "Application Permissions" so far.

Only permissions available are "Delegated Permissions", which means your token has to be acquired with the context of a signed-in user.

Here are two Microsoft documentation sources that I came across:

I know you mention Server to Server authentication using a client secret. AFAIK, that case will NOT work directly, because clientId and clientSecret only provide an application's identity (which can't be assigned any permissions because there are no relevant application permissions available for this API).

Just in case you can have some User context involved, here is code from bookings samples link above, to acquire the token in a Native application using ADAL

var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/common/");

var authenticationResult = await authenticationContext.AcquireTokenAsync(
  "https://graph.microsoft.com/",
  clientApplication_ClientId,
  clientApplication_RedirectUri,
  new PlatformParameters(PromptBehavior.RefreshSession));

// The results of this call are sent as the Authorization header of each HTTPS request to Graph.
var authorizationHeader = authenticationResult.CreateAuthorizationHeader();

Suggestions on ways to make this scenario work

  1. On Behalf Of Flow

    Your mobile application client could prompt a user for credentials to act on Behalf of the user and call your backend web API, which in turn calls the downstream API like Bookings API. This is called Service to Service Calls on behalf of the User

    Here is a code sample which shows exactly this with a native application (WPF) and an SPA. In your case, just replace the WPF application with your mobile client application for understanding purposes and rest of the scenario becomes very similar.

    Calling a downstream web API from a web API using Azure AD

    enter image description here

  2. ROPC Grant (Not Recommended)

    Resource Owner Password Credentials grant can help as your application will have end user password available to it, but it has multiple issues and any security guidance will discourage you from using it.

    ROPC opens up security risks, doesn't follow best practices and has functionality issues as well. ROPC doesn't work with MFA enabled users as well as federated authentication users.

    For all practical purposes, you should avoid ROPC as long as possible. You can find the same recommendation in ADAL documentation itself and multiple other documentations from Microsoft or even generally about OAuth 2.0.

0
On

So I spent over a week trying to solve this problem due to the MS doc nightmare. I'm only posting to help others!

Bookings doesn't support service to service yet. So if you wan't to implement this without a user physically signing in, IE. If you have a dedicated booking admin account credentials you have to hard code the clients credentials.

I found my answer here https://stackoverflow.com/a/49814924/9105626 enter image description here