尝试从 EWS Managed API 发送电子邮件时出现 401 未授权

401 Unauthorized when trying to send emails from EWS Managed API

好的,所以我正在开发一个必须自动向其他人发送电子邮件的插件。我知道 office-js 没有这样做的权限,我已经开始使用 EWS Managed API。我已经实施了 SSO 令牌并通过以下方式获得它:

Office.context.auth.getAccessTokenAsync()

获得令牌后,我向我的服务器发出请求调用我的 EWS Managed API 并尝试发送包含以下代码的电子邮件:

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

当我调用 emailMessage.SendAndSaveCopy(); 时,它抛出 401 错误。

如果我使用 WebCredentials(user, pass) 而不是 OAuthCredentials(ssoToken),它确实有效。我不明白为什么(我在 Azure 门户上也设置了权限)

融合应用与旧注册

您必须创建的 SSO(单点登录)应用程序需要通过 https://apps.dev.microsoft.com 创建。这是您创建 converged 应用程序的地方 - 它允许同意方使用他们的 Outlook.com 帐户或组织帐户(这是较新的方式)登录。

但是 EWS 没有使用它。 EWS 使用旧方法创建应用程序的身份验证方法,这是您需要通过 Azure 门户执行的操作 - 通过 AAD 应用程序注册。有关 EWS 身份验证的更多文档,请参见:https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/authentication-and-ews-in-exchange

基本上,您检索到的 OAuth 访问令牌可用于查询 Microsoft Graph(作为示例),但您不能使用它来调用 EWS。

这造成的一个非常重要的区别是 EWS(顾名思义,Exchange Web 服务)只是组织帐户。 Outlook.com 用户无法使用 API。

  • 如果您使用的是 SSO 框架,您将被锁定到 应用程序注册方式。您可以验证来自 Outlook.com/ 或组织帐户的用户。您可以访问 Microsoft Graph 和其他类似来源 - 但不能访问 EWS。
  • 如果您想使用 EWS - 您无法验证 Outlook.com 用户。并且您无法获得可以通过 SSO 调用 EWS 的令牌。

解决方案

  • 使用您检索的访问令牌(如果您请求正确的范围),您仍然可以发送邮件 - 您的解决方案也适用于 Outlook.com 用户。检查图表 API:https://docs.microsoft.com/en-us/graph/api/resources/mail-api-overview?view=graph-rest-1.0
  • 如果您坚持使用EWS,可以放弃访问令牌调用并使用makeEwsRequestAsync方法。这将要求您在 javascript 中编写 SOAP,但它有效。
  • 如果您不喜欢 JS 中的 SOAP 的想法(我完全理解)并且仍然想通过您的 C# 代码使用 EWS,您应该放弃使用 SSO 框架。而是使用 OAuth 针对您的 AAD 应用程序注册通过对话框 API 对用户进行身份验证(不是融合模型,而是通过 Azure 门户注册)

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