/// <summary> /// Raised AFTER MSAL added the new token in its in-memory copy of the cache. /// This notification is called every time MSAL accessed the cache, not just when a write took place: /// If MSAL's current operation resulted in a cache change, the property TokenCacheNotificationArgs.HasStateChanged will be set to true. /// If that is the case, we call the TokenCache.Serialize() to get a binary blob representing the latest cache content – and persist it. /// </summary> /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param> private void AppTokenCacheAfterAccessNotification(TokenCacheNotificationArgs args) { // if state changed, i.e. new token obtained if (args.HasStateChanged && !string.IsNullOrWhiteSpace(this.ActiveClientId)) { if (this.InMemoryCache == null) { this.InMemoryCache = new AppTokenCache { ClientID = this.ActiveClientId }; } this.InMemoryCache.CacheBits = this.DataProtector.Protect(this.ApptokenCache.SerializeMsalV3()); this.InMemoryCache.LastWrite = DateTime.Now; try { // Update the DB and the lastwrite this.TokenCacheDb.Entry(InMemoryCache).State = InMemoryCache.AppTokenCacheId == 0 ? EntityState.Added : EntityState.Modified; this.TokenCacheDb.SaveChanges(); } catch (DbUpdateConcurrencyException) { // Record already updated on a different thread, so just read the updated record this.ReadCacheForSignedInApp(); } } }
/// <summary> /// Reads the cache data from the backend database. /// </summary> private void ReadCacheForSignedInApp() { if (this.InMemoryCache == null) // first time access { this.InMemoryCache = GetLatestAppRecordQuery().FirstOrDefault(); } else { // retrieve last written record from the DB var lastwriteInDb = GetLatestAppRecordQuery().Select(n => n.LastWrite).FirstOrDefault(); // if the persisted copy is newer than the in-memory copy if (lastwriteInDb > this.InMemoryCache.LastWrite) { // read from from storage, update in-memory copy this.InMemoryCache = GetLatestAppRecordQuery().FirstOrDefault(); } } // Send data to the TokenCache instance this.ApptokenCache.DeserializeMsalV3((this.InMemoryCache == null) ? null : this.DataProtector.Unprotect(this.InMemoryCache.CacheBits)); }
/// <summary> /// Reads the cache data from the backend database. /// </summary> private void ReadCacheForSignedInApp(TokenCacheNotificationArgs args) { // first time access if (this.inMemoryCache == null) { this.inMemoryCache = this.GetLatestAppRecordQuery().FirstOrDefault(); } else { // retrieve last written record from the DB var lastwriteInDb = this.GetLatestAppRecordQuery().Select(n => n.LastWrite).FirstOrDefault(); // if the persisted copy is newer than the in-memory copy if (lastwriteInDb > this.inMemoryCache.LastWrite) { // read from from storage, update in-memory copy this.inMemoryCache = this.GetLatestAppRecordQuery().FirstOrDefault(); } } // Send data to the TokenCache instance args.TokenCache.DeserializeMsalV3((this.inMemoryCache == null) ? null : this.dataProtector.Unprotect(this.inMemoryCache.CacheBits), shouldClearExistingCache: true); }