我尝试使用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持久化,这在调试模式下完美运行。所以,这是一个错误/缺失的实现,或者我没有看到明显的东西..
答案 0 :(得分:4)
我能够几乎完全复制这个。在IDE调试器下运行,它可以很好地工作,但是如果它没有连接到调试器,或者作为发行版本运行,它将无声地存储令牌,并且在尝试持久性之后出现的所有其他内容通常也无法运行。 / p>
我设法通过实现自己从TokenCache
派生的缓存并查看它尝试执行的操作来解决Android上的同一问题。
我找到了桌面应用的示例,如下所述:
然后看看他们的GitHub回购中定义的FileCache
:
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上,它抛出了一个与MSAL库内部某处DateTimeOffset
- 类型属性的序列化处理程序无关的异常。
一旦我将AfterAccessNotification
包装在一个带有处理程序的try-catch中,以记录发生了异常,那么一切都开始完美。
我现在一直坚持使用这个版本的FileCache
,因为它目前主要解决了我的问题,但它确实意味着现在不能安全地存储身份验证令牌等。
我怀疑在模拟器上iOS 10.x上也出现了同样的问题,但我还没有能够验证这一点。
我希望这有助于某人。
编辑:正如@Henrik在评论中提到的:编辑项目属性并告诉它不链接Android上的System.Runtime.Serialization.dll
然后永久修复问题。基于我的(公认的)有限测试,可以安全地再次使用FileCache
转换为默认行为。