如何在ADAL.NET中缓存Token并在过期时自动静默续订?
问题分析与解决方案
你的代码每次都生成新Token,核心问题有两个:
- TokenCache无法复用:每次调用
GetTokenAsync都新建TokenCache实例,之前的缓存数据根本存不住,自然每次都得重新请求Token。 - 调用顺序搞反了:应该先尝试从缓存静默获取Token,失败后再去请求新Token,而不是反过来。
另外你的异常处理太笼统,既不记录错误也不抛出,出问题根本没法排查。
修正后的代码
// 把TokenCache改成类级别的静态变量,确保整个应用复用同一个缓存 private static readonly TokenCache _tokenCache = new TokenCache(); private static AuthenticationContext _authContext; static YourClassName() // 替换成你的控制台应用类名 { _authContext = new AuthenticationContext("https://login.windows.net/{tenant_id}", _tokenCache); } private async Task<string> GetTokenAsync() { var credential = new ClientCredential("ClientID", "ClientSecret"); const string resource = "Resource"; try { // 先尝试从缓存静默获取Token var result = await _authContext.AcquireTokenSilentAsync(resource, credential, UserIdentifier.AnyUser); return result.AccessToken; } catch (AdalSilentTokenAcquisitionException) { // 缓存里没有有效Token,请求新的 try { var result = await _authContext.AcquireTokenAsync(resource, credential); return result.AccessToken; } catch (AdalException ex) { // 可添加日志记录,比如Console.WriteLine($"获取新Token失败: {ex.Message}"); throw; // 按需处理,不要直接吞掉异常 } } catch (AdalException ex) { // 记录其他ADAL异常 // Console.WriteLine($"ADAL异常: {ex.Message}"); throw; } catch (Exception ex) { // 记录通用异常 // Console.WriteLine($"未知异常: {ex.Message}"); throw; } }
关键说明
- 静态TokenCache:将
TokenCache和AuthenticationContext设为类级别的静态成员,控制台应用运行期间,缓存会一直保留,不会每次调用方法都重置。 - 调用顺序调整:优先调用
AcquireTokenSilentAsync,只有缓存中没有未过期Token时,才调用AcquireTokenAsync获取新Token,实现缓存复用和自动续订。 - 异常处理优化:去掉空catch块,添加错误记录(可根据实际用日志框架),必要时抛出异常,避免问题被隐藏。
内容的提问来源于stack exchange,提问作者user584018
相关产品推荐
相关产品推荐

