MSAL.NET中的令牌缓存序列化不起作用
c#
我在尝试序列化令牌缓存时遇到了一些问题,通过 MSAL 进行身份验证返回。我将不胜感激,因为我真的不明白我做错了什么。这是我们的情况/问题:
我们目前正在使用 ADAL 来允许用户从我们的桌面应用程序对其 SharePoint Online 帐户进行身份验证,但希望切换到 MSAL。
我们已经实现了两种可能的身份验证流程。一个 publicClientApplication,允许用户使用其当前活动的 Microsoft 凭据和 ConfidentialClientApplication 进行身份验证,允许使用证书进行身份验证,如您在以下代码的 catch 块中所见:
try
{
Debugger.Launch();
if (certificate != null)
{
IConfidentialClientApplication m_authContext = ConfidentialClientApplicationBuilder.Create(pClientID)
.WithTenantId(m_tenant).WithCertificate(certificate).WithRedirectUri(pClientRedirectURI).Build();
var accounts = await m_authContext.GetAccountsAsync();
authResult = await m_authContext.AcquireTokenSilent(m_scope, accounts.FirstOrDefault()).ExecuteAsync();
}
else
{
IPublicClientApplication m_authContext = PublicClientApplicationBuilder.Create(pClientID).WithTenantId(m_tenant).WithRedirectUri(pClientRedirectURI).Build();
var accounts = await m_authContext.GetAccountsAsync();
authResult = await m_authContext.AcquireTokenSilent(m_scope, accounts.FirstOrDefault()).ExecuteAsync();
}
}
catch
{
if (certificate != null)
{
IConfidentialClientApplication m_authContext = ConfidentialClientApplicationBuilder.Create(pClientID)
.WithTenantId(m_tenant).WithCertificate(certificate).WithRedirectUri(pClientRedirectURI).Build();
TokenCacheHelper.EnableSerialization(m_authContext.AppTokenCache);
authResult = await m_authContext.AcquireTokenForClient(m_scope).WithForceRefresh(true).ExecuteAsync();
}
else
{
IPublicClientApplication m_authContext = PublicClientApplicationBuilder.Create(pClientID)
.WithTenantId(m_tenant).WithRedirectUri(pClientRedirectURI).Build();
TokenCacheHelper.EnableSerialization(m_authContext.UserTokenCache);
authResult = await m_authContext.AcquireTokenInteractive(m_scope).ExecuteAsync();
}
}
到目前为止,代码运行良好,并且在两种情况下初始身份验证都成功。现在的问题是我们希望保留获取的令牌,以便用户下次启动我们的程序并尝试访问 SharePoint 时,他不必再次进行身份验证。但是尝试使用先前存储的令牌进行静默身份验证不起作用,无论是对于公众还是机密应用程序。然而, AfterAccessNotification 的序列化似乎确实有效,因为至少有一些东西被写入缓存文件。但是读回这些数据不会。需要指出的一件事是GetAccountsAsync()将始终返回 0。
到目前为止,我从 Microsoft 文档和此处的其他问题中读到的内容是,应用程序的内存缓存在重新创建时当然会丢失,解决方案似乎是 TokenCacheHelper 的实现。我们的助手类是按照文档中的建议实现的:
static class TokenCacheHelper
{
public static readonly string CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + "msalcache.txt";
private static readonly object FileLock = new object();
public static void EnableSerialization(ITokenCache tokenCache)
{
Debugger.Launch();
tokenCache.SetBeforeAccess(BeforeAccessNotification);
tokenCache.SetAfterAccess(AfterAccessNotification);
}
private static void BeforeAccessNotification(TokenCacheNotificationArgs args)
{
args.TokenCache.DeserializeMsalV3(File.Exists(CacheFilePath)
? ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath),
null,
DataProtectionScope.CurrentUser)
: null);
}
private static void AfterAccessNotification(TokenCacheNotificationArgs args)
{
Debugger.Launch();
if (args.HasStateChanged)
{
lock (FileLock)
{
// reflect changesgs in the persistent store
File.WriteAllBytes(CacheFilePath,
ProtectedData.Protect(args.TokenCache.SerializeMsalV3(),
null,
DataProtectionScope.CurrentUser)
);
}
}
}
}
我对 TokenCacheHelper 或其他东西的使用有重大误解吗?或者是否有更简单的方法来持久化令牌缓存?使用 ADAL 似乎没有那么复杂。
非常感谢您的帮助。