我几乎可以完全复制这个。在 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
再次从使用默认行为切换到默认行为。