/// <summary> /// Before cache access /// </summary> /// <param name="args">Callback parameters from MSAL</param> internal void BeforeAccessNotification(TokenCacheNotificationArgs args) { _logger.LogInformation($"Before access"); _logger.LogInformation($"Acquiring lock for token cache"); // OK, we have two nested locks here. We need to maintain a clear ordering to avoid deadlocks. // 1. Use the CrossPlatLock which is respected by all processes and is used around all cache accesses. // 2. Use _lockObject which is used in UnregisterCache, and is needed for all accesses of _registeredCaches. CacheLock = CreateCrossPlatLock(_storageCreationProperties); _logger.LogInformation($"Before access, the store has changed"); var cachedStoreData = CacheStore.ReadData(); _logger.LogInformation($"Read '{cachedStoreData?.Length}' bytes from storage"); lock (_lockObject) { try { _logger.LogInformation($"Deserializing the store"); args.TokenCache.DeserializeMsalV3(cachedStoreData, shouldClearExistingCache: true); } catch (Exception e) { _logger.LogError($"An exception was encountered while deserializing the {nameof(MsalCacheHelper)} : {e}"); _logger.LogError($"No data found in the store, clearing the cache in memory."); // Clear the memory cache Clear(); throw; } } }
/// <summary> /// Extracts the token cache data from the persistent store /// </summary> /// <returns>an UTF-8 byte array of the unencrypted token cache</returns> /// <remarks>This method should be used with care. The data returned is unencrypted.</remarks> public byte[] LoadUnencryptedTokenCache() { using (CreateCrossPlatLock(_storageCreationProperties)) { return(CacheStore.ReadData(ignoreExceptions: false)); } }