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
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();
|
|
}
|
|
}
|
|
}
|
|
}
|