我们正在使用Microsoft Graph API开发ASP.NET MVC项目。它主要基于https://github.com/microsoftgraph/aspnet-snippets-sample的示例代码。该应用程序最初工作正常 - 我们可以使用我们的租户帐户登录并从图表中获取数据。但是,如果我们从Visual Studio开始一个新的会话,或者我们只是等待一段时间,AcquireTokenSilentAsync
抛出
无法以静默方式获取令牌
如果网络浏览器缓存被清除,它会再次运行,但过了一会儿就会返回错误。 我们已经尝试将权限更改为普通,组织和租户,但错误仍然存在。
我们获取访问令牌的方法如下:
// Gets an access token and its expiration date. First tries to get the token from the token cache.
public async Task<string> GetUserAccessTokenAsync()
{
// Initialize the cache.
HttpContextBase context = HttpContext.Current.GetOwinContext().Environment["System.Web.HttpContextBase"] as HttpContextBase;
tokenCache = new SessionTokenCache(
ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value,
context);
IEnumerable<TokenCacheItem> cachedItems = tokenCache.ReadItems(appId); // see what's in the cache
if (cachedItems.Count() > 0)
return cachedItems.First().Token;
if (!redirectUri.EndsWith("/")) redirectUri = redirectUri + "/";
string[] segments = context.Request.Path.Split(new char[] { '/' });
ConfidentialClientApplication cca = new ConfidentialClientApplication(
appId,
redirectUri + segments[1],
new ClientCredential(appSecret),
tokenCache);
string allScopes = nonAdminScopes;
string[] scopes = allScopes.Split(new char[] { ' ' });
try
{
AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes);
return result.Token;
}
// Unable to retrieve the access token silently.
catch (MsalSilentTokenAcquisitionException)
{
HttpContext.Current.Request.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties() { RedirectUri = redirectUri + segments[1] },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
throw new ServiceException(
new Error
{
Code = GraphErrorCode.AuthenticationFailure.ToString(),
Message = Resource.Error_AuthChallengeNeeded,
});
}
}
为什么不能无声地获得令牌的任何想法?
答案 0 :(得分:1)
你如何处理抛出的异常?在您提供的示例中,他们使用try / catch处理错误,如果引发异常并且错误消息匹配,则返回空结果。此请求将被OpenId中间件拦截(因为..GetOwinContext()。Authentication.Challenge()将响应代码设置为401,将身份验证类型设置为OpenIdConnectAuthenticationDefaults.AuthenticationType)。
try
{
// Initialize the GraphServiceClient.
GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient();
// Get the files and folders in the current user's drive.
results.Items = await filesService.GetMyFilesAndFolders(graphClient);
}
catch (ServiceException se)
{
if (se.Error.Message == Resource.Error_AuthChallengeNeeded) return new EmptyResult();
return RedirectToAction("Index", "Error", new { message = string.Format(Resource.Error_Message, Request.RawUrl, se.Error.Code, se.Error.Message) });
}