我正在使用 PublicClientApplicationBuilder 将 Microsoft Azure AD B2C 添加到桌面应用程序。我们正在扩展已用于网站的现有身份体验框架自定义策略,以便用户也可以使用桌面应用程序。
该流程有效,允许用户使用 AcquireTokenInteractive 登录 B2C。
我的部分要求是允许静默令牌刷新,并允许用户即使在互联网不可用时也可以使用桌面应用程序,因为用户需要将笔记本电脑带到现场。
我已经设置了令牌缓存(https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/wiki/Cross-platform-Token-Cache),但该应用程序仅适用于Windows,所以我只提供所需的参数
// cache file name is a random .txt file name
// CacheDir is set to a test directory within %ProgramData%
var storageProperties = new StorageCreationPropertiesBuilder(_cacheFileName, CacheDir).Build();
我遵循了此指南(https://learn.microsoft.com/en-us/entra/msal/dotnet/acquiring-tokens/acquire-token-silently)并尝试使用 AcquireTokenSilent 来检查是否有良好的有效令牌和/或刷新令牌。我按照此指南(https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-tokens?pivots=b2c-custom-policy#configure-token-lifetime)来设置具有默认令牌生命周期值的自定义策略。
首次交互式登录后,令牌会被缓存,但缓存令牌的 IdToken 字符串比交互式登录检索到的字符串短数百个字符。当使用 JWT Decode 解码令牌时,预期的自定义声明丢失。
我们的 B2C 流程在返回到调用应用程序/网站之前,通过定义的“extension_”声明丰富了我们的用户令牌。丰富在自定义策略中定义为 API 调用。
我不明白为什么缓存的令牌不包含我们的任何自定义声明。自定义声明在交互过程中顺利完成。
我为 AcquireTokenInteractive 和 AcquireTokenSilent 调用完全相同的范围:
public readonly string[] ScopeList = { $"openid", "offline_access" };
按照 Microsoft 和 git 示例建立 MSAL 令牌缓存,并使用 PublicClientApplicationBuilder 的 AcquireTokenSilent 方法尝试刷新用户令牌并允许用户在脱机时访问桌面应用程序。
AcquireTokenSilent 中的令牌缺少我们的 B2C 政策提供的所有丰富声明。
我找到了答案。原来是B2C定制政策的问题。 RedeemRefreshToken 用户旅程指向基本文件中的默认值。我在扩展文件中添加了一个新的用户旅程,并确保它包含我的 API 调用编排步骤。