/// <summary> /// Initializes a new instance of the <see cref="AdalCache"/> class. /// </summary> /// <param name="storage">Adal cache storage</param> /// <param name="logger">Logger</param> /// <param name="lockRetryDelay">Delay in ms between retries if cache lock is contended</param> /// <param name="lockRetryCount">Number of retries if cache lock is contended</param> public AdalCache(AdalCacheStorage storage, TraceSource logger, int lockRetryDelay, int lockRetryCount) { _logger = logger ?? s_staticLogger.Value; _store = storage ?? throw new ArgumentNullException(nameof(storage)); _lockFileRetryCount = lockRetryCount; _lockFileRetryDelay = lockRetryDelay; AfterAccess = AfterAccessNotification; BeforeAccess = BeforeAccessNotification; _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Initializing adal cache"); byte[] data = _store.ReadData(); _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Read '{data?.Length}' bytes from storage"); if (data != null && data.Length > 0) { try { _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Deserializing data into memory"); DeserializeAdalV3(data); } catch (Exception e) { _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"An exception was encountered while deserializing the data during initialization of {nameof(AdalCache)} : {e}"); DeserializeAdalV3(null); _store.Clear(); } } _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Done initializing"); }
// Triggered right before ADAL needs to access the cache. // Reload the cache from the persistent store in case it changed since the last access. private void BeforeAccessNotification(TokenCacheNotificationArgs args) { _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Before access"); _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Acquiring lock for token cache"); _cacheLock = new CrossPlatLock( Path.GetFileNameWithoutExtension(_store.CreationProperties.CacheFileName), Path.Combine(_store.CreationProperties.CacheDirectory, _store.CreationProperties.CacheFileName) + ".lockfile"); if (_store.HasChanged) { _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Before access, the store has changed"); byte[] fileData = _store.ReadData(); _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Read '{fileData?.Length}' bytes from storage"); if (fileData != null && fileData.Length > 0) { try { _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"Deserializing the store"); DeserializeAdalV3(fileData); } catch (Exception e) { _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"An exception was encountered while deserializing the {nameof(AdalCache)} : {e}"); _logger.TraceEvent(TraceEventType.Error, /*id*/ 0, $"No data found in the store, clearing the cache in memory."); // Clear the memory cache DeserializeAdalV3(null); _store.Clear(); throw; } } else { _logger.TraceEvent(TraceEventType.Information, /*id*/ 0, $"No data found in the store, clearing the cache in memory."); // Clear the memory cache DeserializeAdalV3(null); } } }
// Triggered right before ADAL needs to access the cache. // Reload the cache from the persistent store in case it changed since the last access. // Internal for testing. internal void BeforeAccessNotification(TokenCacheNotificationArgs args) { _logger.LogInformation($"Before access"); _logger.LogInformation($"Acquiring lock for token cache"); _cacheLock = new CrossPlatLock(Path.Combine(_store.CreationProperties.CacheDirectory, _store.CreationProperties.CacheFileName) + ".lockfile", this._lockFileRetryDelay, this._lockFileRetryCount); _logger.LogInformation($"Before access, the store has changed"); byte[] fileData = _store.ReadData(); _logger.LogInformation($"Read '{fileData?.Length}' bytes from storage"); if (fileData != null && fileData.Length > 0) { try { _logger.LogInformation($"Deserializing the store"); DeserializeAdalV3(fileData); } catch (Exception e) { _logger.LogError($"An exception was encountered while deserializing the {nameof(AdalCache)} : {e}"); _logger.LogError($"No data found in the store, clearing the cache in memory."); // Clear the memory cache DeserializeAdalV3(null); _store.Clear(); throw; } } else { _logger.LogInformation($"No data found in the store, clearing the cache in memory."); // Clear the memory cache DeserializeAdalV3(null); } }