简体   繁体   中英

401 Unauthorized when trying to send emails from EWS Managed API

Ok so I am developing an addin which must automatically send emails to others. I know that office-js does not have permissions to do so and I have started using EWS Managed API. I have implemented SSO token and I get it with:

Office.context.auth.getAccessTokenAsync()

After I get the token I make a request call to my server where I have my EWS Managed API and try to send an email with the folowing code:

ExchangeService exService = new ExchangeService();
exService.Url = new Uri(ewsUrl);
ExchangeCredentials credentials = new OAuthCredentials(ssoToken);
exService.Credentials = credentials;
EmailMessage emailMessage = new EmailMessage(exService);

When I call emailMessage.SendAndSaveCopy(); it throws 401 Error.

If I do use WebCredentials(user, pass) instead of OAuthCredentials(ssoToken) it does work. I do not understand why (I also have set permissions on Azure Portal)

Converged apps vs Old registrations

The SSO (Single Sign on) app that you had to create, needed to be created through https://apps.dev.microsoft.com . This was where you create the converged apps - which allows the consented parties to sign-in with their Outlook.com accounts or the organizational accounts (which is the newer way).

However EWS is not using this. EWS is using the authentication method of older way of creating apps, which is what you need to do through Azure Portal - through AAD App registrations. More documentation on authentication of EWS here: https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/authentication-and-ews-in-exchange

So basically, the OAuth access token which you've retrieved can be used to query Microsoft Graph (as an example) but you can't use that to call EWS.

One very significant difference this creates is EWS is (as the name suggests, Exchange Web Services) is organizational accounts only. You can't use that API for the Outlook.com users.

  • If you're using SSO framework, you are locked to the new way of app registrations. You can authenticate users from Outlook.com / or organizational accounts. You can access Microsoft Graph and other similar sources - but not EWS.
  • If you want to use EWS - you can't authenticate Outlook.com users. And you can't get the token which you can call EWS through SSO.

Solutions

  • With the access token that you retrieve (if you request the correct scopes) you can still send mail - and your solution would also work with Outlook.com users. Check the Graph API: https://docs.microsoft.com/en-us/graph/api/resources/mail-api-overview?view=graph-rest-1.0
  • If you insist on using EWS, you can drop the access token call and use the makeEwsRequestAsync method. This will require you to write SOAP in javascript but it works.
  • If you dislike the idea of SOAP in JS (which I completely understand) and still want to use EWS through your C# code, you should drop using the SSO framework. Instead authenticate the user through the Dialog API using OAuth against your AAD App registration (Not the converged model, but registration through the Azure Portal)

您还必须将ExchangeServer.ImpersonatedUserId属性设置为代表您发送的用户的地址。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM