15
votes

I'm attempting to build an application that will have access to all of an organization's calendars (users, rooms, etc).

Currently my auth flow will sign in on behalf of a tenant user and make use of refresh tokens to access needed resources. As soon as I make a request to:

https://outlook.office365.com/api/v1.0/users/{room-resource@email}/events

My application is responded with a 401

From my gathering, it seems that this flow is limited to a single user's scope. Although the tenant admin should have permission to see any of the room resources, the room is technically a user itself so the API will respond with a forbidden error. It now seems that the proper flow is a tenant admin must grant permission to my application using the new Service OAuth Flow.

Reading through this post it seems that the API is making use of OAuth client credentials grant type (app only tokens). Instead of using the /oauth/common endpoint I now have to use /oauth/tenant-id which I can retrieve via the JWT token returned in the code+id_token response type. This leads to my first question:

Is using the OpenID flow the only way to initially retrieve the tenant ID?

Next is where things get a little fuzzy for me.

We now have to generate an X.509 SSL certificate and upload the fingerprint/value to our Azure application manifest. Easy enough.

Then according to the discussion in Office 365 Rest API - Daemon week authentication we build a specific JWT, base64 encode it, and sign it with our cert.

I haven't actually gotten to the last few steps here but I will post my results when I can. I'm just making sure that I seem to be following the correct procedure for what resources I'm trying to access. I know the service tokens are a fairly new feature, it's just unfortunate that I had to find the flow of sending the signed JWT on Stackoverflow rather than official MSFT documentation...

I also noticed that since we're using the client credentials flow we will not receive a refresh_token in the response. So for my final question:

When accessing different resources (ie Graph API/Office365 API) do I just get a different access token for each resource using my signed request instead of using refresh tokens for multiple resources?

If the general direction I seem to be going is correct let me know! Any help is greatly appreciated.

2

2 Answers

3
votes

Late to the party, but I've been fighting thru this too, and here's what I've found.

The OAuth route into Office365 will only allow you to access your own calendar. Doesn't matter what permissions the app has in Azure, or what you configure per user. It's a limitation to the API.

This was confirmed by MSFT in the comments to this StackOverflow question:
Office365 API - Admin accessing another users/room's calendar events

You can, however, use Basic Auth to gain access to another person's calendar.

1) Configure the "Primary" user (the one you authenticate with) to have access to the "Secondary" user's (the one with the calendar you want to view) account. To do this, go in to the Exchange Properties for the Secondary user -> Mailbox Delegation and give Full Access to the Primary User.

2) Pass the authentication along with the request to the Office365 API:

<?php
$username = '[email protected]';
$password = 'mypass';
$URL = 'https://outlook.office365.com/api/v1.0/users/[email protected]/events';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$URL);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");

$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$result=curl_exec ($ch);
curl_close ($ch);

print_r($result);

?>

3) If you've done everything right, you now have the events for the Secondary user!

2
votes

You are following the right path. You will need one token per resource, which will grant you access to all users. When that token expires, you will just request a new one.