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

Oauth 2.0 如何在没有交互式登录的情况下通过EWS访问权限受限的邮箱?,oauth-2.0,azure-active-directory,microsoft-graph-api,office365,exchangewebservices,Oauth 2.0,Azure Active Directory,Microsoft Graph Api,Office365,Exchangewebservices,我们需要从专用exchange/outlook邮箱(O365)的联系人文件夹中读取通讯组列表。该进程必须作为服务运行,不需要用户交互 不幸的是,Graph API不支持分发列表(即使Graph beta版也不支持)。因此,我们必须使用另一个API—我尝试使用EWS 我成功地授予了我们服务的“完全访问”权限。但是,这允许读取和修改任何邮箱中存在安全风险的任何数据。仅授予从一个邮箱读取某些通讯组列表的权限是不可接受的 因此,我尝试使用ROPC流,该流应允许对用户进行身份验证,然后使用该用户的权限访问

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

不幸的是,Graph API不支持分发列表(即使Graph beta版也不支持)。因此,我们必须使用另一个API—我尝试使用EWS

我成功地授予了我们服务的“完全访问”权限。但是,这允许读取和修改任何邮箱中存在安全风险的任何数据。仅授予从一个邮箱读取某些通讯组列表的权限是不可接受的

因此,我尝试使用ROPC流,该流应允许对用户进行身份验证,然后使用该用户的权限访问邮箱。我遵循以下信息:

(顺便说一句,我在这里的讨论中发现了这篇文章的链接:其中包含有关该主题的更多信息。)

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

据了解,这已经不起作用了。那么,在没有完全访问权限和交互登录的情况下,如何从特定邮箱读取通讯组列表呢

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

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);
string[]ewscopes={”https://outlook-tdf-2.office.com/EWS.AccessAsUser.All" };
IPPublicClientApplicationClientApplication=PublicClientApplicationBuilder.Create(appId).WithAuthority(AzureCloudInstance.AzurePublic,tenantId).Build();
NetworkCredential credentials=新的NetworkCredential(appUsername、appPassword);
AuthenticationResult authResult=await clientApplication.AcquireTokenByUsernamePassword(EWSCOpes,credentials.UserName,credentials.SecurePassword)。ExecuteAsync().ConfigureAwait(false);
ExchangeService ExchangeService=新的ExchangeService
{
Url=新Uri(“https://outlook.office365.com/EWS/Exchange.asmx"),
凭据=新的OAuthCredentials(authResult.AccessToken),
};
ItemView视图=新的ItemView(int.MaxValue)
{
PropertySet=新的PropertySet(ItemSchema.Id),
};
SearchFilter.IsEqualTo filter=新的SearchFilter.IsEqualTo(ItemSchema.ItemClass,“IPM.Contact”);
FindItemsResults 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的支持


请对此功能请求进行投票:

您的代码中的作用域是错误的(我不确定您从何处获得该作用域)

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"
在正确的范围内使用代码可以很好地工作

但是,为什么Azure UI中没有添加Exchange旧版权限的选项(上面提到的MS docu中的步骤6)


它尚未从AzureUI中删除,只是将所有Exchange旧版权限(包括Exchange Admin cmdlet中使用的权限,它实际上不是旧版API)移动到了图形权限下。为什么他们这样做而没有很好地沟通(我今天也只会看到),我不确定。

昨天11月19日,微软更新了文档:

按照新的文档,它可以(再次)工作。主要区别在于使用了缩短的作用域“EWS.AccessAsUser.All”,而不是在许多示例和帖子中找到的任何完整作用域,例如https://outlook.office.com/EWS.AccessAsUser.All”, “https://outlook.office365.com/EWS.AccessAsUser.All“等等


感谢MS浪费我的时间。

您也可以使用.Net自动化Exchange powershell。这里是文档-有很多功能请求:您列出的一个,可能还有更多。我已经投了所有人的票,但不确定是否有人对此有一个概述,并意识到这都是指相同的分发列表支持…ROPC可以正常工作,但听起来您对它的工作方式有点困惑,例如链接到应用程序权限,这是用户凭据流,对于ROPC,您需要使用委托权限,并确保您的应用程序注册被标记为公共,并且应该可以正常工作。您应该发布您使用的代码,以便更容易理解并指出您在本例中的错误。@GlenScales我完全按照第一个SO链接中描述的步骤进行了操作。在检查链接(以及链接页面中的链接)时,您可以找到所有的代码。该链接中有多种不同的答案,您使用哪一个,我一直使用ROPC和EWS,因此我试图帮助您找出错误,但需要更多信息。@GlenScales我根据MS文档在此处进行设置:(当然,仅授权设置!我完全按照此处所述进行注册,并使用底部1:1的代码)。然后我做了这里提到的两个更改:您是否检查了访问令牌,特别是查看受众和范围谢谢Glen的所有回答!它让我一直在尝试,并让我最终找到了答案。但是您的建议对我不起作用-正如我说过的,我尝试了许多范围,包括您建议的和它们都不起作用-只有我现在发布的新MS文档中的解决方案起作用。我将对你的一些评论进行更新投票,以某种方式奖励你。这可能会