1
votes

I'm trying to authorize my multitenant saas web app to communicate with an Office 365 account. Well, apparently my app needs admin consent because of the permissions, so I have to implement that.

But I would also like for the user to consent as well, so he can go into his account and click "Authorize" after the admin has consented.

How do I implement this? There's already an authorization flow in place, but it just authorizes per-user (the idea of admin consent was entirely unknown at the time). When a non-admin tries to authorize his account, he gets the error "This operation can only be performed by an administrator". When an admin goes through this, it authorizes THEM, and when an admin goes through admin consent, it still just authorizes them. The regular user still gets that error.

These are the permissions my app is requesting:

  • Calendars.Read
  • Calendars.ReadWrite
  • Contacts.ReadWrite
  • Mail.ReadWrite
  • Mail.Send
  • Tasks.ReadWrite

This is the data we're storing for it:

user_id
access_token
expires_on
resource
refresh_token
scope
id_token

It also doesn't help that I'm only basically familiar with oauth 2.0.

I have been pouring through articles, forum questions, help guides, and documentation for a couple weeks now. Help.

UPDATE: So I'm thinking that maybe I need to add an is_admin flag to my data? So when the admin consents, I save all of the above fields along with is_admin => 1. So when a standard user goes to consent office 365, my app will check to see if their account has an oauth access token with is_admin, which would mean it's been authorized by an account admin and I can proceed to authorize them.

Am I getting warm?

Sign in URL:

https://login.microsoftonline.com/common/oauth2/authorize?
response_type=code
&client_id={my_client_id}
&redirect_uri=https%3A%2F%2Fapp.example.com%2Fintegrations%2Foffice-auth&state=V6diTW2TaHl1Zpawg1AFub7fWtKfGnyl1464023103
&resource=https%3A%2F%2Foutlook.office365.com%2F
&prompt=consent
1
Those permissions don't require admin consent, so you shouldn't have to do this. What does your sign in URL look like?Jason Johnston
Thanks for putting your sign in URL. From that you are using the v1 auth endpoints, so your permissions are all specified in advance as part of the app registration. Do you also have permissions specified for Active Directory maybe? Some of those require admin consent.Jason Johnston
I used to have the permissions Directory.AccessAsUser.All Directory.Read.All Directory.ReadWrite.All, but I removed them to get around this a few hours ago. Perhaps something is stale?Captain Hypertext
Ah yeah, those will do it. If you've removed them, I'd expect it to unblock since you have the prompt=consent parameter. What error are you getting?Jason Johnston
The v2 app model is the newer model supported by Azure that supports consumer and Office 365 accounts. It's easier to register apps and you specify permissions dynamically (scopes are encoded in the sign in URL). The downside is that it doesn't support client credential flow yet, but it doesn't sound like you need that. For a walkthrough using PHP, see dev.outlook.com/restapi/tutorial/php.Jason Johnston

1 Answers

0
votes

Fixed it. It was the application permissions in Azure (as opposed to the delegated permissions). It had "Read and Write All Mailboxes", among a few others that were essentially giving permissions to access all users in the organization.

Removing that, user authorization works, and I don't even need admin consent.