Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

250
Views
La serialización de caché de tokens en MSAL.NET no funciona

Me enfrento a algunos problemas al intentar serializar el tokencache, devuelto de la autenticación con MSAL. Agradecería cualquier ayuda, ya que realmente no entiendo lo que estoy haciendo mal. Aquí está nuestra situación/problema:

Actualmente usamos ADAL para permitir que los usuarios se autentiquen en sus cuentas de SharePoint Online desde nuestra aplicación de escritorio, pero queremos cambiar a MSAL.

Hemos implementado dos posibles flujos de autenticación. Una publicClientApplication, para permitir que el usuario se autentique con sus credenciales de Microsoft actualmente activas y una ConfidentialClientApplication, que permite autenticarse con el uso de un certificado, como puede ver en el bloque catch del código a continuación:

 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(); } }

Hasta ahora, el código funciona bien y la autenticación inicial es exitosa en ambos casos. El problema ahora es que nos gustaría conservar los tokens adquiridos, para que la próxima vez que el usuario inicie nuestro programa e intente acceder a SharePoint no tenga que autenticarse nuevamente. Pero tratar de autenticar en silencio con el uso de un token almacenado previamente no funciona, ni para la aplicación pública ni para la confidencial. Sin embargo, la serialización de AfterAccessNotification parece funcionar, ya que al menos algo se escribe en el archivo de caché. Pero la lectura de estos datos no lo hace. Una cosa a señalar es que GetAccountsAsync() siempre devolverá 0.

Lo que he leído hasta ahora, de la documentación de Microsoft y otras preguntas aquí, es que, por supuesto, el caché en memoria de las aplicaciones se perderá al recrearlo y la solución parece ser la implementación de TokenCacheHelper. Nuestra clase auxiliar se implementa como se sugiere en la documentación:

 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) ); } } } }

¿Tengo un gran malentendido sobre el uso de TokenCacheHelper o algo más aquí? ¿O hay una manera más simple de conservar el tokencache? Esto parecía ser mucho menos complicado con el uso de ADAL.

Muchas gracias por su ayuda.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

No hay forma más sencilla. Estoy usando esta clase provista por Mircosoft (TokenCacheHelper) y funciona muy bien. Estoy persistiendo el token ahora durante varias semanas. No hay problemas para leerlo y usarlo. En general, hasta donde lo probé, primero debe autenticarse de forma interactiva para muchos tipos de datos que desea leer y luego leer el token guardado para acciones futuras. Puede comprobar en su centro de seguridad de Azure qué datos ha autenticado de forma interactiva o puede autenticar de forma no interactiva.

  1. Vuelva a verificar su configuración de seguridad para leer cuentas en el centro de seguridad de Azure.
  2. Vuelva a comprobar ámbitos como: "User.Read", "User.ReadBasic.All"
  3. Consulte el ejemplo en https://github.com/Azure-Samples/active-directory-dotnet-desktop-msgraph-v2 que me ayudó

¡Pruébalo!

PD: Consideraría toda la biblioteca de MS-graph en un "estado beta" y todavía con errores, propensa a errores y no terminada. Así que espere un comportamiento diferente ahora y en el futuro.

Saludos

over 4 years ago · Santiago Trujillo Report

0

Descubrimos qué estaba causando el problema. Simplemente hubo una llamada de TokenCacheHelper.EnableSerialization(m_authContext.UserTokenCache); falta antes de intentar adquirir el token silencioso.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!