@@ -28,110 +28,96 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2828
2929namespace GroupManager . Utils
3030{
31- /// <summary>
32- /// An implementation of token cache for Confidential clients backed by MemoryCache.
33- /// MemoryCache is useful in Api scenarios where there is no HttpContext to cache data.
34- /// </summary>
35- /// <seealso cref="https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/token-cache-serialization"/>
36- public class MSALAppMemoryTokenCache
37- {
38- /// <summary>
39- /// The application cache key
40- /// </summary>
41- internal readonly string AppCacheId ;
42-
43- /// <summary>
44- /// The backing MemoryCache instance
45- /// </summary>
46- internal readonly MemoryCache memoryCache = MemoryCache . Default ;
47-
48- /// <summary>
49- /// The duration till the tokens are kept in memory cache. In production, a higher value , upto 90 days is recommended.
50- /// </summary>
51- private readonly DateTimeOffset cacheDuration = DateTimeOffset . Now . AddHours ( 48 ) ;
52-
53- /// <summary>
54- /// The internal handle to the client's instance of the Cache
55- /// </summary>
56- private ITokenCache ApptokenCache ;
57-
58- /// <summary>
59- /// Initializes a new instance of the <see cref="MSALAppMemoryTokenCache"/> class.
60- /// </summary>
61- /// <param name="tokenCache">The client's instance of the token cache.</param>
62- /// <param name="clientId">The application's id (Client ID).</param>
63- public MSALAppMemoryTokenCache ( ITokenCache tokenCache , string clientId )
64- {
65- this . AppCacheId = clientId + "_AppTokenCache" ;
66-
67- if ( this . ApptokenCache == null )
68- {
69- this . ApptokenCache = tokenCache ;
70- this . ApptokenCache . SetBeforeAccess ( this . AppTokenCacheBeforeAccessNotification ) ;
71- this . ApptokenCache . SetAfterAccess ( this . AppTokenCacheAfterAccessNotification ) ;
72- this . ApptokenCache . SetBeforeWrite ( this . AppTokenCacheBeforeWriteNotification ) ;
73- }
74-
75- this . LoadAppTokenCacheFromMemory ( ) ;
76- }
77-
78- /// <summary>
79- /// if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry
80- /// </summary>
81- /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param>
82- private void AppTokenCacheBeforeWriteNotification ( TokenCacheNotificationArgs args )
83- {
84- // Since we are using a MemoryCache ,whose methods are threads safe, we need not to do anything in this handler.
85- }
86-
87- /// <summary>
88- /// Loads the application's token from memory cache.
89- /// </summary>
90- private void LoadAppTokenCacheFromMemory ( )
91- {
92- // Ideally, methods that load and persist should be thread safe. MemoryCache.Get() is thread safe.
93- byte [ ] tokenCacheBytes = ( byte [ ] ) this . memoryCache . Get ( this . AppCacheId ) ;
94- this . ApptokenCache . DeserializeMsalV3 ( tokenCacheBytes ) ;
95- }
96-
97- /// <summary>
98- /// Persists the application's token to the cache.
99- /// </summary>
100- private void PersistAppTokenCache ( )
101- {
102- // Ideally, methods that load and persist should be thread safe.MemoryCache.Get() is thread safe.
103- // Reflect changes in the persistence store
104- this . memoryCache . Set ( this . AppCacheId , this . ApptokenCache . SerializeMsalV3 ( ) , this . cacheDuration ) ;
105- }
106-
107- public void Clear ( )
108- {
109- this . memoryCache . Remove ( this . AppCacheId ) ;
110-
111- // Nulls the currently deserialized instance
112- this . LoadAppTokenCacheFromMemory ( ) ;
113- }
114-
115- /// <summary>
116- /// Triggered right before MSAL needs to access the cache. Reload the cache from the persistence store in case it changed since the last access.
117- /// </summary>
118- /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param>
119- private void AppTokenCacheBeforeAccessNotification ( TokenCacheNotificationArgs args )
120- {
121- this . LoadAppTokenCacheFromMemory ( ) ;
122- }
123-
124- /// <summary>
125- /// Triggered right after MSAL accessed the cache.
126- /// </summary>
127- /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param>
128- private void AppTokenCacheAfterAccessNotification ( TokenCacheNotificationArgs args )
129- {
130- // if the access operation resulted in a cache update
131- if ( args . HasStateChanged )
132- {
133- this . PersistAppTokenCache ( ) ;
134- }
135- }
136- }
31+ /// <summary>
32+ /// An implementation of token cache for Confidential clients backed by MemoryCache.
33+ /// MemoryCache is useful in Api scenarios where there is no HttpContext to cache data.
34+ /// </summary>
35+ /// <seealso cref="https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/token-cache-serialization"/>
36+ public class MSALAppMemoryTokenCache
37+ {
38+ /// <summary>
39+ /// The application cache key
40+ /// </summary>
41+ internal readonly string AppCacheId ;
42+
43+ /// <summary>
44+ /// The backing MemoryCache instance
45+ /// </summary>
46+ internal readonly MemoryCache memoryCache = MemoryCache . Default ;
47+
48+ /// <summary>
49+ /// The duration till the tokens are kept in memory cache. In production, a higher value , upto 90 days is recommended.
50+ /// </summary>
51+ private readonly DateTimeOffset cacheDuration = DateTimeOffset . Now . AddHours ( 48 ) ;
52+
53+ /// <summary>
54+ /// Initializes a new instance of the <see cref="MSALAppMemoryTokenCache"/> class.
55+ /// </summary>
56+ /// <param name="tokenCache">The client's instance of the token cache.</param>
57+ /// <param name="clientId">The application's id (Client ID).</param>
58+ public MSALAppMemoryTokenCache ( ITokenCache tokenCache , string clientId )
59+ {
60+ this . AppCacheId = clientId + "_AppTokenCache" ;
61+
62+ tokenCache . SetBeforeAccess ( AppTokenCacheBeforeAccessNotification ) ;
63+ tokenCache . SetAfterAccess ( AppTokenCacheAfterAccessNotification ) ;
64+ tokenCache . SetBeforeWrite ( AppTokenCacheBeforeWriteNotification ) ;
65+ }
66+
67+ /// <summary>
68+ /// if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry
69+ /// </summary>
70+ /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param>
71+ private void AppTokenCacheBeforeWriteNotification ( TokenCacheNotificationArgs args )
72+ {
73+ // Since we are using a MemoryCache ,whose methods are threads safe, we need not to do anything in this handler.
74+ }
75+
76+ /// <summary>
77+ /// Loads the application's token from memory cache.
78+ /// </summary>
79+ private void LoadAppTokenCacheFromMemory ( TokenCacheNotificationArgs args )
80+ {
81+ // Ideally, methods that load and persist should be thread safe. MemoryCache.Get() is thread safe.
82+ byte [ ] tokenCacheBytes = ( byte [ ] ) this . memoryCache . Get ( this . AppCacheId ) ;
83+ args . TokenCache . DeserializeMsalV3 ( tokenCacheBytes ) ;
84+ }
85+
86+ /// <summary>
87+ /// Persists the application's token to the cache.
88+ /// </summary>
89+ private void PersistAppTokenCache ( TokenCacheNotificationArgs args )
90+ {
91+ // Ideally, methods that load and persist should be thread safe.MemoryCache.Get() is thread safe.
92+ // Reflect changes in the persistence store
93+ this . memoryCache . Set ( this . AppCacheId , args . TokenCache . SerializeMsalV3 ( ) , this . cacheDuration ) ;
94+ }
95+
96+ public void Clear ( )
97+ {
98+ this . memoryCache . Remove ( this . AppCacheId ) ;
99+ }
100+
101+ /// <summary>
102+ /// Triggered right before MSAL needs to access the cache. Reload the cache from the persistence store in case it changed since the last access.
103+ /// </summary>
104+ /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param>
105+ private void AppTokenCacheBeforeAccessNotification ( TokenCacheNotificationArgs args )
106+ {
107+ this . LoadAppTokenCacheFromMemory ( args ) ;
108+ }
109+
110+ /// <summary>
111+ /// Triggered right after MSAL accessed the cache.
112+ /// </summary>
113+ /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param>
114+ private void AppTokenCacheAfterAccessNotification ( TokenCacheNotificationArgs args )
115+ {
116+ // if the access operation resulted in a cache update
117+ if ( args . HasStateChanged )
118+ {
119+ this . PersistAppTokenCache ( args ) ;
120+ }
121+ }
122+ }
137123}
0 commit comments