internal TokenCache(IServiceBundle serviceBundle, bool isApplicationTokenCache, ICacheSerializationProvider optionalDefaultSerializer = null)
        {
            if (serviceBundle == null)
            {
                throw new ArgumentNullException(nameof(serviceBundle));
            }

            // useRealSemaphore= false for MyApps and potentially for all apps when using non-singleton MSAL
            _semaphoreSlim = new OptionalSemaphoreSlim(useRealSemaphore: serviceBundle.Config.CacheSynchronizationEnabled);

            var proxy = serviceBundle?.PlatformProxy ?? PlatformProxyFactory.CreatePlatformProxy(null);

            _accessor     = proxy.CreateTokenCacheAccessor();
            _featureFlags = proxy.GetFeatureFlags();

            _usesDefaultSerialization = optionalDefaultSerializer != null;
            optionalDefaultSerializer?.Initialize(this);

            LegacyCachePersistence = proxy.CreateLegacyCachePersistence();

#if iOS
            SetIosKeychainSecurityGroup(serviceBundle.Config.IosKeychainSecurityGroup);
#endif // iOS

            IsAppTokenCache = isApplicationTokenCache;

            // Must happen last, this code can access things like _accessor and such above.
            ServiceBundle = serviceBundle;
        }
 private void AssertAccessorsAreEqual(ITokenCacheAccessor expected, ITokenCacheAccessor actual)
 {
     Assert.AreEqual(expected.GetAllAccessTokens().Count(), actual.GetAllAccessTokens().Count());
     Assert.AreEqual(expected.GetAllRefreshTokens().Count(), actual.GetAllRefreshTokens().Count());
     Assert.AreEqual(expected.GetAllIdTokens().Count(), actual.GetAllIdTokens().Count());
     Assert.AreEqual(expected.GetAllAccounts().Count(), actual.GetAllAccounts().Count());
 }
Example #3
0
        public static void AddAccountToCache(ITokenCacheAccessor accessor, string uid, string utid)
        {
            MsalAccountCacheItem accountCacheItem = new MsalAccountCacheItem
                                                        (MsalTestConstants.ProductionPrefCacheEnvironment, null, MockHelpers.CreateClientInfo(uid, utid), null, null, utid, null, null);

            accessor.SaveAccount(accountCacheItem);
        }
 public static void AddRefreshTokensToCache(ITokenCacheAccessor cacheAccessor, int tokensQuantity = 1)
 {
     for (int i = 1; i <= tokensQuantity; i++)
     {
         AddRefreshTokenToCache(cacheAccessor, Guid.NewGuid().ToString(), TestConstants.Utid);
     }
 }
 public static void ClearRefreshTokens(this ITokenCacheAccessor accessor)
 {
     foreach (var item in accessor.GetAllRefreshTokens())
     {
         accessor.DeleteRefreshToken(item.GetKey());
     }
 }
Example #6
0
 public static void ClearAccessTokens(this ITokenCacheAccessor accessor)
 {
     foreach (var item in accessor.GetAllAccessTokens())
     {
         accessor.DeleteAccessToken(item);
     }
 }
        public static void AddRefreshTokenToCache(ITokenCacheAccessor accessor, string uid, string utid, string name)
        {
            var rtItem = new MsalRefreshTokenCacheItem
                             (CoreTestConstants.ProductionPrefCacheEnvironment, CoreTestConstants.ClientId, "someRT", MockHelpers.CreateClientInfo(uid, utid));

            accessor.SaveRefreshToken(rtItem);
        }
Example #8
0
        internal TokenCache(IServiceBundle serviceBundle)
        {
            var proxy = serviceBundle?.PlatformProxy ?? PlatformProxyFactory.CreatePlatformProxy(null);

            _accessor     = proxy.CreateTokenCacheAccessor();
            _featureFlags = proxy.GetFeatureFlags();
            _defaultTokenCacheBlobStorage = proxy.CreateTokenCacheBlobStorage();

            if (_defaultTokenCacheBlobStorage != null)
            {
                BeforeAccess      = _defaultTokenCacheBlobStorage.OnBeforeAccess;
                AfterAccess       = _defaultTokenCacheBlobStorage.OnAfterAccess;
                BeforeWrite       = _defaultTokenCacheBlobStorage.OnBeforeWrite;
                AsyncBeforeAccess = null;
                AsyncAfterAccess  = null;
                AsyncBeforeWrite  = null;
            }

            LegacyCachePersistence = proxy.CreateLegacyCachePersistence();

#if iOS
            SetIosKeychainSecurityGroup(serviceBundle.Config.IosKeychainSecurityGroup);
#endif // iOS

            // Must happen last, this code can access things like _accessor and such above.
            ServiceBundle = serviceBundle;
        }
 internal void PopulateCacheForClientCredential(ITokenCacheAccessor accessor, int tokenQuantity = 1)
 {
     for (int i = 1; i <= tokenQuantity; i++)
     {
         var atItem = CreateAccessTokenItem(string.Format(System.Globalization.CultureInfo.InvariantCulture, TestConstants.ScopeStrFormat, i));
         accessor.SaveAccessToken(atItem);
     }
 }
Example #10
0
        public MsalClientFactory(IOptionsSnapshot <MsalOptions> config, ITokenCacheAccessor tokenCacheAccessor, ILoggerFactory loggerFactory)
        {
            _log = loggerFactory.CreateLogger <MsalClientFactory>();
            _log.LogDebug($"Entering MsalClientFactory without certificate");

            _config             = config.Get("Commercial");
            _chinaConfig        = config.Get("China");
            _tokenCacheAccessor = tokenCacheAccessor;
        }
Example #11
0
        public MsalClientFactory(IOptions <MsalOptions> config, ITokenCacheAccessor tokenCacheAccessor, X509Certificate2 cert, ILoggerFactory loggerFactory)
        {
            _log = loggerFactory.CreateLogger <MsalClientFactory>();
            _log.LogDebug($"Entering MsalClientFactory with injected certificate {cert.Subject}, {cert.Thumbprint}");

            _config             = config.Value;
            _config.Certificate = cert;
            _tokenCacheAccessor = tokenCacheAccessor;
        }
        internal void PopulateCache(ITokenCacheAccessor accessor)
        {
            PopulateCacheWithOneAccessToken(accessor);

            // add another access token
            accessor.SaveAccessToken(_atItem);

            AddRefreshTokenToCache(accessor, CoreTestConstants.Uid, CoreTestConstants.Utid, CoreTestConstants.Name);
        }
Example #13
0
        public static void AddIdTokenToCache(ITokenCacheAccessor accessor, string uid, string utid)
        {
            MsalIdTokenCacheItem idTokenCacheItem = new MsalIdTokenCacheItem(
                MsalTestConstants.ProductionPrefCacheEnvironment,
                MsalTestConstants.ClientId,
                MockHelpers.CreateIdToken(MsalTestConstants.UniqueId, MsalTestConstants.DisplayableId),
                MockHelpers.CreateClientInfo(),
                MsalTestConstants.Utid);

            accessor.SaveIdToken(idTokenCacheItem);
        }
        public static AdalResultWrapper FindMsalEntryForAdal(ITokenCacheAccessor tokenCacheAccessor, string authority,
                                                             string clientId, string upn, RequestContext requestContext)
        {
            try
            {
                var environment = new Uri(authority).Host;

                List <MsalAccountCacheItem> accounts = new List <MsalAccountCacheItem>();
                foreach (string accountStr in tokenCacheAccessor.GetAllAccountsAsString())
                {
                    var accountItem = JsonHelper.TryToDeserializeFromJson <MsalAccountCacheItem>(accountStr, requestContext);
                    if (accountItem != null && accountItem.Environment.Equals(environment, StringComparison.OrdinalIgnoreCase))
                    {
                        accounts.Add(accountItem);
                    }
                }
                if (accounts.Count > 0)
                {
                    foreach (var rtString in tokenCacheAccessor.GetAllRefreshTokensAsString())
                    {
                        var rtCacheItem =
                            JsonHelper.TryToDeserializeFromJson <MsalRefreshTokenCacheItem>(rtString, requestContext);

                        //TODO - authority check needs to be updated for alias check
                        if (rtCacheItem != null && environment.Equals(rtCacheItem.Environment, StringComparison.OrdinalIgnoreCase) &&
                            rtCacheItem.ClientId.Equals(clientId, StringComparison.OrdinalIgnoreCase))
                        {
                            // join refresh token cache item to corresponding account cache item to get upn
                            foreach (MsalAccountCacheItem accountCacheItem in accounts)
                            {
                                if (rtCacheItem.HomeAccountId.Equals(accountCacheItem.HomeAccountId, StringComparison.OrdinalIgnoreCase) &&
                                    accountCacheItem.PreferredUsername.Equals(upn, StringComparison.OrdinalIgnoreCase))
                                {
                                    return(new AdalResultWrapper
                                    {
                                        Result = new AdalResult(null, null, DateTimeOffset.MinValue),
                                        RefreshToken = rtCacheItem.Secret,
                                        RawClientInfo = rtCacheItem.RawClientInfo
                                    });
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MsalLogger.Default.WarningPiiWithPrefix(ex, "An error occurred while searching for refresh tokens in MSAL format in the cache for ADAL. " +
                                                        "For details please see https://aka.ms/net-cache-persistence-errors. ");
            }

            return(null);
        }
        public static void AddRefreshTokenToCache(
            ITokenCacheAccessor accessor,
            string uid,
            string utid,
            string clientId    = TestConstants.ClientId,
            string environment = TestConstants.ProductionPrefCacheEnvironment,
            string rtSecret    = TestConstants.RTSecret)
        {
            var rtItem = new MsalRefreshTokenCacheItem
                             (environment, clientId, rtSecret, MockHelpers.CreateClientInfo(uid, utid), null, $"{uid}.{utid}");

            accessor.SaveRefreshToken(rtItem);
        }
Example #16
0
        private static MsalAccessTokenCacheItem UpdateATWithRefreshOn(
            ITokenCacheAccessor accessor,
            DateTimeOffset refreshOn,
            bool expired = false)
        {
            MsalAccessTokenCacheItem atItem = accessor.GetAllAccessTokens().Single();

            UpdateATWithRefreshOn(atItem, refreshOn, expired);

            accessor.SaveAccessToken(atItem);

            return(atItem);
        }
        /// <summary>
        /// Serializes the entire token cache
        /// </summary>
        /// <param name="tokenCacheAccessor">Token cache accessor to perform cache read operations</param>
        /// <returns>array of bytes containing the serialized cache</returns>
        internal static byte[] SerializeUnifiedCache(ITokenCacheAccessor tokenCacheAccessor)
        {
            // reads the underlying in-memory dictionary and dumps out the content as a JSON
            Dictionary <string, IEnumerable <string> > cacheDict = new Dictionary <string, IEnumerable <string> >
            {
                [AccessTokenKey]  = tokenCacheAccessor.GetAllAccessTokensAsString(),
                [RefreshTokenKey] = tokenCacheAccessor.GetAllRefreshTokensAsString(),
                [IdTokenKey]      = tokenCacheAccessor.GetAllIdTokensAsString(),
                [AccountKey]      = tokenCacheAccessor.GetAllAccountsAsString()
            };

            return(JsonHelper.SerializeToJson(cacheDict).ToByteArray());
        }
Example #18
0
        internal void PopulateCacheForClientCredential(ITokenCacheAccessor accessor)
        {
            MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem(
                MsalTestConstants.ProductionPrefCacheEnvironment,
                MsalTestConstants.ClientId,
                MsalTestConstants.Scope.AsSingleString(),
                MsalTestConstants.Utid,
                "",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn)),
                MockHelpers.CreateClientInfo());

            accessor.SaveAccessToken(atItem);
        }
 internal static void AssertItemCount(
     this ITokenCacheAccessor accessor,
     int expectedAtCount,
     int expectedRtCount,
     int expectedIdtCount,
     int expectedAccountCount,
     int expectedAppMetadataCount = 0)
 {
     Assert.AreEqual(expectedAtCount, accessor.GetAllAccessTokens().Count());
     Assert.AreEqual(expectedRtCount, accessor.GetAllRefreshTokens().Count());
     Assert.AreEqual(expectedIdtCount, accessor.GetAllIdTokens().Count());
     Assert.AreEqual(expectedAccountCount, accessor.GetAllAccounts().Count());
     Assert.AreEqual(expectedAppMetadataCount, accessor.GetAllAppMetadata().Count());
 }
        internal static void PopulateCache(ITokenCacheAccessor accessor)
        {
            MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem(
                CoreTestConstants.ProductionPrefCacheEnvironment,
                CoreTestConstants.ClientId,
                "Bearer",
                CoreTestConstants.Scope.AsSingleString(),
                CoreTestConstants.Utid,
                "",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn)),
                MockHelpers.CreateClientInfo());

            // add access token
            accessor.SaveAccessToken(atItem);

            MsalIdTokenCacheItem idTokenCacheItem = new MsalIdTokenCacheItem(
                CoreTestConstants.ProductionPrefCacheEnvironment, CoreTestConstants.ClientId,
                MockHelpers.CreateIdToken(CoreTestConstants.UniqueId + "more", CoreTestConstants.DisplayableId),
                MockHelpers.CreateClientInfo(), CoreTestConstants.Utid);

            accessor.SaveIdToken(idTokenCacheItem);

            MsalAccountCacheItem accountCacheItem = new MsalAccountCacheItem
                                                        (CoreTestConstants.ProductionPrefNetworkEnvironment, null, MockHelpers.CreateClientInfo(), null, null, CoreTestConstants.Utid,
                                                        null, null);

            accessor.SaveAccount(accountCacheItem);

            atItem = new MsalAccessTokenCacheItem(
                CoreTestConstants.ProductionPrefCacheEnvironment,
                CoreTestConstants.ClientId,
                "Bearer",
                CoreTestConstants.ScopeForAnotherResource.AsSingleString(),
                CoreTestConstants.Utid,
                "",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn)),
                MockHelpers.CreateClientInfo());

            // add another access token
            accessor.SaveAccessToken(atItem);

            AddRefreshTokenToCache(accessor, CoreTestConstants.Uid, CoreTestConstants.Utid, CoreTestConstants.Name);
        }
        internal void PopulateCacheForClientCredential(ITokenCacheAccessor accessor)
        {
            string clientInfo = MockHelpers.CreateClientInfo();
            string homeAccId  = ClientInfo.CreateFromJson(clientInfo).ToAccountIdentifier();

            MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem(
                TestConstants.ProductionPrefCacheEnvironment,
                TestConstants.ClientId,
                TestConstants.s_scope.AsSingleString(),
                TestConstants.Utid,
                "",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn)),
                MockHelpers.CreateClientInfo(),
                homeAccId);

            accessor.SaveAccessToken(atItem);
        }
        internal void PopulateCacheWithOneAccessToken(ITokenCacheAccessor accessor)
        {
            string clientInfo    = MockHelpers.CreateClientInfo();
            string homeAccountId = ClientInfo.CreateFromJson(clientInfo).ToAccountIdentifier();

            MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem(
                TestConstants.ProductionPrefCacheEnvironment,
                TestConstants.ClientId,
                TestConstants.s_scope.AsSingleString(),
                TestConstants.Utid,
                "",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn)),
                clientInfo,
                homeAccountId);

            // add access token
            accessor.SaveAccessToken(atItem);

            MsalIdTokenCacheItem idTokenCacheItem = new MsalIdTokenCacheItem(
                TestConstants.ProductionPrefCacheEnvironment,
                TestConstants.ClientId,
                MockHelpers.CreateIdToken(TestConstants.UniqueId + "more", TestConstants.DisplayableId),
                clientInfo,
                homeAccountId,
                TestConstants.Utid);

            accessor.SaveIdToken(idTokenCacheItem);

            MsalAccountCacheItem accountCacheItem = new MsalAccountCacheItem(
                TestConstants.ProductionPrefNetworkEnvironment,
                null,
                clientInfo,
                homeAccountId,
                null,
                null,
                TestConstants.Utid,
                null,
                null,
                null);

            accessor.SaveAccount(accountCacheItem);
            AddRefreshTokenToCache(accessor, TestConstants.Uid, TestConstants.Utid);
        }
        public static void WriteMsalRefreshToken(ITokenCacheAccessor tokenCacheAccessor,
                                                 AdalResultWrapper resultWrapper, string authority, string clientId, string displayableId,
                                                 string givenName, string familyName, string objectId)
        {
            if (string.IsNullOrEmpty(resultWrapper.RawClientInfo))
            {
                MsalLogger.Default.Info("Client Info is missing. Skipping MSAL refresh token cache write");
                return;
            }

            if (string.IsNullOrEmpty(resultWrapper.RefreshToken))
            {
                MsalLogger.Default.Info("Refresh Token is missing. Skipping MSAL refresh token cache write");
                return;
            }

            if (string.IsNullOrEmpty(resultWrapper.Result.IdToken))
            {
                MsalLogger.Default.Info("Id Token is missing. Skipping MSAL refresh token cache write");
                return;
            }

            try
            {
                var rtItem = new MsalRefreshTokenCacheItem
                                 (new Uri(authority).Host, clientId, resultWrapper.RefreshToken, resultWrapper.RawClientInfo);
                tokenCacheAccessor.SaveRefreshToken(rtItem);

                MsalAccountCacheItem accountCacheItem = new MsalAccountCacheItem
                                                            (new Uri(authority).Host, objectId, resultWrapper.RawClientInfo, null, displayableId, resultWrapper.Result.TenantId,
                                                            givenName, familyName);
                tokenCacheAccessor.SaveAccount(accountCacheItem);
            }
            catch (Exception ex)
            {
                MsalLogger.Default.WarningPiiWithPrefix(
                    ex,
                    "An error occurred while writing ADAL refresh token to the cache in MSAL format. "
                    + "For details please see https://aka.ms/net-cache-persistence-errors. ");
            }
        }
        private static MsalAccessTokenCacheItem UpdateATWithRefreshOn(
            ITokenCacheAccessor accessor,
            DateTimeOffset refreshOn,
            bool expired = false)
        {
            MsalAccessTokenCacheItem atItem = accessor.GetAllAccessTokens().Single();

            // past date on refresh on
            atItem.RefreshOnUnixTimestamp = CoreHelpers.DateTimeToUnixTimestamp(refreshOn);

            Assert.IsTrue(atItem.ExpiresOn > DateTime.UtcNow + TimeSpan.FromMinutes(10));

            if (expired)
            {
                atItem.ExpiresOnUnixTimestamp = CoreHelpers.DateTimeToUnixTimestamp(DateTime.UtcNow - TimeSpan.FromMinutes(1));
            }

            accessor.SaveAccessToken(atItem);

            return(atItem);
        }
Example #25
0
        internal TokenCache(IServiceBundle serviceBundle, bool isApplicationTokenCache, ICacheSerializationProvider optionalDefaultSerializer = null)
        {
            var proxy = serviceBundle?.PlatformProxy ?? PlatformProxyFactory.CreatePlatformProxy(null);

            _accessor     = proxy.CreateTokenCacheAccessor();
            _featureFlags = proxy.GetFeatureFlags();

            _usesDefaultSerialization = optionalDefaultSerializer != null;
            optionalDefaultSerializer?.Initialize(this);

            LegacyCachePersistence = proxy.CreateLegacyCachePersistence();

#if iOS
            SetIosKeychainSecurityGroup(serviceBundle.Config.IosKeychainSecurityGroup);
#endif // iOS

            IsAppTokenCache = isApplicationTokenCache;

            // Must happen last, this code can access things like _accessor and such above.
            ServiceBundle = serviceBundle;
        }
Example #26
0
        private static MsalAccessTokenCacheItem UpdateATWithRefreshOn(
            ITokenCacheAccessor accessor,
            DateTimeOffset?refreshOn = null,
            bool expired             = false)
        {
            MsalAccessTokenCacheItem atItem = accessor.GetAllAccessTokens().Single();

            refreshOn = refreshOn ?? DateTimeOffset.UtcNow - TimeSpan.FromMinutes(30);
            atItem    = atItem.WithRefreshOn(refreshOn);

            Assert.IsTrue(atItem.ExpiresOn > DateTime.UtcNow + TimeSpan.FromMinutes(10));

            if (expired)
            {
                atItem = atItem.WithExpiresOn(DateTime.UtcNow - TimeSpan.FromMinutes(1));
            }

            accessor.SaveAccessToken(atItem);

            return(atItem);
        }
Example #27
0
 public TokenCacheDictionarySerializer(ITokenCacheAccessor accessor)
 {
     _accessor = accessor;
 }
Example #28
0
        internal void PopulateCache(
            ITokenCacheAccessor accessor,
            string uid      = MsalTestConstants.Uid,
            string utid     = MsalTestConstants.Utid,
            string clientId = MsalTestConstants.ClientId)
        {
            MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem(
                MsalTestConstants.ProductionPrefCacheEnvironment,
                clientId,
                MsalTestConstants.Scope.AsSingleString(),
                utid,
                "",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn)),
                MockHelpers.CreateClientInfo(uid, utid));

            // add access token
            accessor.SaveAccessToken(atItem);

            var idTokenCacheItem = new MsalIdTokenCacheItem(
                MsalTestConstants.ProductionPrefCacheEnvironment,
                clientId,
                MockHelpers.CreateIdToken(MsalTestConstants.UniqueId + "more", MsalTestConstants.DisplayableId),
                MockHelpers.CreateClientInfo(uid, utid),
                utid);

            accessor.SaveIdToken(idTokenCacheItem);

            var accountCacheItem = new MsalAccountCacheItem(
                MsalTestConstants.ProductionPrefCacheEnvironment,
                null,
                MockHelpers.CreateClientInfo(uid, utid),
                null,
                MsalTestConstants.DisplayableId,
                utid,
                null,
                null);

            accessor.SaveAccount(accountCacheItem);

            atItem = new MsalAccessTokenCacheItem(
                MsalTestConstants.ProductionPrefCacheEnvironment,
                clientId,
                MsalTestConstants.ScopeForAnotherResource.AsSingleString(),
                utid,
                "",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn)),
                MockHelpers.CreateClientInfo(uid, utid));

            // add another access token
            accessor.SaveAccessToken(atItem);

            AddRefreshTokenToCache(accessor, uid, utid, clientId);

            var appMetadataItem = new MsalAppMetadataCacheItem(
                clientId,
                MsalTestConstants.ProductionPrefCacheEnvironment,
                null);

            accessor.SaveAppMetadata(appMetadataItem);
        }
Example #29
0
        internal void PopulateCacheForClientCredential(ITokenCacheAccessor accessor)
        {
            var atItem = CreateAccessTokenItem();

            accessor.SaveAccessToken(atItem);
        }
        internal void PopulateCache(
            ITokenCacheAccessor accessor,
            string uid               = TestConstants.Uid,
            string utid              = TestConstants.Utid,
            string clientId          = TestConstants.ClientId,
            string environment       = TestConstants.ProductionPrefCacheEnvironment,
            string displayableId     = TestConstants.DisplayableId,
            string rtSecret          = TestConstants.RTSecret,
            string overridenScopes   = null,
            bool expiredAccessTokens = false,
            bool addSecondAt         = true)
        {
            string clientInfo = MockHelpers.CreateClientInfo(uid, utid);
            string homeAccId  = ClientInfo.CreateFromJson(clientInfo).ToAccountIdentifier();

            var accessTokenExpiresOn = expiredAccessTokens ?
                                       new DateTimeOffset(DateTime.UtcNow) :
                                       new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn));

            var extendedAccessTokenExpiresOn = expiredAccessTokens ?
                                               new DateTimeOffset(DateTime.UtcNow) :
                                               new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExtendedExpiresIn));

            MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem(
                environment,
                clientId,
                overridenScopes ?? TestConstants.s_scope.AsSingleString(),
                utid,
                "",
                accessTokenExpiresOn,
                extendedAccessTokenExpiresOn,
                clientInfo,
                homeAccId);

            // add access token
            accessor.SaveAccessToken(atItem);

            var idTokenCacheItem = new MsalIdTokenCacheItem(
                environment,
                clientId,
                MockHelpers.CreateIdToken(TestConstants.UniqueId + "more", displayableId),
                clientInfo,
                homeAccId,
                tenantId: utid);

            accessor.SaveIdToken(idTokenCacheItem);

            // add another access token
            if (addSecondAt)
            {
                atItem = new MsalAccessTokenCacheItem(
                    environment,
                    clientId,
                    TestConstants.s_scopeForAnotherResource.AsSingleString(),
                    utid,
                    "",
                    accessTokenExpiresOn,
                    extendedAccessTokenExpiresOn,
                    clientInfo,
                    homeAccId);

                accessor.SaveAccessToken(atItem);
            }

            var accountCacheItem = new MsalAccountCacheItem(
                environment,
                null,
                clientInfo,
                homeAccId,
                null,
                displayableId,
                utid,
                null,
                null);

            accessor.SaveAccount(accountCacheItem);

            AddRefreshTokenToCache(accessor, uid, utid, clientId, environment, rtSecret);

            var appMetadataItem = new MsalAppMetadataCacheItem(
                clientId,
                environment,
                null);

            accessor.SaveAppMetadata(appMetadataItem);
        }