2

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

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

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

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

所以,当我登录时,关闭并重新进入应用程序,我仍然需要再次登录。

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

查看 MSAL 源代码,我可以清楚地看到 UserTokenCache 正在使用 Android SharePreferences 进行持久性,这在调试模式下完美运行。所以,要么这是一个错误/缺失的实现,要么我没有看到明显的东西..

4

1 回答 1

4

我几乎可以完全复制这个。在 IDE 调试器下运行,它可以完美运行,但是如果它没有连接到调试器,或者作为发布版本运行,它会默默地无法存储令牌,并且在尝试持久性之后出现的所有其他内容通常也无法运行。

我设法通过实现我自己的缓存来解决 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属性留空,以可能使用平台默认共享首选项)。

然后对其进行调整以在读/写/访问期间进行一些详细的日志记录,以查看它在做什么:

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

DateTimeOffset日志记录显示,在 Android 上,它抛出了一个异常,与 MSAL 库深处某处的 -type 属性没有序列化处理程序有关。

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

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

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

我希望这可以帮助别人。

编辑:正如@Henrik 在他的评论中提到的那样:编辑项目属性并告诉它不要在 Android上链接System.Runtime.Serialization.dll然后永久修复问题。根据我(诚然)有限的测试,然后可以安全地FileCache再次从使用默认行为切换到默认行为。

于 2016-12-07T04:05:41.337 回答