MSAL UserTokenCache 未在 Android 上保留

MSAL UserTokenCache not persisted on Android

我曾尝试使用 Azure B2C 和 MSAL 对用户进行身份验证,但偶然发现了一些用户体验问题。

当我调试我的应用程序时,我通常不需要登录,因为我已经通过身份验证并且令牌仍然有效。但是,如果我从调试切换到发布然后测试应用程序,AquireTokenSilentAsync 方法似乎无法从 UserTokenCache 检索有效令牌。我的假设是每次关闭应用程序时都会清除 UserTokenCache。不知何故,这在调试模式下不会发生,我猜这是因为缓存在部署之间保持不变。

我通过这种方式获得了身份验证结果,但是尝试了不同的重载都没有成功。

AuthenticationResult ar = await App.PCApplication.AcquireTokenSilentAsync(App.Scopes, "", App.Authority, App.SignUpSignInpolicy, false);

因此,当我登录、关闭并重新进入应用程序时,我仍然需要重新登录。

我完全知道 MSAL 仍处于预览阶段,但我还没有发现与此行为相关的任何问题。这是一个已知问题吗?是否有可用的解决方法?

查看 MSAL 源代码,我可以清楚地看到 UserTokenCache 使用 Android SharePreferences 进行持久化,这在调试模式下工作得很好。所以,要么这是一个 bug/missing 实现,要么我没有看到明显的东西..

我几乎可以完全复制它。 运行 在 IDE 调试器下,它工作得很好,但如果它没有附加到调试器,或者 运行ning 作为发布版本,它会默默地无法存储令牌和其他所有东西在尝试坚持通常也失败后出现 运行。

我设法在 Android 上解决了同样的问题,方法是实现我自己的从 TokenCache 派生的缓存并查看它试图做什么。

我找到了一个桌面应用程序示例,如下所述:

https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-native-dotnet

然后查看了他们的 FileCache,因为它在他们的 GitHub 仓库中定义:

https://github.com/AzureADQuickStarts/B2C-NativeClient-DotNet/blob/complete/TaskClient/FileCache.cs

我复制了他们的 FileCache,并将其添加到 PublicClientApplication 初始化中:

ClientApplication = new PublicClientApplication(SharedConstants.AuthContext, SharedConstants.ClientId)
{
  RedirectUri = "urn:ietf:wg:oauth:2.0:oob",
  UserTokenCache = new FileCache(),
};

(默认情况下,大多数示例将 UserTokenCache 属性 留空,大概使用平台默认共享首选项)。

然后调整它在 reads/writes/accesses 期间做一些详细的日志记录只是为了看看它在做什么:

private void AfterAccessNotification(TokenCacheNotificationArgs args)
{
  // if the access operation resulted in a cache update
  try
  {
    this.Log().Debug("About to update token cache (if it's changed)...");
    if (this.HasStateChanged)
    {
      this.Log().Debug("State has changed, updating cache file...");
      lock (FileLock)
      {
        // reflect changes in the persistent store
        _file.WriteAllBytes(CacheFilePath, this.Serialize());
        // once the write operation took place, restore the HasStateChanged bit to false
        this.HasStateChanged = false;
      }
      this.Log().Debug("Token cache file updated");
    }
    this.Log().Debug("Finished updating token cache file");
  }
  catch (Exception ex)
  {
    this.Log().ErrorException($"Something went wrong during token AfterAccessNotification: {ex.Message}", ex);
  }
}

日志记录显示,在 Android 上,它抛出了一个与 DateTimeOffset 类型 属性 的序列化处理程序相关的异常MSAL 库。

一旦我将 AfterAccessNotification 包裹在一个带有处理程序的 try-catch 中以记录异常的发生,它就开始完美地工作了。

我现在一直坚持使用这个版本的 FileCache,因为它目前主要解决了我的问题,但这确实意味着 auth 令牌等现在没有安全存储。

我怀疑模拟器上的 iOS 10.x 也会出现同样的问题,但我还无法验证这一点。

我希望这对某人有所帮助。

编辑:正如@Henrik 在他的评论中提到的:编辑项目属性并告诉它 not 到 link System.Runtime.Serialization.dll on [=60] =] 然后永久解决问题。基于我(公认的)有限的测试,可以安全地再次使用 FileCache 切换到默认行为。