【发布时间】:2017-12-22 11:00:39
【问题描述】:
我正在编写一个应用程序以使用 EWS 托管 API 与 Exchange Online 通信,并使用 ADAL 库通过 OAuth 2.0 对我的应用程序进行身份验证。
访问令牌将在 60 分钟后过期。之后我需要刷新访问令牌。目前,我正在 StreamSubscriptionConnection OnNotificationEvent 处理程序以及我的 OnDisconnect 事件处理程序中执行此操作,以使用以下代码刷新 OAuth 访问令牌。
private void OnNotificationEventHandler(object sender, NotificationEventArgs args)
{
exchangeService.Credentials = new OAuthCredentials(GetOAuthAccessToken().Result);
// Do my work
}
我还在我的 OnDisconnect 事件处理程序中添加了相同的刷新访问令牌代码,因为 StreamSubscriptionConnection 最多只能保持打开 30 分钟。
private void OnDisconnectEventHandler(object sender, SubscriptionErrorEventArgs args)
{
exchangeService.Credentials = new OAuthCredentials(GetOAuthAccessToken().Result);
streamingSubscriptionConnection.Open();
}
这是我的访问令牌代码。
private async Task<string> GetOAuthAccessToken(PromptBehavior promptBehavior = PromptBehavior.Auto)
{
var authenticationContext = new AuthenticationContext(myAadTenant);
var authenticationResult = await authenticationContext.AcquireTokenAsync(exchangeOnlineServerName, myClientId, redirectUri, new PlatformParameters(promptBehavior));
return authenticationResult.AccessToken;
}
即使认为上述方法“有效”,我觉得这不是处理这种情况的最佳方法,因为我几乎需要确保在与 EWS 通信时刷新我的访问令牌。如果我添加了另一个事件处理程序并且我忘记在事件处理程序中添加令牌刷新逻辑,如果我的访问令牌过期并且我需要在事件处理程序中调用 EWS,我可能会在处理该事件时得到 401。
上面的代码被简化了,我可以在与 EWS 通信时使用 try catch,如果我得到 401,我会刷新我的访问令牌并重试,但这并不能解决我上面提到的不便。
我认为应该有一种更简单的方法来处理问题,但我没有找到正确的文档。这是我在开发时参考的材料。 https://blogs.msdn.microsoft.com/webdav_101/2015/05/11/best-practices-ews-authentication-and-access-issues/
【问题讨论】:
-
为什么不使用计时器线程每 n 分钟刷新一次令牌,并让它与所有经过身份验证的 Web 请求共享某种锁定,从而避免竞争条件?如果 EWS 延长每个请求的超时时间,您甚至可以在每个成功的 Web 请求时重置计时器。
-
我不认为有一个计时器线程每 n 分钟刷新一次令牌可以解决这个问题。令牌每 60 分钟过期一次,我的应用程序需要响应新邮件事件。因此,如果下一个计时器在 65 分钟标记处刷新令牌,但在 62 分钟标记处收到事件,那么我仍然会遇到问题。为了处理这个问题,我仍然需要在响应事件并调用 EWS 之前刷新令牌。我想知道是否可以将我的 EWS 实例设置为在需要时自动刷新令牌。
-
那么不要将计时器设置为每 65 分钟刷新一次,哈哈。如果刷新周期是 60 分钟,我会每 50 分钟进行一次。天哪。
-
那行不通,因为在您已经拥有的 OAuth 访问令牌过期之前,您不会获得新的 OAuth 访问令牌。因此,在 55 分钟标记上调用 AcquireTokenAsync() 不会刷新令牌。当然,除非有一种我不知道的强制更新的方法。
-
方法 #2 是简单地重新获取令牌以响应错误的请求。
标签: c# oauth-2.0 exchangewebservices adal ews-managed-api