我能够复制这几乎完全。在IDE调试器下运行,它可以很好地工作,但如果它没有连接到调试器,或者作为发布版本运行,它将默默无法存储该令牌,并且尝试持久性后的所有其他操作通常也无法运行。
我设法通过实现我自己的缓存来源于TokenCache
并查看它试图做什么来解决Android上的这个相同问题。
我所在的例子为一个桌面应用程序,如下所述:
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);
}
}
的记录显示,在Android上,它被扔涉及有异常不是一个DateTimeOffset
类型属性的序列化处理程序,它位于MSAL库的深处。
一旦我将AfterAccessNotification
封装在try-catch中并使用处理程序记录发生了异常,它就完全开始工作。
我一直坚持使用这个版本的FileCache
现在,因为它大多解决了我目前的问题,但它确实意味着认证令牌等现在不能安全存储。
我怀疑同样的问题发生在模拟器上的iOS 10.x上,但我还没有能够验证这一点。
我希望这可以帮助别人。
编辑:作为@Henrik在他的评论中提到:编辑项目属性,并告诉它不到Android上System.Runtime.Serialization.dll
链接,然后永久解决该问题。根据我的(公认的)有限的测试,可以安全地从使用FileCache
再次转换为默认行为。
我已经做了一篇关于我在这里弄清楚这个问题的博客文章:http://blog.wislon.io/posts/2016/12/05/msal-token-not-stored-on- android - 稍微不太详细的版本作为下面的潜在答案提供。 – wislon