2
votes

I would like to get some clarification on whether or to what degree OAuth 2.0 can be used with EWS applications. Here is my situation: I maintain an application that accesses Office 365 data. It uses EWS with Basic authentication. In response to the plan to no longer support Basic authentication and to deprecate EWS, I developed a new version of the application that uses Microsoft Graph and OAuth 2.0. I had no problem getting OAuth to work. However there are still some significant shortcomings in Graph (for our needs) so what I would like to do now is support OAuth in our original EWS application.

My hope was that I could just take a token generated in the same way I do in the Graph application, and feed it into my EWS calls in the "Authorization: bearer ..." header of the http call. (I am not using the EWS managed API or any kind of authentication library, just making direct http calls using libcurl). Unfortunately this results in http error 401 Unauthorized.

Here is how I am obtaining the token:

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token

with data:

client_id={client_id}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret={client_secret}&grant_type=client_credentials

This produces http 200 and a returned token:

eyJ0eXAiOiJKV1QiLCJub25jZSI6...

As I said, using this token in the Authorization header of the EWS call fails with http 401. However, using the same token with a Graph call works. I did try replacing the scope with ""https://outlook.office365.com/.default" but it produced the same results.

I have looked at the API permissions granted to my application in the Azure portal. They are all of type Microsoft Graph. I don't see any "EWS" permissions available to request. Could this be my problem?

Any help on this issue will be appreciated, thank you.

Update: I did go ahead and add all the "Legacy Exchange" API permissions, and re-authorized my test tenant for the application. Still no luck. I am trying to execute the "GetFolder" EWS API. Only the graph.microsoft.com scope works to get a token, so maybe that needs to change?

1

1 Answers

3
votes

I would suggest you start with https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth

For EWS if you are using the Client Credentials grant (which is what you using in you example) then the only permission that will work is the full_access_as_app which is under the legacy Exchange Application permissions. The scope you need to use is https://outlook.office365.com/.default . You can check the token your generating in https://jwt.io/ . Eg the Audience should be for outlook.office365.com and the scope should have full_access_as_app.

The one last thing you need to do in your EWS code is to include the EWS impersonation header set to the Mailbox you want to impersonate (or access) eg

<soap:Header>
  <t:ExchangeImpersonation>
    <t:ConnectingSID>
      <t:PrimarySmtpAddress>[email protected]</t: PrimarySmtpAddress>
    </t:ConnectingSID>
  </t:ExchangeImpersonation>
</soap:Header>