You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

86 lines
2.7 KiB

using Microsoft.Identity.Client;
using System.Threading;
using System.Web;
namespace WebApp.Outlook.TokenStorage
{
public class SessionTokenCache
{
private static ReaderWriterLockSlim SessionLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
private string UserId = string.Empty;
private string CacheId = string.Empty;
private HttpContextBase httpContext = null;
private TokenCache cache = new TokenCache();
public SessionTokenCache(string userId, HttpContextBase httpcontext)
{
// not object, we want the SUB
UserId = userId;
CacheId = UserId + "_TokenCache";
httpContext = httpcontext;
Load();
}
public TokenCache GetMsalCacheInstance()
{
cache.SetBeforeAccess(BeforeAccessNotification);
cache.SetAfterAccess(AfterAccessNotification);
Load();
return cache;
}
public void SaveUserStateValue(string state)
{
SessionLock.EnterWriteLock();
httpContext.Session[CacheId + "_state"] = state;
SessionLock.ExitWriteLock();
}
public string ReadUserStateValue()
{
var state = string.Empty;
SessionLock.EnterReadLock();
state = (string)httpContext.Session[CacheId + "_state"];
SessionLock.ExitReadLock();
return state;
}
public void Load()
{
SessionLock.EnterReadLock();
cache.Deserialize((byte[])httpContext.Session[CacheId]);
SessionLock.ExitReadLock();
}
public void Persist()
{
SessionLock.EnterWriteLock();
// Optimistically set HasStateChanged to false. We need to do it early to avoid losing
// changes made by a concurrent thread.
cache.HasStateChanged = false;
// Reflect changes in the persistent store
httpContext.Session[CacheId] = cache.Serialize();
SessionLock.ExitWriteLock();
}
// Triggered right before MSAL 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)
{
Load();
}
// Triggered right after MSAL accessed the cache.
private void AfterAccessNotification(TokenCacheNotificationArgs args)
{
// if the access operation resulted in a cache update
if (cache.HasStateChanged)
{
Persist();
}
}
}
}