如何在没有交互式登录的情况下通过 EWS 访问权限受限的邮箱?
How can I access a mailbox with restricted permissions through EWS without interactive login?
我们需要从专用 exchange/outlook 邮箱 (O365) 的联系人文件夹中读出通讯组列表。该进程必须 运行 作为没有用户交互的服务。
不幸的是,Graph API 不支持通讯组列表(甚至 Graph beta 版也不支持)。因此,我们必须使用另一个 API - 我尝试使用 EWS。
我成功地向我们的服务授予 full_access_as_app 权限。然而,这允许读取和修改任何邮箱中的任何数据,这是一个安全风险。仅授予此权限以从一个邮箱中读取某些通讯组列表是不可接受的。
所以我尝试使用应该允许对用户进行身份验证然后使用该用户的权限访问邮箱的 ROPC 流程。我按照这里的信息:How to get OAuth2 access token for EWS managed API in service/daemon application
(顺便说一句,我在此处的讨论中找到了这个 post 链接:https://github.com/microsoftgraph/microsoft-graph-docs/issues/5659 其中包含有关该主题的更多信息。)
我完全按照上述步骤操作,但不幸的是,这不起作用:在执行 EWS 调用(OAuth 调用成功)时,我总是收到“401 未授权”异常,并且没有其他信息。
根据 https://developer.microsoft.com/en-us/graph/blogs/upcoming-changes-to-exchange-web-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 现在不见了...?
分发组目前仅在 Exchange PowerShell 中公开,目前不受 Microsoft Graph 支持API。
请在 UserVoice 上对此功能请求投票:
你代码中的范围是错误的(我不确定你从哪里得到的)它应该是
string[] ewsScopes = { "https://outlook.office.com/EWS.AccessAsUser.All" };
将您的代码与您拥有的范围一起使用会产生 401 错误,如果您查看 EWS 响应的响应 headers,它实际上会告诉您范围是问题所在,例如
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"
在正确的范围内使用您的代码可以正常工作
But then why is the option to add the Exchange Legacy permission (step 6 in the MS docu mentioned above) gone from the Azure UI?
它尚未从 AzureUI 中删除,他们只是将所有 Exchange 遗留权限(包括在 Exchange Admin cmdlet 中使用的那些并不是真正的遗留 API)移动到图形权限下.为什么他们这样做,没有很好地沟通(我也是今天才看到)我不确定。
昨天 11 月 19 日微软更新了文档:https://docs.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 浪费我的时间。
我们需要从专用 exchange/outlook 邮箱 (O365) 的联系人文件夹中读出通讯组列表。该进程必须 运行 作为没有用户交互的服务。
不幸的是,Graph API 不支持通讯组列表(甚至 Graph beta 版也不支持)。因此,我们必须使用另一个 API - 我尝试使用 EWS。
我成功地向我们的服务授予 full_access_as_app 权限。然而,这允许读取和修改任何邮箱中的任何数据,这是一个安全风险。仅授予此权限以从一个邮箱中读取某些通讯组列表是不可接受的。
所以我尝试使用应该允许对用户进行身份验证然后使用该用户的权限访问邮箱的 ROPC 流程。我按照这里的信息:How to get OAuth2 access token for EWS managed API in service/daemon application
(顺便说一句,我在此处的讨论中找到了这个 post 链接:https://github.com/microsoftgraph/microsoft-graph-docs/issues/5659 其中包含有关该主题的更多信息。)
我完全按照上述步骤操作,但不幸的是,这不起作用:在执行 EWS 调用(OAuth 调用成功)时,我总是收到“401 未授权”异常,并且没有其他信息。
根据 https://developer.microsoft.com/en-us/graph/blogs/upcoming-changes-to-exchange-web-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 现在不见了...?
分发组目前仅在 Exchange PowerShell 中公开,目前不受 Microsoft Graph 支持API。
请在 UserVoice 上对此功能请求投票:
你代码中的范围是错误的(我不确定你从哪里得到的)它应该是
string[] ewsScopes = { "https://outlook.office.com/EWS.AccessAsUser.All" };
将您的代码与您拥有的范围一起使用会产生 401 错误,如果您查看 EWS 响应的响应 headers,它实际上会告诉您范围是问题所在,例如
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"
在正确的范围内使用您的代码可以正常工作
But then why is the option to add the Exchange Legacy permission (step 6 in the MS docu mentioned above) gone from the Azure UI?
它尚未从 AzureUI 中删除,他们只是将所有 Exchange 遗留权限(包括在 Exchange Admin cmdlet 中使用的那些并不是真正的遗留 API)移动到图形权限下.为什么他们这样做,没有很好地沟通(我也是今天才看到)我不确定。
昨天 11 月 19 日微软更新了文档:https://docs.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 浪费我的时间。