我正在编写一个应用程序,以便使用EWS Managed API与Exchange Online进行通信,并通过OAuth 2.0利用ADAL库对我的应用程序进行身份验证。
访问令牌将在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/
3条答案
按热度按时间kx7yvsdv1#
另一种方法是通过EWS托管API与Exchange联机通信时,需要提供
exchangeService
对象。并且需要捕获每个请求的401异常,在捕获此异常后,需要重新设置exchangeService
对象的Credentials
属性或重新创建此对象。wooyq4lh2#
我同意应该有一个更好的方法来处理令牌刷新。如果EWS API本身可以管理令牌刷新,那就太好了,但作为一个变通办法,我所做的是...。
将对EWS服务的引用放入公共/内部属性中,该属性可a)示例化尚未示例化的服务,b)确保身份验证令牌仍然有效(如果无效,则执行令牌刷新)。然后,我们需要确保此属性是EWS服务的单一访问点。
大体上看起来
我不打算详细介绍
CreateExchangeService
,但ValidateAuthentication
是对EWS的基本调用,如果未经身份验证,它将引发异常RefreshOAuthCredentials
将简单地刷新令牌。类似地,我在StreamingSubscription上也有一个OnDisconnect
事件处理程序,它将尝试重新打开连接(如果重新打开失败,则重新进行身份验证)。为了简洁起见,这里没有显示这两个事件处理程序。不过,主要的一点是,我们现在有了对EWS服务的单个引用,该服务在每次调用之前执行身份验证检查和重新身份验证(如果需要)。
毫无疑问,这会增加流量/延迟,如果有更好的方法,这是可以避免的。如果有人有更好的方法-我洗耳恭听!
holgip5t3#
我不得不在netcore应用程序中处理同样的问题(使用官方EWS托管API客户端的fork,它不以任何方式触及这方面)。在完整请求之前主动做
.Bind
增加了流量/延迟,如PaulG的回答中所提到的。并且容易受到定时故障的影响-令牌可能在Bind本身运行时超时,下一个请求无论如何都将失败。希望我的单点“401重试”解决方案能对大家有所帮助。