【问题标题】:AAD Graph API returns 404 after call to AcquireTokenAsync, but not after call to AcquireTokenSilentAsyncAAD Graph API 在调用 AcquireTokenAsync 后返回 404,但在调用 AcquireTokenSilentAsync 后不返回
【发布时间】:2018-11-24 06:16:05
【问题描述】:

所以我有一个调用图形 API 的应用程序。

请参阅以下 sn-p:

调用try(AquireTokenSilent)时,Web Request成功完成没问题。

但是,当使用从 AcquireTokenAsync 获得的令牌发出相同的 Web 请求时,我收到 404 错误并引发异常。

1) 能否推荐一些分析HTTP请求的好工具(这样我可以比较差异并找出问题)。 Visual Studio 调试器很有帮助,但我看不到全貌,这混淆了这里可能存在的问题。

2) 你能帮我确定为什么一个是成功的,一个是失败的吗?两个token好像都获取成功了,不知道是什么问题。

【问题讨论】:

  • Microsoft 示例表明您应该在 acquiretokensilent 方法引发异常后调用质询进行身份验证。但是,因为调用了 await,所以 HTTPContext 为空,无论是设计还是错误。因此,我别无选择,只能尝试手动获取令牌。我认为我错误地提取了令牌,这就是 Web 请求失败的原因。那么如何正确获取该死的令牌呢?
  • 我建议您可以使用fiddler 来捕获http 请求。然后你就可以得到这方面的详细信息。
  • 我肯定会在这里使用 fiddler,但我认为这里的根本问题是这是一个没有收到授权码的场景,因为登录令牌来自另一个会话。我想在这种情况下我需要强制退出。

标签: asp.net oauth azure-active-directory azure-ad-graph-api


【解决方案1】:

所以我已经弄清楚了这里的根本原因。

在我们的身份验证方案中,我们在生态系统中有多个使用 azure AD SSO 的产品。由于“OnAuthorizationCodeReceived”仅在登录时调用,而不是在已保存有效登录 cookie 时调用,因此不会使用授权码填充令牌缓存。所以在这种情况下,这个场景的微软代码示例是完全错误的。发出身份验证质询不会导致调用“OnAuthorizationCodeReceived”,因为您已经持有有效的登录令牌。

所以,虽然它有点 litte 丑陋,但修复起来非常简单。强制注销,以便可以填充令牌缓存。

          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();
        }

现在,因为我们在控制器之外使用此代码,并且我们调用了 await,所以 HttpContext 将为空。 HttpContext 中发生了一些严重的巫术,但我离题了。我们可以使用这个小变通方法来保持上下文:

        var context = HttpContext.Current;
        var sessionState = context.Session;

编辑:将应用程序部署到天蓝色应用服务时遇到了另一个问题。您要确保在 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;
                    }

                }
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多