我有以下功能可以使用 graph api 从 active directory 调用用户。 这个函数在文本框的每个 keyup 上被击中。但是我收到以下错误
Code: TokenNotFound Message: User not found in token cache. Maybe the server was restarted.
在线
var user = await graphClient.Users.Request().GetAsync();
完整功能如下:
public async Task<string> GetUsersJSONAsync(string textValue)
{
// email = email ?? User.Identity.Name ?? User.FindFirst("preferred_username").Value;
var identifier = User.FindFirst(Startup.ObjectIdentifierType)?.Value;
var graphClient = _graphSdkHelper.GetAuthenticatedClient(identifier);
string usersJSON = await GraphService.GetAllUserJson(graphClient, HttpContext, textValue);
return usersJSON;
}
public static async Task<string> GetAllUserJson(GraphServiceClient graphClient, HttpContext httpContext, string textValue)
{
// if (email == null) return JsonConvert.SerializeObject(new { Message = "Email address cannot be null." }, Formatting.Indented);
try
{
// Load user profile.
var user = await graphClient.Users.Request().GetAsync();
return JsonConvert.SerializeObject(user.Where(u => !string.IsNullOrEmpty(u.Surname) && ( u.Surname.ToLower().StartsWith(textValue) || u.Surname.ToUpper().StartsWith(textValue.ToUpper()))), Formatting.Indented);
}
catch (ServiceException e)
{
switch (e.Error.Code)
{
case "Request_ResourceNotFound":
case "ResourceNotFound":
case "ErrorItemNotFound":
//case "itemNotFound":
// return JsonConvert.SerializeObject(new { Message = $"User '{email}' was not found." }, Formatting.Indented);
//case "ErrorInvalidUser":
// return JsonConvert.SerializeObject(new { Message = $"The requested user '{email}' is invalid." }, Formatting.Indented);
case "AuthenticationFailure":
return JsonConvert.SerializeObject(new { e.Error.Message }, Formatting.Indented);
case "TokenNotFound":
await httpContext.ChallengeAsync();
return JsonConvert.SerializeObject(new { e.Error.Message }, Formatting.Indented);
default:
return JsonConvert.SerializeObject(new { Message = "An unknown error has occured." }, Formatting.Indented);
}
}
}
// Gets an access token. First tries to get the access token from the token cache.
// Using password (secret) to authenticate. Production apps should use a certificate.
public async Task<string> GetUserAccessTokenAsync(string userId)
{
_userTokenCache = new SessionTokenCache(userId, _memoryCache).GetCacheInstance();
var cca = new ConfidentialClientApplication(
_appId,
_redirectUri,
_credential,
_userTokenCache,
null);
if (!cca.Users.Any()) throw new ServiceException(new Error
{
Code = "TokenNotFound",
Message = "User not found in token cache. Maybe the server was restarted."
});
try
{
var result = await cca.AcquireTokenSilentAsync(_scopes, cca.Users.First());
return result.AccessToken;
}
// Unable to retrieve the access token silently.
catch (Exception)
{
throw new ServiceException(new Error
{
Code = GraphErrorCode.AuthenticationFailure.ToString(),
Message = "Caller needs to authenticate. Unable to retrieve the access token silently."
});
}
}
你能帮我看看哪里出了问题吗?
最佳答案
我知道这已经 4 个月大了 - 这对您来说仍然是个问题吗?
正如之前的受访者所指出的,您看到的错误是在您的代码中用于处理空用户集合的 catch block 中引发的。
万一你卡在这上面,或者其他人来到这里 - 如果你使用了 this sample (或在任何方面使用 ConfidentialClientApplication
)并抛出此异常,这是因为您的 _userTokenCache 没有用户*。当然,不是因为你的AD没有用户,否则就无法认证。很可能是因为浏览器中的旧 cookie 作为访问 token 传递给了 authProvider。您可以使用 Fiddler(或只检查您的本地主机浏览器 cookie)来找到它(应该称为 AspNetCore.Cookies,但您可能想要清除所有这些)。
如果您将 token 缓存存储在 session 中(如示例所示),请记住每次启动和停止应用程序时,您的工作内存将被丢弃,因此浏览器提供的 token 将不再匹配新的一个您的应用程序将在再次启动时检索(除非您再次清除了浏览器 cookie)。
MSAL 不再使用或支持*cca.Users
- 您必须使用 cca.GetAccountsAsync()
。如果您有一个已部署的应用程序使用已弃用的 IUser
实现运行,则必须更改它。否则,在开发过程中,您的编译器会提示并且不允许您构建,因此您已经知道这一点。
关于c# - 代码 : TokenNotFound Message: User not found in token cache. 可能服务器已重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50171836/