401尝试从EWS托管API发送电子邮件时未经授权

时间:2018-12-20 10:43:37

标签: c# outlook exchangewebservices office-js outlook-web-addins

好,所以我正在开发一个插件,该插件必须自动向他人发送电子邮件。我知道office-js无权这样做,并且我已经开始使用EWS托管API。我已经实现了SSO令牌,并且获得了:

 mMainView = inflater.inflate(R.layout.fragment_request, container, false);

    mRequestList = (RecyclerView) mMainView.findViewById(R.id.request_list);
    mAuth = FirebaseAuth.getInstance();

    mCurrent_user_id = mAuth.getCurrentUser().getUid(); //at this line


    mRequestDatabase = FirebaseDatabase.getInstance().getReference().child("Friend_req").child(mCurrent_user_id);
    mRequestDatabase.keepSynced(true);
    mUsersDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
    mUsersDatabase.keepSynced(true);

获得令牌后,我将对拥有EWS托管API的服务器进行请求调用,并尝试发送包含以下代码的电子邮件:

Office.context.auth.getAccessTokenAsync()

当我致电ExchangeService exService = new ExchangeService(); exService.Url = new Uri(ewsUrl); ExchangeCredentials credentials = new OAuthCredentials(ssoToken); exService.Credentials = credentials; EmailMessage emailMessage = new EmailMessage(exService); 时,它会引发401错误。

如果我确实使用emailMessage.SendAndSaveCopy();而不是WebCredentials(user, pass),它将起作用。我不明白为什么(我在Azure Portal上也设置了权限)

2 个答案:

答案 0 :(得分:0)

融合的应用程序与旧的注册信息

您必须通过https://apps.dev.microsoft.com创建的必须创建的SSO(单点登录)应用程序。在这里创建融合应用程序-允许被许可方使用其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 Services)仅是组织帐户。您不能为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通过Dialog API通过Dialog API对用户进行身份验证(不是聚合模型,而是通过Azure门户进行注册)

答案 1 :(得分:0)

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