Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.