diff --git a/TaskWebApp/TaskWebApp.csproj b/TaskWebApp/TaskWebApp.csproj
index 1573c5b..49f2b86 100644
--- a/TaskWebApp/TaskWebApp.csproj
+++ b/TaskWebApp/TaskWebApp.csproj
@@ -52,8 +52,8 @@
..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll
-
- ..\packages\Microsoft.Identity.Client.3.0.8\lib\net45\Microsoft.Identity.Client.dll
+
+ ..\packages\Microsoft.Identity.Client.4.3.1\lib\net45\Microsoft.Identity.Client.dll
..\packages\Microsoft.IdentityModel.JsonWebTokens.5.4.0\lib\net451\Microsoft.IdentityModel.JsonWebTokens.dll
@@ -187,7 +187,6 @@
-
diff --git a/TaskWebApp/Utils/MSALPerUserMemoryTokenCache.cs b/TaskWebApp/Utils/MSALPerUserMemoryTokenCache.cs
index 3624b51..7784f0a 100644
--- a/TaskWebApp/Utils/MSALPerUserMemoryTokenCache.cs
+++ b/TaskWebApp/Utils/MSALPerUserMemoryTokenCache.cs
@@ -41,11 +41,6 @@ public class MSALPerUserMemoryTokenCache
///
private readonly DateTimeOffset cacheDuration = DateTimeOffset.Now.AddHours(48);
- ///
- /// The internal handle to the client's instance of the Cache
- ///
- private ITokenCache UserTokenCache;
-
///
/// Once the user signes in, this will not be null and can be ontained via a call to Thread.CurrentPrincipal
///
@@ -77,18 +72,15 @@ private void Initialize(ITokenCache tokenCache, ClaimsPrincipal user)
{
this.SignedInUser = user;
- this.UserTokenCache = tokenCache;
- this.UserTokenCache.SetBeforeAccess(this.UserTokenCacheBeforeAccessNotification);
- this.UserTokenCache.SetAfterAccess(this.UserTokenCacheAfterAccessNotification);
- this.UserTokenCache.SetBeforeWrite(this.UserTokenCacheBeforeWriteNotification);
+ tokenCache.SetBeforeAccess(this.UserTokenCacheBeforeAccessNotification);
+ tokenCache.SetAfterAccess(this.UserTokenCacheAfterAccessNotification);
+ tokenCache.SetBeforeWrite(this.UserTokenCacheBeforeWriteNotification);
if (this.SignedInUser == null)
{
// No users signed in yet, so we return
return;
}
-
- this.LoadUserTokenCacheFromMemory();
}
///
@@ -107,7 +99,7 @@ internal string GetMsalAccountId()
///
/// Loads the user token cache from memory.
///
- private void LoadUserTokenCacheFromMemory()
+ private void LoadUserTokenCacheFromMemory(ITokenCacheSerializer tokenCache)
{
string cacheKey = this.GetMsalAccountId();
@@ -116,13 +108,13 @@ private void LoadUserTokenCacheFromMemory()
// Ideally, methods that load and persist should be thread safe. MemoryCache.Get() is thread safe.
byte[] tokenCacheBytes = (byte[])this.memoryCache.Get(this.GetMsalAccountId());
- this.UserTokenCache.DeserializeMsalV3(tokenCacheBytes);
+ tokenCache.DeserializeMsalV3(tokenCacheBytes);
}
///
/// Persists the user token blob to the memoryCache.
///
- private void PersistUserTokenCache()
+ private void PersistUserTokenCache(ITokenCacheSerializer tokenCache)
{
string cacheKey = this.GetMsalAccountId();
@@ -130,7 +122,7 @@ private void PersistUserTokenCache()
return;
// Ideally, methods that load and persist should be thread safe.MemoryCache.Get() is thread safe.
- this.memoryCache.Set(this.GetMsalAccountId(), this.UserTokenCache.SerializeMsalV3(), this.cacheDuration);
+ this.memoryCache.Set(this.GetMsalAccountId(), tokenCache.SerializeMsalV3(), this.cacheDuration);
}
///
@@ -139,9 +131,6 @@ private void PersistUserTokenCache()
public void Clear()
{
this.memoryCache.Remove(this.GetMsalAccountId());
-
- // Nulls the currently deserialized instance
- this.LoadUserTokenCacheFromMemory();
}
///
@@ -155,7 +144,7 @@ private void UserTokenCacheAfterAccessNotification(TokenCacheNotificationArgs ar
// if the access operation resulted in a cache update
if (args.HasStateChanged)
{
- this.PersistUserTokenCache();
+ this.PersistUserTokenCache(args.TokenCache);
}
}
@@ -165,7 +154,7 @@ private void UserTokenCacheAfterAccessNotification(TokenCacheNotificationArgs ar
/// Contains parameters used by the MSAL call accessing the cache.
private void UserTokenCacheBeforeAccessNotification(TokenCacheNotificationArgs args)
{
- this.LoadUserTokenCacheFromMemory();
+ this.LoadUserTokenCacheFromMemory(args.TokenCache);
}
///
diff --git a/TaskWebApp/Utils/MSALPerUserSessionTokenCache.cs b/TaskWebApp/Utils/MSALPerUserSessionTokenCache.cs
deleted file mode 100644
index c4dc1ce..0000000
--- a/TaskWebApp/Utils/MSALPerUserSessionTokenCache.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- The MIT License (MIT)
-
-Copyright (c) 2015 Microsoft Corporation
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-using Microsoft.Identity.Client;
-using System.Security.Claims;
-using System.Threading;
-using System.Web;
-
-namespace TaskWebApp.Utils
-{
- ///
- /// This is a MSAL's TokenCache implementation for one user. It uses Sql server as a backend store and uses the Entity Framework to read and write to that database.
- ///
- ///
- public class MSALPerUserSessionTokenCache
- {
- private static ReaderWriterLockSlim SessionLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
-
- ///
- /// Once the user signes in, this will not be null and can be ontained via a call to ClaimsPrincipal.Current
- ///
- internal ClaimsPrincipal SignedInUser;
-
- ///
- /// The HTTP context being used by this app
- ///
- private HttpContextBase HttpContext = null;
-
- ///
- /// The internal handle to the client's instance of the Cache
- ///
- private ITokenCache UserTokenCache;
-
- /// Initializes a new instance of the class.
- /// The token cache.
- /// The current HttpContext.
- public MSALPerUserSessionTokenCache(ITokenCache tokenCache, HttpContextBase httpcontext)
- {
- this.Initialize(tokenCache, httpcontext, ClaimsPrincipal.Current);
- }
-
- public MSALPerUserSessionTokenCache(ITokenCache tokenCache, HttpContextBase httpcontext, ClaimsPrincipal user)
- {
- this.Initialize(tokenCache, httpcontext, user);
- }
-
- /// Initializes the cache instance
- /// The ITokenCache passed through the constructor
- /// The current HttpContext
- /// The signed in user's ClaimPrincipal, could be null.
- /// If the calling app has it available, then it should pass it themselves.
- private void Initialize(ITokenCache tokenCache, HttpContextBase httpcontext, ClaimsPrincipal user)
- {
- this.HttpContext = httpcontext;
-
- this.UserTokenCache = tokenCache;
-
- this.UserTokenCache.SetBeforeAccess(this.UserTokenCacheBeforeAccessNotification);
- this.UserTokenCache.SetAfterAccess(this.UserTokenCacheAfterAccessNotification);
- this.UserTokenCache.SetBeforeWrite(this.UserTokenCacheBeforeWriteNotification);
-
- if (user == null)
- {
- // No users signed in yet, so we return
- return;
- }
-
- this.SignedInUser = user;
- this.LoadUserTokenCacheFromSession();
- }
-
- ///
- /// Loads the user token cache from http session.
- ///
- public void LoadUserTokenCacheFromSession()
- {
- string cacheKey = this.GetSignedInUsersUniqueId();
-
- if (string.IsNullOrWhiteSpace(cacheKey))
- return;
-
- SessionLock.EnterReadLock();
- try
- {
- this.UserTokenCache.DeserializeMsalV3((byte[])this.HttpContext.Session[cacheKey]);
- }
- finally
- {
- SessionLock.ExitReadLock();
- }
- }
-
- ///
- /// Persists the user token blob to the Http session.
- ///
- public void PersistUserTokenCache()
- {
- string cacheKey = this.GetSignedInUsersUniqueId();
-
- if (string.IsNullOrWhiteSpace(cacheKey))
- return;
-
- SessionLock.EnterWriteLock();
-
- try
- {
- // Reflect changes in the persistence store
- this.HttpContext.Session[cacheKey] = this.UserTokenCache.SerializeMsalV3();
- }
- finally
- {
- SessionLock.ExitWriteLock();
- }
- }
-
- ///
- /// Clears the TokenCache's copy of this user's cache.
- ///
- public void Clear()
- {
- string cacheKey = this.GetSignedInUsersUniqueId();
-
- if (string.IsNullOrWhiteSpace(cacheKey))
- return;
-
- // httpContext.Session[this.GetSignedInUsersCacheKey()] = null;
-
- SessionLock.EnterWriteLock();
-
- try
- {
- // Reflect changes in the persistent store
- this.HttpContext.Session.Remove(cacheKey);
- }
- finally
- {
- SessionLock.ExitWriteLock();
- }
-
- // Nulls the currently deserialized instance
- this.LoadUserTokenCacheFromSession();
- }
-
- ///
- /// if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry
- ///
- /// Contains parameters used by the MSAL call accessing the cache.
-
- private void UserTokenCacheBeforeWriteNotification(TokenCacheNotificationArgs args)
- {
- // Since we obtain and release lock right before and after we read the Http session, we need not do anything here.
- }
-
- ///
- /// Triggered right after MSAL accessed the cache.
- ///
- /// Contains parameters used by the MSAL call accessing the cache.
- private void UserTokenCacheAfterAccessNotification(TokenCacheNotificationArgs args)
- {
- // if the access operation resulted in a cache update
- if (args.HasStateChanged)
- {
- this.PersistUserTokenCache();
- }
- }
-
- ///
- /// Triggered right before MSAL needs to access the cache. Reload the cache from the persistence store in case it changed since the last access.
- ///
- /// Contains parameters used by the MSAL call accessing the cache.
- private void UserTokenCacheBeforeAccessNotification(TokenCacheNotificationArgs args)
- {
- this.LoadUserTokenCacheFromSession();
- }
-
- ///
- /// Explores the Claims of a signed-in user (if available) to populate the unique Id of this cache's instance.
- ///
- /// The signed in user's object.tenant Id , if available in the ClaimsPrincipal.Current instance
- internal string GetSignedInUsersUniqueId()
- {
- if (this.SignedInUser != null)
- {
- return this.SignedInUser.GetB2CMsalAccountId();
- }
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/TaskWebApp/Utils/MsalAppBuilder.cs b/TaskWebApp/Utils/MsalAppBuilder.cs
index 11e2a7a..d6ace6d 100644
--- a/TaskWebApp/Utils/MsalAppBuilder.cs
+++ b/TaskWebApp/Utils/MsalAppBuilder.cs
@@ -76,8 +76,8 @@ public static async Task ClearUserTokenCache()
//Remove the users from the MSAL's internal cache
await clientapp.RemoveAsync(account);
}
+ userTokenCache.Clear();
- userTokenCache.Clear();
- }
- }
+ }
+ }
}
\ No newline at end of file
diff --git a/TaskWebApp/packages.config b/TaskWebApp/packages.config
index 7c67a14..8ea9241 100644
--- a/TaskWebApp/packages.config
+++ b/TaskWebApp/packages.config
@@ -9,7 +9,7 @@
-
+