调用Graph API查询AD用户时遇TokenNotFound错误求助
排查并解决Graph API调用的TokenNotFound问题
首先,咱们来拆解这个TokenNotFound错误的核心原因:这个报错说明你的应用在尝试调用Graph API时,找不到当前用户的访问令牌缓存——要么是服务器重启导致内存缓存被清空,要么是高频触发的请求里没有正确传递/保留用户身份对应的令牌。结合你是在keyup事件触发请求的场景,下面是具体的排查和解决步骤:
1. 先解决令牌缓存丢失的根本问题
默认情况下,很多Graph SDK的令牌缓存是内存级别的,服务器重启后所有缓存的令牌都会丢失。如果你的应用部署在会重启的环境(比如云服务器、容器),必须换成持久化的缓存方案:
- 如果你用的是MSAL.NET(Microsoft身份认证库),可以配置分布式缓存(比如Redis、SQL Server)来存储令牌,这样服务器重启后缓存不会丢失。
- 简单配置示例:
// 假设你已经注入了IDistributedCache实例 var tokenCache = new DistributedTokenCache(_distributedCache, "user-token-cache"); // 将该缓存绑定到MSAL的用户令牌缓存 _msalClient.UserTokenCache.SetCache(tokenCache);
2. 确保每次请求都正确获取/刷新令牌
你的GetUsersJSONAsync函数直接调用Graph API,但没有处理令牌缺失的情况。应该在调用前优先尝试获取令牌,缓存里没有就重新从身份提供者那里获取:
public async Task<string> GetUsersJSONAsync(string textValue) { try { // 先获取用户的Graph API访问令牌,这里假设你用TokenAcquisition服务 var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { "User.Read.All" }); // 用令牌初始化Graph Client的认证逻辑 _graphClient.AuthenticationProvider = new DelegateAuthenticationProvider(async (request) => { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); }); var users = await _graphClient.Users.Request().GetAsync(); return JsonSerializer.Serialize(users); } catch (MsalUiRequiredException ex) { // 触发用户重新登录的逻辑(比如返回前端重定向信号) throw new InvalidOperationException("需要用户重新登录以获取令牌", ex); } }
3. 优化keyup事件的请求频率
keyup会触发极高频率的请求(用户每敲一个键就发一次),这不仅会浪费Graph API配额,还可能导致令牌缓存的并发竞争问题。建议:
- 给前端加**防抖(debounce)**处理,比如用户停止输入500ms后再发送请求,大幅减少请求次数。
- 后端对相同的查询参数做本地缓存,避免重复调用Graph API。
4. 验证请求上下文的用户身份
确保每次keyup触发的请求里,用户身份是正确传递的:比如前端请求有没有带上身份Cookie,后端有没有正确解析用户的oid或preferred_username。如果请求是匿名的,或者身份解析失败,令牌缓存自然找不到对应的用户条目。
5. 检查令牌缓存的键值逻辑
如果是自定义的令牌缓存,确认缓存的键是基于用户唯一标识(比如oid,而不是不稳定的用户名)来存储的,确保每个用户的令牌是独立存储和读取的,不会出现混淆。
内容的提问来源于stack exchange,提问作者SmartestVEGA
相关产品推荐
相关产品推荐

