Office 365 / EWS使用OAuth进行身份验证:受众声明值无效

本文关键字:声明 无效 身份验证 EWS 使用 OAuth Office | 更新日期: 2023-09-27 18:09:44

我还在纠结这个问题。请参考我之前的问题。

我正在做一个应用程序(目前是命令行),它应该通过EWS管理的API访问Office 365/Exchange。目标是通过OAuth2进行身份验证。

我在Azure AD中注册了一个应用程序。
我从那里使用了ClientID
我生成了一个App Secret/Key
我已经授权了"完全访问用户邮箱(预览)"&;App的权限

我使用ADAL像这样检索访问令牌:

var authority = "https://login.windows.net/<tenant>"
var authContext = new AuthenticationContext(authority);
var clientCredential = new ClientCredential("<clientId>", "<appKey>");
result = OAuthTokenManager.authContext.AcquireToken("<my ResourceID>", clientCredential);

我确实得到了一个访问令牌。解码后的值为:

{
 "typ": "JWT",
 "alg": "RS256",
 "x5t": "kriMPdmBvx68skT8-mPAB3BseeA"
}.
{
 "aud": "<my resource ID>",
 "iss": "https://sts.windows.net/2d1f889d-7930-4ef6-9f87-ef096d91ac47/",
 "nbf": 1403253608,
 "exp": 1403296808,
 "sub": "bdb0baf9-29ca-4a43-b9f8-d81ca2ae83bd",
 "appid": "<my app ID>",
 "oid": "bdb0baf9-29ca-4a43-b9f8-d81ca2ae83bd",
 "tid": "2d1f889d-7930-4ef6-9f87-ef096d91ac47",
 "idp": "https://sts.windows.net/2d1f889d-7930-4ef6-9f87-ef096d91ac47/"
}.
[signature] 

然后我使用这个令牌连接到EWS:

var service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
var credentials = new OAuthCredentials(token);
service.Credentials = credentials;
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "<smtp address of o365 mailbox>");
Folder inbox = Folder.Bind(service, WellKnownFolderName.Inbox);

文件夹中。绑定失败,出现401错误。

在EWS Trace中,我可以看到这就是原因:

The audience claim value is invalid <my resource ID>

资源ID为"app -ID- uri";从已注册的应用程序

我肯定我只遗漏了一个小细节…但是我找不到它:)
如有任何建议,不胜感激。

如果我使用https://outlook.office365.com/作为资源ID (aud),我得到这个错误消息:

ACS50001: Relying party with identifier 'https://outlook.office365.com/' was not found.

租户有Exchange订阅,并且对邮箱有完全访问权。

Office 365 / EWS使用OAuth进行身份验证:受众声明值无效

好的。对于服务类型的应用程序,您将希望使用可以模拟用户的服务帐户。有关详细信息,请参阅此MSDN主题。拥有该帐户后,您将希望通过OAuth作为该服务帐户进行身份验证,然后根据需要模拟您的用户。

对于本机应用程序,您不能使用应用程序秘密进行身份验证。所以你需要这样做:

AuthenticationResult result = authContext.AcquireToken("https://outlook.office365.com", clientId, new Uri(callbackUri), PromptBehavior.Auto);

其中clientId是您在Azure注册时的客户端ID, callbackUri是您在Azure中注册应用程序时指定的重定向URI。这将导致显示一个提示窗口,但是如果您保存令牌和刷新令牌并使用它们来刷新,则应该避免任何进一步的提示。您得到的令牌应该看起来像这样:

{
 "typ": "JWT",
 "alg": "RS256",
 "x5t": "kriMPdmBvx68skT8-mPAB3BseeA"
}.
{
 "aud": "https://outlook.office365.com",
 "iss": "https://sts.windows.net/9e4563d1-423e-493b-bdc5-9a98fe2e24d9/",
 "iat": 1403706230,
 "nbf": 1403706230,
 "exp": 1403710130,
 "ver": "1.0",
 "tid": "9e4563d1-423e-493b-bdc5-9a98fe2e24d9",
 "amr": [
  "pwd"
 ],
 "oid": "4a6e20e6-9711-4ca1-888b-34e63f65f897",
 "upn": "impersonationaccount@contoso.com",
 "unique_name": "impersonationaccount@contoso.com",
 "sub": "Pp3JW2dfYELMUBjGjUIZLarT4diOkkKZ1OJPVunzAYE",
 "puid": "100300008A9245F4",
 "family_name": "Account",
 "given_name": "Application",
 "appid": "<your app id>",
 "appidacr": "0",
 "scp": "user_impersonation",
 "acr": "1"
}.
[signature]

应用程序将验证为impersonationaccount@contoso.com用户,然后您可以冒充其他用户。我刚刚用一个小的测试控制台应用程序测试了我的Office 365测试帐户。

最后一个警告:EWS所需的OAuth权限范围不像其他权限范围那样可移植。我的意思是,与REST API应用程序不同,你可以使用开发者租户在Azure中注册它,然后其他Office 365组织可以同意你的应用程序,使用OAuth的EWS应用程序必须在使用它们的每个租户中单独注册。如果你是在为你自己的组织创建这个应用程序,也没什么大不了的。但是,如果你打算将这个应用程序授权给其他组织,你应该注意一些事情。

参数aud应为"https://outlook.office365.com"。尝试将其传递给AcquireToken。您也不需要设置ImpersonatedUserId。希望这对你有帮助!