Oauth 2.0 OAuth 2.0与Exchange Web服务的配合使用

Oauth 2.0 OAuth 2.0与Exchange Web服务的配合使用,oauth-2.0,microsoft-graph-api,exchangewebservices,Oauth 2.0,Microsoft Graph Api,Exchangewebservices,我想澄清一下OAuth2.0是否可以或在多大程度上用于EWS应用程序。以下是我的情况:我维护一个访问Office 365数据的应用程序。它使用带有基本身份验证的EWS。为了响应不再支持基本身份验证和反对EWS的计划,我开发了一个使用MicrosoftGraph和OAuth2.0的应用程序的新版本。我让OAuth工作没有问题。然而,Graph中仍然存在一些明显的缺陷(出于我们的需要),所以我现在想做的是在我们最初的EWS应用程序中支持OAuth 我的希望是,我可以像在Graph应用程序中一样获取生

我想澄清一下OAuth2.0是否可以或在多大程度上用于EWS应用程序。以下是我的情况:我维护一个访问Office 365数据的应用程序。它使用带有基本身份验证的EWS。为了响应不再支持基本身份验证和反对EWS的计划,我开发了一个使用MicrosoftGraph和OAuth2.0的应用程序的新版本。我让OAuth工作没有问题。然而,Graph中仍然存在一些明显的缺陷(出于我们的需要),所以我现在想做的是在我们最初的EWS应用程序中支持OAuth

我的希望是,我可以像在Graph应用程序中一样获取生成的令牌,并将其输入到http调用的“Authorization:bearer…”头中的EWS调用中。(我没有使用EWS管理的API或任何类型的身份验证库,只是使用libcurl进行直接http调用)。不幸的是,这会导致http错误401

以下是我获取令牌的方式:

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
关于数据:

client_id={client_id}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret={client_secret}&grant_type=client_credentials
这将生成http 200和返回的令牌:

eyJ0eXAiOiJKV1QiLCJub25jZSI6...
正如我所说的,在EWS调用的授权头中使用该令牌在http 401中失败。但是,在图形调用中使用相同的令牌是可行的。我确实尝试过将作用域替换为“”https://outlook.office365.com/.default但它产生了同样的结果

我已经查看了Azure门户中授予我的应用程序的API权限。它们都是Microsoft Graph类型。我没有看到任何可请求的“EWS”权限。这可能是我的问题吗

在此问题上的任何帮助都将不胜感激,谢谢


更新:我确实添加了所有“旧版Exchange”API权限,并重新授权了该应用程序的测试租户。仍然没有成功。我正在尝试执行“GetFolder”EWS API。只有graph.microsoft.com作用域可以获取令牌,所以可能需要更改吗?

我建议您从

对于EWS,如果您正在使用客户端凭据授权(这是您在示例中使用的)然后,唯一有效的权限是旧版Exchange应用程序权限下的“完全访问”应用程序。您需要使用的范围是。您可以在中检查生成的令牌。例如,访问群体应该是outlook.office365.com,范围应该具有“完全访问”应用程序

在EWS代码中,您需要做的最后一件事是将EWS模拟头设置为要模拟(或访问)的邮箱,例如


alisa@contoso.com

Ah,关于添加ExchangeImpersonation的部分是我所缺少的。它现在似乎工作得很好。非常感谢。11月24日更新:当我要求一位新客户在“受支持的旧版API”下添加“Exchange”权限时,我们发现它不再存在。唯一的旧版API是“Azure Active Directory图形””“怎么了?是否不再支持Exchange与OAuth一起使用?它们刚刚在Azure门户中移动,因此EWS权限以及Exchange远程Powershell所需的权限现在在Graph API下。(我不知道为什么会有这样的变化)实际上我可以在“API我的组织用户”下找到它。在搜索框中输入“Office 365”,然后选择“Office 365 Exchange Online”。使用Microsoft Identity Client v4.27中引用的示例代码,对
AcquireTokenForClient
的调用将永远不会返回。删除
wait
,添加
.Result
并使用单独的
try-catch
块。这个答案中的细节