首页 > 解决方案 > IConfidentialClientApplication GetAccountsAsync 不返回任何内容

问题描述

我正在尝试使 Azure AD B2C 演示与我的 Azure AD 一起工作。这有两个项目 - TaskService 和 TaskWebApp。我得到了 Web App 部分的工作。它引导我到正确的登录页面。我使用的是 b2clogin.com 而不是 login.microsoftonline.com。如果我转到网络应用程序中的索赔页面,一切似乎都正常。但是,当我尝试使用 TaskService(待办事项列表)时,它在 TaskController 中失败了。

首先它进入 OnAuthorizationCodeReceived,并且令牌和声明看起来正确。AcquireTokenByAuthorizationCode 返回一个令牌,并且注释说它应该被缓存。然后它进入 TaskController 函数 (Index),并创建另一个 ConfidentialClientApplication。然后它调用 GetAccountsAsync 并返回一个空列表。没有错误,我不知道为什么。这会导致下一行失败,并显示合理的错误消息:“没有向 AcquireTokenSilent 调用传递帐户或登录提示。” 因为它传递一个空列表作为第二个参数。

这会导致浏览器在登录页面和 Web 应用程序之间循环多次,直到它决定停止。

// Retrieve the token with the specified scopes
var scope = new string[] { Globals.ReadTasksScope };

IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
var accounts = await cca.GetAccountsAsync(); //this returns empty
AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync(); //this throws exception

当我确实有当前的 ClaimsPrincipal 时,我不确定是什么导致我没有帐户。
编辑:我确实注意到在 OnAuthorizationCodeReceived 中,我的 AuthenticationResult 几乎填写了所有内容,但没有填写 Account.Username。那有关系吗?如果有,为什么不填写?

标签: azureazure-ad-b2c

解决方案


假设您指的是这些教程:

  1. Active Directory B2C 教程 Web 应用程序
  2. Active Directory B2C 教程 Web Api

以及相关的GitHub 项目(master 分支,提交 bf3bcce)

我有同样的问题。TaskWebApp 工作正常,但访问依赖于 TaskWebApi 的任务视图会导致身份验证循环。这是我发现的,以及如何使它工作。


TL;博士

在 TaskWebApp 项目的 Web.config 中,在 configuration/appSettings 中添加以下行:

<add key="ida:TenantId" value="[your AAD B2C Tenant GUID here]" />

保存、构建和运行。您应该通过此身份验证循环。


细节

在 Visual Studio 中,我在 TasksController.cs 第 29 行设置了一个断点:

var accounts = await cca.GetAccountsAsync();

每当我导航到 /Tasks 时,我都可以验证是否命中了此 LOC。进入之后调用的每个 LOC,我查看了调用堆栈的每个部分以查看返回 null 的位置。

  • GetAccountsAsync()
  • {外部代码}
  • TaskWebApp.Utils.MSALPerUserMemoryTokenCache .UserTokenCacheBeforeAccessNotification(TokenClassNotification) 非空
  • .LoadUserTokenCacheFromMemory() NOT NULL
  • .GetMsalAccountID() 非空
  • TaskWebApp.Utils.ClaimPrincipalExtension.GetB2CMsalAccountId(System.Security.Claims.ClaimsPrincipal) NULL!

具体来说,TaskWebApp\Utils\ClaimsPrincipalExtension.cs 中的第 40 行返回 null。

string tenantId = Globals.TenantId;

它从 TaskWebApp Web.config 中定义的 Globals 类分配租户 ID,但它使用键“ida:TenantId”中未提供的值。


推荐阅读