使用WithForceRefresh方法无法刷新令牌,求解决方案
问题解决:强制刷新令牌后仍出现401过期错误
问题重现
使用以下VB.NET代码尝试定期强制刷新Office 365 EWS的令牌:
Dim cca = ConfidentialClientApplicationBuilder.Create((appID)).WithClientSecret((clientSecret)).WithTenantId((tenantId)).Build() Dim ewsScopes = New String() {"https://outlook.office365.com/.default"} authResult = cca.AcquireTokenForClient(ewsScopes).WithForceRefresh(True).ExecuteAsync().GetAwaiter().GetResult
但65分钟后仍收到401错误,令牌已过期,要求必须通过WithForceRefresh方法续订令牌。
解决方案
1. 每次EWS请求前都执行强制刷新逻辑
客户端凭据流获取的令牌默认有效期约60分钟,65分钟必然过期。你需要确保每次发起EWS请求前,都调用这段带WithForceRefresh(True)的代码获取最新令牌,而非一次性获取后长期复用旧令牌。
2. 增加401自动重试机制
在捕获到EWS请求返回的401错误时,立即触发强制刷新获取新令牌,然后重新发起请求。示例逻辑如下:
Dim retryCount = 0 Dim maxRetries = 1 Do Try ' 每次请求前强制刷新获取最新令牌 Dim cca = ConfidentialClientApplicationBuilder.Create(appID).WithClientSecret(clientSecret).WithTenantId(tenantId).Build() Dim ewsScopes = New String() {"https://outlook.office365.com/.default"} Dim authResult = cca.AcquireTokenForClient(ewsScopes).WithForceRefresh(True).ExecuteAsync().GetAwaiter().GetResult() ' 使用新令牌初始化EWS客户端并发起请求 Dim ewsClient = New ExchangeService(ExchangeVersion.Exchange2013_SP1) ewsClient.Credentials = New OAuthCredentials(authResult.AccessToken) ewsClient.Url = New Uri("https://outlook.office365.com/EWS/Exchange.asmx") ' 执行具体EWS操作 ' ... Exit Do ' 请求成功,退出重试循环 Catch ex As WebException When ex.Response IsNot Nothing AndAlso DirectCast(ex.Response, HttpWebResponse).StatusCode = HttpStatusCode.Unauthorized retryCount += 1 If retryCount > maxRetries Then Throw ' 超过重试次数,抛出异常 End If ' 401时自动重试,重新执行强制刷新逻辑 End Try Loop While retryCount <= maxRetries
3. 验证MSAL版本兼容性
确保使用的是最新稳定版的Microsoft.Identity.Client包,旧版本可能存在强制刷新逻辑的bug,导致刷新后仍返回旧令牌。
关键说明
WithForceRefresh(True)的作用是绕过MSAL的令牌缓存,直接向Azure AD请求新令牌。但如果你的代码没有在需要的时候(每次请求前或401触发时)调用该逻辑,旧令牌过期后自然会触发401错误。核心是要将令牌获取逻辑与EWS请求绑定,确保每次请求都使用最新的有效令牌。
内容的提问来源于stack exchange,提问作者John in 't Veld
相关产品推荐
相关产品推荐

