Created
June 28, 2017 08:56
-
-
Save luismanez/a80860ebc96622df62df6afcdb647961 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class EFADALTokenCache : TokenCache | |
| { | |
| private ApplicationDbContext db = new ApplicationDbContext(); | |
| private string user; | |
| private PerWebUserCache cache; | |
| // constructor | |
| public EFADALTokenCache(string user) | |
| { | |
| // associate the cache to the current user of the web app | |
| this.user = user; | |
| this.AfterAccess = AfterAccessNotification; | |
| this.BeforeAccess = BeforeAccessNotification; | |
| this.BeforeWrite = BeforeWriteNotification; | |
| // look up the entry in the DB | |
| cache = db.PerUserCacheList.FirstOrDefault(c => c.WebUserUniqueId == this.user); | |
| // place the entry in memory | |
| this.Deserialize(cache?.CacheBits); | |
| } | |
| // clean up the DB | |
| public override void Clear() | |
| { | |
| base.Clear(); | |
| foreach (var cacheEntry in db.PerUserCacheList.Where(u => u.WebUserUniqueId == user).ToList()) | |
| db.PerUserCacheList.Remove(cacheEntry); | |
| db.SaveChanges(); | |
| } | |
| // Notification raised before ADAL accesses the cache. | |
| // This is your chance to update the in-memory copy from the DB, if the in-memory version is stale | |
| private void BeforeAccessNotification(TokenCacheNotificationArgs args) | |
| { | |
| if (cache == null) | |
| { | |
| // first time access | |
| cache = db.PerUserCacheList.FirstOrDefault(c => c.WebUserUniqueId == user); | |
| } | |
| else | |
| { // retrieve last write from the DB | |
| var status = from e in db.PerUserCacheList | |
| where (e.WebUserUniqueId == user) | |
| select new | |
| { | |
| LastWrite = e.LastWrite | |
| }; | |
| // if the in-memory copy is older than the persistent copy | |
| if (status.First().LastWrite > cache.LastWrite) | |
| //// read from from storage, update in-memory copy | |
| { | |
| cache = db.PerUserCacheList.FirstOrDefault(c => c.WebUserUniqueId == user); | |
| } | |
| } | |
| this.Deserialize((cache == null) ? null : cache.CacheBits); | |
| } | |
| // Notification raised after ADAL accessed the cache. | |
| // If the HasStateChanged flag is set, ADAL changed the content of the cache | |
| private void AfterAccessNotification(TokenCacheNotificationArgs args) | |
| { | |
| // if state changed | |
| if (this.HasStateChanged) | |
| { | |
| if (cache != null) | |
| { | |
| cache.CacheBits = this.Serialize(); | |
| cache.LastWrite = DateTime.Now; | |
| } | |
| else | |
| { | |
| cache = new PerWebUserCache | |
| { | |
| WebUserUniqueId = user, | |
| CacheBits = this.Serialize(), | |
| LastWrite = DateTime.Now | |
| }; | |
| } | |
| //// update the DB and the lastwrite | |
| db.Entry(cache).State = cache.EntryId == 0 ? EntityState.Added : EntityState.Modified; | |
| db.SaveChanges(); | |
| this.HasStateChanged = false; | |
| } | |
| } | |
| private void BeforeWriteNotification(TokenCacheNotificationArgs args) | |
| { | |
| // if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment