当前位置: 首页 > 知识库问答 >
问题:

如何在没有交互式登录的情况下通过EWS访问具有受限权限的邮箱?

孔茂
2023-03-14

我们需要从专用 exchange/outlook 邮箱 (O365) 的联系人文件夹中读出通讯组列表。该进程必须作为服务运行,没有用户交互。

不幸的是,图形应用编程接口不支持分发列表(甚至图形测试版也不支持)。因此,我们必须使用另一个应用编程接口——我尝试使用EWS。

我成功地向我们的服务授予了full_access_as_app权限。然而,这允许读取和修改任何邮箱中的任何数据,这是一个安全风险。不允许只授予此权限从一个邮箱中读取某些通讯组列表。

所以我尝试使用ROPC流,该流应该允许对用户进行身份验证,然后使用该用户的权限访问邮箱。我遵循了以下信息:如何在服务/守护程序应用程序中获取EWS托管API的OAuth2访问令牌

(顺便说一下,我在这里的讨论中找到了这篇文章的链接:https://github . com/Microsoft graph/Microsoft-graph-docs/issues/5659,其中有关于这个主题的更多信息。)

我完全遵循了上面提到的步骤,但不幸的是这不起作用:我总是在进行EWS调用时得到一个“401未授权”异常(OAuth调用成功),没有其他信息。

根据https://developer . Microsoft . com/en-us/graph/blogs/upcoming-changes-to-exchange-we b-services-EWS-API-for-office-365/这已经不起作用了。那么,在没有完全访问权限和交互式登录的情况下,我如何从特定的邮箱中读取分发列表呢?

按要求在此处编辑完整代码:

string[] ewsScopes = { "https://outlook-tdf-2.office.com/EWS.AccessAsUser.All" };

IPublicClientApplication clientApplication = PublicClientApplicationBuilder.Create(appId).WithAuthority(AzureCloudInstance.AzurePublic, tenantId).Build();
NetworkCredential credentials = new NetworkCredential(appUsername, appPassword);

AuthenticationResult authResult = await clientApplication.AcquireTokenByUsernamePassword(ewsScopes, credentials.UserName, credentials.SecurePassword).ExecuteAsync().ConfigureAwait(false);

ExchangeService exchangeService = new ExchangeService
{
    Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
    Credentials = new OAuthCredentials(authResult.AccessToken),
};

ItemView view = new ItemView(int.MaxValue)
{
    PropertySet = new PropertySet(ItemSchema.Id),
};
SearchFilter.IsEqualTo filter = new SearchFilter.IsEqualTo(ItemSchema.ItemClass, "IPM.Contact");

FindItemsResults<Item> ewsResult = await exchangeService.FindItems(WellKnownFolderName.Contacts, filter, view).ConfigureAwait(false);

我还尝试了其他范围,如“https://outlook.office.com/EWS.AccessAsUser.All“或”https://outlook.office365.com/EWS.AccessAsUser.All“但没有成功。我觉得问题可能与范围有关?我可以看到,添加权限时在Azure UI中列出的Exchange旧版API现在不存在了。。。?

共有3个答案

唐啸
2023-03-14

通讯组目前仅在Exchange PowerShell中公开,目前不支持通过Microsoft Graph API。

请在用户之声上对此功能请求进行投票:

严亦
2023-03-14

昨天11月19日微软更新了留档:https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth

根据新文档,它(再次)工作。主要区别是使用缩短的范围“EWS.AccessAsUser.All”,而不是许多示例和帖子中的任何完整范围,如“https://outlook.office.com/EWS.AccessAsUser.All”, “https://outlook.office365.com/EWS.AccessAsUser.All“等。

谢谢MS浪费我的时间。

吕淮晨
2023-03-14

代码中的范围是错误的(我不确定你从哪里得到的)它应该是

string[] ewsScopes = { "https://outlook.office.com/EWS.AccessAsUser.All" };

将您的代码与您的范围一起使用会产生401错误,如果您查看EWS响应的响应标头,它实际上告诉您范围是问题所在,例如

2000003;reason="The audience claim value is invalid for current resource. Audience claim is 'https://outlook-tdf-2.office.com/', request url is 'https://outlook.office365.com/EWS/Exchange.asmx' and resource type is 'Exchange'.";error_category="invalid_resource"

使用正确范围的代码工作正常

但是为什么添加Exchange旧版权限的选项(上面提到的MS文档中的第6步)从Azure UI中消失了呢?

它并没有从AzureUI中移除,他们只是将所有的Exchange传统权限(包括在Exchange Admin cmdlets中使用的权限,它并不是真正的传统API)移到了图形权限下。为什么他们这样做,没有很好地沟通(我也是今天才看到的),我不知道。

 类似资料:
  • 问题内容: 我有个问题。我想防止用户访问页面而不登录jsf2。当用户直接将受限制的页面网址写入浏览器时,他/她应该看不到该页面。就像上述情况那样,他/她必须被重定向到登录页面。如何以编程方式执行此操作? 问题答案: 这取决于您如何设置登录名。您似乎正在使用本地认证,其中将登录用户设置为会话范围的受管Bean的属性。因为使用Java EE提供的容器管理登录名,已经考虑了防止访问受限页面。 假设你已经

  • 我在用 Linux 编写的 CUDA 代码中使用了一个库(该库称为 cublas),我可以使用 nvcc 成功编译我的代码,但是当我运行代码时出现此错误: 加载共享库时出错:libcublas.so.7.5:无法打开共享对象文件:没有这样的文件或目录 我发现此链接是一种解决方案,建议运行一些命令以解决问题。基于此链接的一种解决方案是运行以下命令: export LD_LIBRARY_PATH=$L

  • 我有一个bash文件,从终端执行时可以正常工作。 注意:tensorflow\u p36是一个内置的conda环境,不需要从特定的目录调用。它可以从任何目录激活。我认为这是亚马逊深度学习AMIs的一个特点。 如果我用sudo运行这个bash脚本,它不会激活虚拟环境,并且在默认的python环境中工作。python文件只能在该虚拟环境中运行。 我在这里尝试了所有3个替代方案(rc.local、. c

  • 我正在使用Unity游戏引擎创建游戏。在这个游戏中,我抓取了一个屏幕截图,并将其保存到Unity的默认文件夹(“Application.PersistentDataPath”): /data/data/de.mytest.mygame/files/screenshot.png 如何修复此权限问题? 编辑:创建意图如下所示:

  • 问题内容: 我正在尝试在办公室笔记本电脑上安装JDK,但是它说我需要管理员权限。我只能在工作中使用自己的帐户。 没有管理员权限的情况下如何安装Java开发套件? 问题答案: 这是一种在没有管理员特权或没有管理员密码的情况下安装Java的解决方法。为此,您需要安装不需要管理员特权的cygwin。在utils中,确保您选择cabextract.exe进行安装。 启动Cygwin Bash外壳。 键入c