예제 #1
0
        /// <summary>
        /// Raised AFTER MSAL added the new token in its in-memory copy of the cache.
        /// This notification is called every time MSAL accessed the cache, not just when a write took place:
        /// If MSAL's current operation resulted in a cache change, the property TokenCacheNotificationArgs.HasStateChanged will be set to true.
        /// If that is the case, we call the TokenCache.Serialize() to get a binary blob representing the latest cache content – and persist it.
        /// </summary>
        /// <param name="args">Contains parameters used by the MSAL call accessing the cache.</param>
        private void UserTokenCacheAfterAccessNotification(TokenCacheNotificationArgs args)
        {
            SetSignedInUserFromNotificationArgs(args);

            // if state changed, i.e. new token obtained
            if (args.HasStateChanged && !string.IsNullOrWhiteSpace(GetSignedInUsersUniqueId()))
            {
                if (_inMemoryCache == null)
                {
                    _inMemoryCache = new UserTokenCache
                    {
                        WebUserUniqueId = GetSignedInUsersUniqueId()
                    };
                }

                _inMemoryCache.CacheBits = _dataProtector.Protect(_userTokenCache.SerializeMsalV3());
                _inMemoryCache.LastWrite = DateTime.Now;

                try
                {
                    // Update the DB and the lastwrite
                    _tokenCacheDb.Entry(_inMemoryCache).State = _inMemoryCache.UserTokenCacheId == 0
                        ? EntityState.Added
                        : EntityState.Modified;

                    _tokenCacheDb.SaveChanges();
                }
                catch (DbUpdateConcurrencyException)
                {
                    // Record already updated on a different thread, so just read the updated record
                    ReadCacheForSignedInUser();
                }
            }
        }