问题
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)
回答1:
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)
回答2:
You must also set the ExchangeServer.ImpersonatedUserId
property to the address of the user on whose behalf you are sending.
来源:https://stackoverflow.com/questions/53867075/401-unauthorized-when-trying-to-send-emails-from-ews-managed-api