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

时间:2014-06-20 09:29:47

标签: c# oauth-2.0 ms-office exchangewebservices office365

我还在努力解决这个问题。 有关详细信息,请参阅我的previous question

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

我已在Azure AD中注册了一个应用程序 我从那里使用了ClientID 我生成了一个App Secret / Key
我已将“具有对用户邮箱的完全访问权限(预览)”权限委派给应用程序。

我正在使用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);

Folder.Bind失败,出现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订阅,并且可以完全访问邮箱。

2 个答案:

答案 0 :(得分:1)

好的,好的。使用服务类型的应用,您可能希望使用可以冒充用户的服务帐户。有关详细信息,请参阅this MSDN topic。拥有该帐户后,您需要通过OAuth作为该服务帐户进行身份验证,然后根据需要模拟您的用户。

使用原生应用程序you cannot use the app secret to authenticate。因此,您需要执行以下操作:

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应用程序必须在每个应用程序中单独注册使用它们的租户。如果您为自己的组织创建此应用程序,则不是那么大的交易。但是,如果您计划将此应用程序许可给其他组织,那么您应该注意这一点。

答案 1 :(得分:0)

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