尝试序列化从使用 MSAL 进行身份验证返回的 token 缓存时,我遇到了一些问题。
我会很感激任何帮助,因为我真的不明白我做错了什么。
这是我们的情况/问题:
我们目前使用 ADAL 允许用户从我们的桌面应用程序对其 SharePoint Online 帐户进行身份验证,但希望切换到 MSAL。
我们已经实现了两种可能的身份验证流程。一个 publicClientApplication,允许用户使用其当前事件的 Microsoft 凭据和一个 ConfidentialClientApplication 进行身份验证,它允许使用证书进行身份验证,如下面代码的 catch block 所示:
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();
}
}
到目前为止,代码工作正常,初始身份验证在两种情况下都成功。现在的问题是我们希望保留获得的 token ,以便用户下次启动我们的程序并尝试访问 SharePoint 时不必再次进行身份验证。但是尝试使用先前存储的 token 进行静默身份验证是行不通的,无论是对于公共(public)应用程序还是 secret 应用程序。
然而,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 或这里的其他东西有重大误解吗?或者有没有更简单的方法来持久化 token 缓存?
使用 ADAL 似乎要简单得多。
非常感谢您的帮助。
最佳答案
我们找出了导致问题的原因。只需调用 TokenCacheHelper.EnableSerialization(m_authContext.UserTokenCache);
在尝试获取 token 之前丢失。
关于c# - MSAL.NET 中的 token 缓存序列化不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68395034/