AAD Graph API在调用AcquireTokenAsync后返回404,但在调用AcquireTokenSilentAsync后不返回404

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AAD Graph API在调用AcquireTokenAsync后返回404,但在调用AcquireTokenSilentAsync后不返回404相关的知识,希望对你有一定的参考价值。

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

请参阅以下代码段:enter image description here

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

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

1)你能推荐一些好的工具来分析HTTP请求(所以我可以比较差异并找出问题)。 Visual Studio调试器很有用,但我看不到整个图片,这会混淆一个可能的问题。

2)你能帮我确定为什么一个成功而一个失败?这两个令牌似乎都是成功获得的,所以我不确定问题是什么。

答案

所以我已经弄明白这里的根本原因是什么。

在我们的身份验证方案中,我们在生态系统中使用azure 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();
        }

现在,因为我们在控制器之外使用这个代码,并且我们调用await,HttpContext将为null。在HttpContext中发生了一些严重的伏都教,但我离题了。我们可以使用这个小解决方法来挂起上下文:

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

编辑:在将应用程序部署到azure app-service时遇到了另一个问题。您希望确保在Azure上的“身份验证”面板中切换Azure AD身份验证。在切换之前,我们遇到了一些无限的登录循环问题。

编辑:所以,在这种情况下强制注销真的不适合我。但是,我遇到了这个问题:

Azure Active Directory Graph API - access token for signed in user

我们可以做的是按照答案,并调用AcquireTokenByAuthorizationCodeAsync(...),并确保使用4参数方法重载,其中最后一个参数是“https://graph.windows.net/

现在,只要我们将授权代码存储在某处(在我的情况下存储在DB表中)。在AcquireTokenSilentAsync(...)失败的情况下,我们应该能够获得给定用户的授权代码,并获得新的GraphAPI令牌。

现在,您的statefull tokencache可以通过无状态数据库调用进行备份!

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

                }
            }

以上是关于AAD Graph API在调用AcquireTokenAsync后返回404,但在调用AcquireTokenSilentAsync后不返回404的主要内容,如果未能解决你的问题,请参考以下文章

Azure Developer使用Microsoft Graph API 批量创建用户,先后遇见的三个错误及解决办法

使用 react-aad-msal 缺少范围从 react SPA 调用 web api

Microsoft Graph 和自定义 API 的访问令牌

powershell 使用PowerShell对AAD进行身份验证然后调用Web API

使用 Graph API 查询 SharePoint 列表项并展开用户字段

无法根据访问令牌对用户进行身份验证 - MS Graph API C#