所以我有一个调用图形API的应用程序。
调用try(AquireTokenSilent)时,Web请求成功完成,没有问题。
但是,当使用从AcquireTokenAsync获得的令牌进行相同的Web请求时,出现了404错误和抛出异常。
1)您能否推荐一些好的工具来分析HTTP请求(以便我可以比较差异并确定问题)。 Visual Studio调试器很有用,但是我看不到整个图片,这使这里的问题变得难以理解。
2)您能帮我确定为什么一个成功和一个失败的原因吗?这两个令牌似乎都已成功获取,所以我不确定问题出在哪里。
答案 0 :(得分:0)
所以我已经弄清楚了根本原因是什么。
在我们的身份验证方案中,我们有多种产品在生态系统中使用天蓝色的AD SSO。由于“ OnAuthorizationCodeReceived”仅在登录时调用,而在已经保存有效登录cookie时不调用,因此不会使用授权码填充令牌缓存。因此,在这种情况下,此方案的Microsoft代码示例完全错误。发出身份验证质询不会导致调用“ OnAuthorizationCodeReceived”,因为您已经持有有效的登录令牌。
因此,尽管这很麻烦,但修复仍然非常简单。强制注销,以便可以填充令牌缓存。
catch (AdalSilentTokenAcquisitionException e)
{
//in this case, it's possible there's no authorization code because the login cookie is from another session in
//the ecosystem. So in this scenario, force a logout so we can get a token into the tokencache
context.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType,
CookieAuthenticationDefaults.AuthenticationType);
sessionState.Abandon();
}
现在,因为我们正在Controllers外部使用此代码,并且我们调用await,所以HttpContext将为null。 HttpContext中发生了一些严重的伏都教,但我离题了。我们可以使用这种小变通方法来挂起上下文:
var context = HttpContext.Current;
var sessionState = context.Session;
编辑:在将应用程序部署到azure应用程序服务时遇到了另一个问题。您要确保在Azure的“身份验证”面板中启用“ Azure AD身份验证”。在切换之前,我们遇到了一些无限的登录循环问题。
编辑: 因此,在这种情况下强制注销确实对我不利。但是,我遇到了这个问题:
Azure Active Directory Graph API - access token for signed in user
我们可以按照答案进行操作,并调用AcquireTokenByAuthorizationCodeAsync(...),并确保使用4参数方法重载,其中最后一个参数是“ https://graph.windows.net/”
现在,只要我们将授权代码存储在某个位置(在我的情况下存储在数据库表中)。如果AcquireTokenSilentAsync(...)失败,我们应该能够获得给定用户的授权代码,并获得新的GraphAPI令牌。
现在可以通过无状态数据库调用来备份您的全状态令牌缓存!
catch (AdalSilentTokenAcquisitionException e)
{
//in this case, the stateful cache is empty, so lets get the codeId from the DB
PersistentTokenCache pt = db.PersistentTokenCaches.Find(userObjectId);
if (pt != null && pt.token != null)
{
try
{
result = await ath.AcquireTokenByAuthorizationCodeAsync(pt.token,
new Uri(Startup.hostUri),
cc,
"https://graph.windows.net");
}
catch (AdalException ex)
{
Debug.WriteLine(ex.StackTrace);
//both authentication types have failed
pt.token = null;
await db.SaveChangesAsync();
context.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType,
CookieAuthenticationDefaults.AuthenticationType);
sessionState.Abandon();
return -1;
}
}
}