TokenCacheKey can be used with Linq to access items from the TokenCache dictionary.
        public void ConstructorInitCombinations()
        {
            //no policy, user properties
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId);
            this.ValidateTokenCacheKey(key, true);

            //with policy, user properties
            key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            this.ValidateTokenCacheKey(key, false);


            User user = new User();
            user.DisplayableId = TestConstants.DefaultDisplayableId;
            user.UniqueId = TestConstants.DefaultUniqueId;
            user.HomeObjectId = TestConstants.DefaultHomeObjectId;

            //no policy, user object
            key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId, user);
            this.ValidateTokenCacheKey(key, true);

            //with policy, user object
            key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId, user,
                TestConstants.DefaultPolicy);
            this.ValidateTokenCacheKey(key, false);

        }
 /// <summary>
 /// Determines whether the specified TokenCacheKey is equal to the current object.
 /// </summary>
 /// <returns>
 /// true if the specified TokenCacheKey is equal to the current object; otherwise, false.
 /// </returns>
 /// <param name="other">The TokenCacheKey to compare with the current object. </param><filterpriority>2</filterpriority>
 public bool Equals(TokenCacheKey other)
 {
     return(ReferenceEquals(this, other) ||
            (other != null &&
             (other.Authority == this.Authority) &&
             this.ScopeEquals(other.Scope) &&
             this.Equals(this.ClientId, other.ClientId) &&
             (other.UniqueId == this.UniqueId) &&
             this.Equals(this.DisplayableId, other.DisplayableId) &&
             (this.HomeObjectId == other.HomeObjectId) &&
             this.Equals(this.Policy, other.Policy)));
 }
        private void ValidateTokenCacheKey(TokenCacheKey key, bool policyMissing)
        {
            Assert.IsNotNull(key);
            Assert.AreEqual(TestConstants.DefaultAuthorityHomeTenant, key.Authority);
            Assert.AreEqual(TestConstants.DefaultScope, key.Scope);
            Assert.AreEqual(TestConstants.DefaultClientId, key.ClientId);
            Assert.AreEqual(TestConstants.DefaultUniqueId, key.UniqueId);
            Assert.AreEqual(TestConstants.DefaultDisplayableId, key.DisplayableId);
            Assert.AreEqual(TestConstants.DefaultHomeObjectId, key.HomeObjectId);
            Assert.AreEqual(policyMissing, key.Policy == null);

            if (!policyMissing)
            {
                Assert.AreEqual(TestConstants.DefaultPolicy, key.Policy);
            }
        }
        /// <summary>
        ///     Default constructor.
        /// </summary>
        internal TokenCacheItem(TokenCacheKey key, AuthenticationResult result)
        {
            this.Authority = key.Authority;
            this.Scope = key.Scope;
            this.ClientId = key.ClientId;
            this.UniqueId = key.UniqueId;
            this.DisplayableId = key.DisplayableId;
            this.HomeObjectId = key.HomeObjectId;
            this.TenantId = result.TenantId;
            this.ExpiresOn = result.ExpiresOn;
            this.Token = result.Token;
            this.User = result.User;
            this.Policy = key.Policy;

            if (result.User!= null)
            {
                this.Name = result.User.Name;
            }
        }
        public static TokenCache CreateCacheWithItems()
        {
            TokenCache cache = new TokenCache();
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.DefaultScope;

            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            key = new TokenCacheKey(TestConstants.DefaultAuthorityGuestTenant,
                TestConstants.ScopeForAnotherResource, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId + "more", TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId + "more",
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.ScopeForAnotherResource;
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            return cache;
        }
        public void LoadFromCacheExpiredToken()
        {
            TokenCache cache = new TokenCache();
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(), new DateTimeOffset(DateTime.UtcNow));
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            AuthenticationResultEx resultEx = cache.LoadFromCache(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUser,
                TestConstants.DefaultPolicy, null);
            Assert.IsNotNull(resultEx);
            Assert.IsNotNull(resultEx.Result);
            Assert.IsNull(resultEx.Result.Token);
            Assert.AreEqual(resultEx.RefreshToken, "someRT");
        }
 private static void AddToDictionary(TokenCache tokenCache, TokenCacheKey key, AuthenticationResultEx value)
 {
     tokenCache.OnBeforeAccess(new TokenCacheNotificationArgs {TokenCache = tokenCache});
     tokenCache.OnBeforeWrite(new TokenCacheNotificationArgs {TokenCache = tokenCache});
     tokenCache.tokenCacheDictionary.Add(key, value);
     tokenCache.HasStateChanged = true;
     tokenCache.OnAfterAccess(new TokenCacheNotificationArgs {TokenCache = tokenCache});
 }
        private static bool RemoveFromDictionary(TokenCache tokenCache, TokenCacheKey key)
        {
            tokenCache.OnBeforeAccess(new TokenCacheNotificationArgs {TokenCache = tokenCache});
            tokenCache.OnBeforeWrite(new TokenCacheNotificationArgs {TokenCache = tokenCache});
            bool result = tokenCache.tokenCacheDictionary.Remove(key);
            tokenCache.HasStateChanged = true;
            tokenCache.OnAfterAccess(new TokenCacheNotificationArgs {TokenCache = tokenCache});

            return result;
        }
        private static void VerifyCacheItems(TokenCache cache, int expectedCount, TokenCacheKey firstKey,
            TokenCacheKey secondKey)
        {
            var items = cache.ReadItems(TestConstants.DefaultClientId).ToList();
            Assert.AreEqual(expectedCount, items.Count);

            if (firstKey != null)
            {
                Assert.IsTrue(AreEqual(items[0], firstKey) || AreEqual(items[0], secondKey));
            }

            if (secondKey != null)
            {
                Assert.IsTrue(AreEqual(items[1], firstKey) || AreEqual(items[1], secondKey));
            }
        }
 private static bool AreEqual(TokenCacheItem item, TokenCacheKey key)
 {
     return item.Match(key);
 }
コード例 #11
0
        internal void StoreToCache(AuthenticationResultEx resultEx, string authority, string clientId,
            string policy, bool restrictToSingleUser, CallState callState)
        {
            lock (lockObject)
            {
                PlatformPlugin.Logger.Verbose(callState, "Storing token in the cache...");

                //single user mode cannot allow more than 1 unique id in the cache including null
                if (restrictToSingleUser &&
                    (resultEx.Result.User == null || string.IsNullOrEmpty(resultEx.Result.User.UniqueId) ||
                     !this.GetUniqueIdsFromCache(clientId).Contains(resultEx.Result.User.UniqueId)))
                {
                    throw new MsalException(MsalError.InvalidCacheOperation,
                        "Cannot add more than 1 user with a different unique id when RestrictToSingleUser is set to TRUE.");
                }

                this.OnBeforeWrite(new TokenCacheNotificationArgs
                {
                    Scope = resultEx.Result.Scope,
                    ClientId = clientId,
                    User = resultEx.Result.User,
                    Policy = policy
                });

                TokenCacheKey tokenCacheKey = new TokenCacheKey(authority, resultEx.Result.ScopeSet, clientId,
                    resultEx.Result.User, policy);
                // First identify all potential tokens.
                List<KeyValuePair<TokenCacheKey, AuthenticationResultEx>> items = this.QueryCache(authority, clientId,
                    resultEx.Result.User, policy);
                List<KeyValuePair<TokenCacheKey, AuthenticationResultEx>> itemsToRemove =
                    items.Where(p => p.Key.ScopeIntersects(resultEx.Result.ScopeSet)).ToList();

                if (!itemsToRemove.Any())
                {
                    this.tokenCacheDictionary[tokenCacheKey] = resultEx;
                    PlatformPlugin.Logger.Verbose(callState, "An item was stored in the cache");
                }
                else
                {
                    //remove all intersections
                    PlatformPlugin.Logger.Verbose(callState, "Items to remove - " + itemsToRemove.Count);
                    foreach (var itemToRemove in itemsToRemove)
                    {
                        this.tokenCacheDictionary.Remove(itemToRemove);
                    }

                    this.tokenCacheDictionary[tokenCacheKey] = resultEx;
                    PlatformPlugin.Logger.Verbose(callState, "An item was updated in the cache");
                }

                this.UpdateCachedRefreshTokens(resultEx, authority, clientId, policy);
                this.HasStateChanged = true;
            }
        }
 private static void VerifyCacheItems(TokenCache cache, int expectedCount, TokenCacheKey firstKey)
 {
     VerifyCacheItems(cache, expectedCount, firstKey, null);
 }
 /// <summary>
 /// Determines whether the specified TokenCacheKey is equal to the current object.
 /// </summary>
 /// <returns>
 /// true if the specified TokenCacheKey is equal to the current object; otherwise, false.
 /// </returns>
 /// <param name="other">The TokenCacheKey to compare with the current object. </param><filterpriority>2</filterpriority>
 public bool Equals(TokenCacheKey other)
 {
     return ReferenceEquals(this, other) ||
            (other != null
             && (other.Authority == this.Authority)
             && this.ScopeEquals(other.Scope)
             && this.Equals(this.ClientId, other.ClientId)
             && (other.UniqueId == this.UniqueId)
             && this.Equals(this.DisplayableId, other.DisplayableId)
             && (this.HomeObjectId == other.HomeObjectId)
             && this.Equals(this.Policy, other.Policy));
 }
        /// <summary>
        /// Determines whether the specified object is equal to the current object.
        /// </summary>
        /// <returns>
        /// true if the specified object is equal to the current object; otherwise, false.
        /// </returns>
        /// <param name="obj">The object to compare with the current object. </param><filterpriority>2</filterpriority>
        public override bool Equals(object obj)
        {
            TokenCacheKey other = obj as TokenCacheKey;

            return((other != null) && this.Equals(other));
        }
        public void LoadSingleItemFromCacheIntersectingScopeDifferentAuthorities()
        {
            TokenCache cache = TokenCacheHelper.CreateCacheWithItems();
            HashSet<string> scope = new HashSet<string>(new[] {"r1/scope1"});

            KeyValuePair<TokenCacheKey, AuthenticationResultEx>? item =
                cache.LoadSingleItemFromCache(TestConstants.DefaultAuthorityHomeTenant,
                    scope, TestConstants.DefaultClientId,
                    TestConstants.DefaultUser,
                    TestConstants.DefaultPolicy, null);
            Assert.IsNotNull(item);
            TokenCacheKey key = item.Value.Key;
            AuthenticationResultEx resultEx = item.Value.Value;

            Assert.AreEqual(TestConstants.DefaultAuthorityHomeTenant, key.Authority);
            Assert.AreEqual(TestConstants.DefaultScope, key.Scope);
            Assert.AreEqual(TestConstants.DefaultClientId, key.ClientId);
            Assert.AreEqual(TestConstants.DefaultUniqueId, key.UniqueId);
            Assert.AreEqual(TestConstants.DefaultDisplayableId, key.DisplayableId);
            Assert.AreEqual(TestConstants.DefaultHomeObjectId, key.HomeObjectId);
            Assert.AreEqual(TestConstants.DefaultPolicy, key.Policy);
            Assert.AreEqual(key.ToString(), resultEx.Result.Token);

            scope.Add("unique-scope");
            item = cache.LoadSingleItemFromCache(TestConstants.DefaultAuthorityHomeTenant,
                scope, TestConstants.DefaultClientId,
                TestConstants.DefaultUser,
                TestConstants.DefaultPolicy, null);

            Assert.IsNotNull(item);
            key = item.Value.Key;
            resultEx = item.Value.Value;

            Assert.AreEqual(TestConstants.DefaultAuthorityHomeTenant, key.Authority);
            Assert.AreEqual(TestConstants.DefaultScope, key.Scope); //default scope contains r1/scope1
            Assert.AreEqual(TestConstants.DefaultClientId, key.ClientId);
            Assert.AreEqual(TestConstants.DefaultUniqueId, key.UniqueId);
            Assert.AreEqual(TestConstants.DefaultDisplayableId, key.DisplayableId);
            Assert.AreEqual(TestConstants.DefaultHomeObjectId, key.HomeObjectId);
            Assert.AreEqual(TestConstants.DefaultPolicy, key.Policy);
            Assert.AreEqual(key.ToString(), resultEx.Result.Token);


            //invoke multiple tokens error
            TokenCacheKey cacheKey = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId + "more", TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[cacheKey] = ex;

            try
            {
                User user = TestConstants.DefaultUser;
                user.DisplayableId = null;

                item = cache.LoadSingleItemFromCache(TestConstants.DefaultAuthorityHomeTenant,
                    TestConstants.DefaultScope, TestConstants.DefaultClientId, user,
                    TestConstants.DefaultPolicy, null);
                Assert.Fail("multiple tokens should have been detected");
            }
            catch (MsalException exception)
            {
                Assert.AreEqual("multiple_matching_tokens_detected", exception.ErrorCode);
            }
        }
        public void ActAsCurrentUserNoSsoHeaderForLoginHintOnlyTest()
        {
            //this test validates that no SSO header is added when developer passes only login hint and UiOption.ActAsCurrentUser
            Authenticator authenticator = new Authenticator(TestConstants.DefaultAuthorityHomeTenant, false, Guid.NewGuid());
            TokenCache cache = new TokenCache();
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3599)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            MockWebUI webUi = new MockWebUI();
            webUi.MockResult = new AuthorizationResult(AuthorizationStatus.Success,
                TestConstants.DefaultAuthorityHomeTenant + "?code=some-code");

            AuthenticationRequestParameters parameters = new AuthenticationRequestParameters()
            {
                Authenticator = authenticator,
                ClientKey = new ClientKey(TestConstants.DefaultClientId),
                Policy = TestConstants.DefaultPolicy,
                RestrictToSingleUser = TestConstants.DefaultRestrictToSingleUser,
                Scope = TestConstants.DefaultScope.ToArray(),
                TokenCache = cache
            };

            InteractiveRequest request = new InteractiveRequest(parameters,
                TestConstants.ScopeForAnotherResource.ToArray(),
                new Uri("some://uri"), new PlatformParameters(),
                ex.Result.User, UiOptions.ActAsCurrentUser, "extra=qp", webUi);
            request.PreRunAsync().Wait();
            request.PreTokenRequest().Wait();
        }
        public void LoadSingleItemFromCacheNullUserSingleUniqueIdInCacheTest()
        {
            TokenCache cache = new TokenCache();

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            KeyValuePair<TokenCacheKey, AuthenticationResultEx>? item =
                cache.LoadSingleItemFromCache(TestConstants.DefaultAuthorityCommonTenant,
                    TestConstants.DefaultScope, TestConstants.DefaultClientId,
                    null,
                    TestConstants.DefaultPolicy, null);
            Assert.IsNotNull(item);

            Assert.AreEqual(TestConstants.DefaultAuthorityHomeTenant, key.Authority);
            Assert.AreEqual(TestConstants.DefaultScope, key.Scope);
            Assert.AreEqual(TestConstants.DefaultClientId, key.ClientId);
            Assert.AreEqual(TestConstants.DefaultUniqueId, key.UniqueId);
            Assert.AreEqual(TestConstants.DefaultDisplayableId, key.DisplayableId);
            Assert.AreEqual(TestConstants.DefaultHomeObjectId, key.HomeObjectId);
            Assert.AreEqual(TestConstants.DefaultPolicy, key.Policy);
        }
        public void LoadFromCacheCrossTenantNullUserToken()
        {
            //this test will result only in a RT and no access token returned.
            TokenCache tokenCache = TokenCacheHelper.CreateCacheWithItems();

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId + "more", TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            tokenCache.tokenCacheDictionary[key] = ex;

            try
            {
                AuthenticationResultEx resultEx =
                    tokenCache.LoadFromCache(TestConstants.DefaultAuthorityHomeTenant, TestConstants.DefaultScope,
                        TestConstants.DefaultClientId, null, TestConstants.DefaultPolicy, null);
                Assert.Fail("multiple tokens should have been detected");
            }
            catch (MsalException exception)
            {
                Assert.AreEqual("multiple_matching_tokens_detected", exception.ErrorCode);
            }
        }
        public void LoadFromCacheNullUserSingleEntry()
        {
            var tokenCache = new TokenCache();
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            tokenCache.tokenCacheDictionary[key] = ex;

            AuthenticationResultEx resultEx = tokenCache.LoadFromCache(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope,
                TestConstants.DefaultClientId, null,
                TestConstants.DefaultPolicy, null);
            Assert.IsNotNull(resultEx);
            Assert.IsNotNull(resultEx.Result);
            Assert.IsNotNull(resultEx.Result.Token);
        }
 internal bool Match(TokenCacheKey key)
 {
     return key != null &&
            (key.Authority == this.Authority && key.ScopeEquals(this.Scope) &&
             key.Equals(key.ClientId, this.ClientId)
             && key.UniqueId == this.UniqueId &&
             key.Equals(key.DisplayableId, this.DisplayableId) && (key.HomeObjectId == this.HomeObjectId) &&
             key.Equals(key.Policy, this.Policy));
 }
コード例 #21
0
        /// <summary>
        ///     Deserializes state of the cache. The state should be the blob received earlier by calling the method Serialize.
        /// </summary>
        /// <param name="state">State of the cache as a blob</param>
        public void Deserialize(byte[] state)
        {
            lock (lockObject)
            {
                if (state == null || state.Length == 0)
                {
                    this.tokenCacheDictionary.Clear();
                    return;
                }

                using (Stream stream = new MemoryStream())
                {
                    BinaryWriter writer = new BinaryWriter(stream);
                    writer.Write(state);
                    writer.Flush();
                    stream.Position = 0;

                    BinaryReader reader = new BinaryReader(stream);
                    int schemaVersion = reader.ReadInt32();
                    if (schemaVersion != SchemaVersion)
                    {
                        PlatformPlugin.Logger.Warning(null,
                            "The version of the persistent state of the cache does not match the current schema, so skipping deserialization.");
                        return;
                    }

                    this.tokenCacheDictionary.Clear();
                    int count = reader.ReadInt32();
                    for (int n = 0; n < count; n++)
                    {
                        string keyString = reader.ReadString();

                        string[] kvpElements = keyString.Split(new[] {Delimiter}, StringSplitOptions.None);
                        AuthenticationResultEx resultEx = AuthenticationResultEx.Deserialize(reader.ReadString());

                        TokenCacheKey key = new TokenCacheKey(kvpElements[0],
                            kvpElements[1].AsSet(), kvpElements[2], resultEx.Result.User, kvpElements[3]);

                        this.tokenCacheDictionary.Add(key, resultEx);
                    }

                    PlatformPlugin.Logger.Information(null,
                        string.Format(CultureInfo.InvariantCulture,"Deserialized {0} items to token cache.", count));
                }
            }
        }
        public void TestEquals()
        {
            TokenCacheKey key1 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);

            TokenCacheKey key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsTrue(key1.Equals(key2));

            //scope
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.ScopeForAnotherResource, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            //different case scope
            HashSet<string> uppercaseScope = new HashSet<string>();
            foreach (var item in TestConstants.DefaultScope)
            {
                uppercaseScope.Add(item.ToUpper(CultureInfo.InvariantCulture));
            }

            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                uppercaseScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsTrue(key1.Equals(key2));

            //authority
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant + "more",
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            key2 = new TokenCacheKey(null,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            //null scope
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                null, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            //client id
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, null,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId + "more",
               
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            //unique id
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                null, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId, TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId + "more", TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            //displayable id
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, null, TestConstants.DefaultHomeObjectId, TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId + "more", TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            //root id
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, null, TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId + "more",
                TestConstants.DefaultPolicy);
            Assert.IsFalse(key1.Equals(key2));

            //policy
            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId, null);
            Assert.IsFalse(key1.Equals(key2));

            key2 = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy + "more");
            Assert.IsFalse(key1.Equals(key2));

            // mistmatched object
            Assert.IsFalse(key1.Equals(new object()));
        }
        public void TestScopeContains()
        {
            //null scope
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                null, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);

            //null will contain null
            HashSet<string> otherScope = null;
            Assert.IsTrue(key.ScopeContains(otherScope));
            Assert.IsFalse(key.ScopeContains(new HashSet<string>()));

            //put scope value
            key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            Assert.IsTrue(key.ScopeContains(otherScope));
            Assert.IsTrue(key.ScopeContains(new HashSet<string>()));

            otherScope = new HashSet<string>(TestConstants.DefaultScope.ToArray());
            Assert.IsTrue(key.ScopeContains(otherScope));

            // other scope has more
            otherScope.Add("anotherscope");
            Assert.IsFalse(key.ScopeContains(otherScope));
        }
        public void LoadSingleItemFromCacheCrossTenantLookupTest()
        {
            var tokenCache = new TokenCache();

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            tokenCache.tokenCacheDictionary[key] = ex;

            User user = TestConstants.DefaultUser;
            user.DisplayableId = null;
            user.UniqueId = null;

            //cross-tenant works by default. search cache using non-existant authority
            //using root id. Code will find multiple results with the same root id. it can return any.
            KeyValuePair<TokenCacheKey, AuthenticationResultEx>? item =
                tokenCache.LoadSingleItemFromCache(TestConstants.DefaultAuthorityGuestTenant + "non-existant",
                    new HashSet<string>(new[] {"scope1", "random-scope"}),
                    TestConstants.DefaultClientId, user, TestConstants.DefaultPolicy, null);
            Assert.IsNotNull(item);
            key = item.Value.Key;
            AuthenticationResultEx resultEx = item.Value.Value;

            Assert.AreEqual(TestConstants.DefaultAuthorityHomeTenant, key.Authority);
            Assert.AreEqual(TestConstants.DefaultScope, key.Scope);
            Assert.AreEqual(TestConstants.DefaultClientId, key.ClientId);
            Assert.AreEqual(TestConstants.DefaultUniqueId, key.UniqueId);
            Assert.AreEqual(TestConstants.DefaultDisplayableId, key.DisplayableId);
            Assert.AreEqual(TestConstants.DefaultHomeObjectId, key.HomeObjectId);
            Assert.AreEqual(TestConstants.DefaultPolicy, key.Policy);
            Assert.AreEqual(key.ToString(), resultEx.Result.Token);
        }
コード例 #25
0
        private AuthenticationResultEx CreateResultExFromCacheResultEx(TokenCacheKey key, AuthenticationResultEx resultEx)
        {
            var newResultEx = new AuthenticationResultEx
            {
                Result = new AuthenticationResult(null, null, DateTimeOffset.MinValue)
                {
                    ScopeSet = new HashSet<string>(resultEx.Result.ScopeSet.ToArray())
                },
                RefreshToken = resultEx.RefreshToken,
            };

            newResultEx.Result.UpdateTenantAndUser(resultEx.Result.TenantId, resultEx.Result.IdToken,
                resultEx.Result.User);

            if (newResultEx.Result.User != null)
            {
                newResultEx.Result.User.Authority = key.Authority;
                newResultEx.Result.User.ClientId = key.ClientId;
                newResultEx.Result.User.TokenCache = this;
            }

            return newResultEx;
        }
        public void NoCacheLookup()
        {
            Authenticator authenticator = new Authenticator(TestConstants.DefaultAuthorityHomeTenant, false, Guid.NewGuid());
            TokenCache cache = new TokenCache();
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3599)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            IWebUI ui = Substitute.For<IWebUI>();
            AuthorizationResult ar = new AuthorizationResult(AuthorizationStatus.Success,
                TestConstants.DefaultAuthorityHomeTenant + "?code=some-code");
            ui.AcquireAuthorizationAsync(Arg.Any<Uri>(), Arg.Any<Uri>(), Arg.Any<IDictionary<string, string>>(),
                Arg.Any<CallState>())
                .Returns(ar);

            MockHttpMessageHandler mockHandler = new MockHttpMessageHandler();
            mockHandler.Method = HttpMethod.Post;
            mockHandler.QueryParams = new Dictionary<string, string>() {{"p", "some-policy"}};

            mockHandler.ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage();
            HttpMessageHandlerFactory.MockHandler = mockHandler;

            AuthenticationRequestParameters parameters = new AuthenticationRequestParameters()
            {
                Authenticator = authenticator,
                ClientKey = new ClientKey(TestConstants.DefaultClientId),
                Policy = "some-policy",
                RestrictToSingleUser = TestConstants.DefaultRestrictToSingleUser,
                Scope = TestConstants.DefaultScope.ToArray(),
                TokenCache = cache
            };

            InteractiveRequest request = new InteractiveRequest(parameters,
                TestConstants.ScopeForAnotherResource.ToArray(),
                new Uri("some://uri"), new PlatformParameters(), TestConstants.DefaultDisplayableId,
                UiOptions.SelectAccount, "extra=qp", ui);
            Task<AuthenticationResult> task = request.RunAsync();
            task.Wait();
            AuthenticationResult result = task.Result;
            Assert.IsNotNull(result);
            Assert.AreEqual(2, cache.Count);
            Assert.AreEqual(result.Token, "some-access-token");

            //both cache entry authorities are TestConstants.DefaultAuthorityHomeTenant
            foreach (var item in cache.ReadItems(TestConstants.DefaultClientId))
            {
                Assert.AreEqual(TestConstants.DefaultAuthorityHomeTenant, item.Authority);
            }
        }
        public void ClearCacheTest()
        {
            TokenCache tokenCache = TokenCacheHelper.CreateCacheWithItems();

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId + "more",
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            tokenCache.tokenCacheDictionary[key] = ex;

            tokenCache.Clear(TestConstants.DefaultClientId);
            Assert.AreEqual(1, tokenCache.Count);
            Assert.AreEqual(key, tokenCache.tokenCacheDictionary.Keys.First());
        }
        public void MapToIdentifierMultipleMatchingEntriesTest()
        {
            Authenticator authenticator = new Authenticator(TestConstants.DefaultAuthorityHomeTenant, false,
                Guid.NewGuid());
            TokenCache cache = TokenCacheHelper.CreateCacheWithItems();

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.ScopeForAnotherResource, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3600)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.DefaultScope;

            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            cache.tokenCacheDictionary[key] = ex;


            AuthenticationRequestParameters parameters = new AuthenticationRequestParameters()
            {
                Authenticator = authenticator,
                ClientKey = new ClientKey(TestConstants.DefaultClientId),
                Policy = TestConstants.DefaultPolicy,
                RestrictToSingleUser = TestConstants.DefaultRestrictToSingleUser,
                Scope = new[] { "something" },
                TokenCache = cache
            };

            SilentRequest request = new SilentRequest(parameters, (string) null,
                new PlatformParameters(), false);
            User user = request.MapIdentifierToUser(TestConstants.DefaultUniqueId);
            Assert.IsNotNull(user);
            Assert.AreEqual(TestConstants.DefaultUniqueId, user.UniqueId);
        }
        public void StoreToCacheNewUserRestrictToSingleUserTrueTest()
        {
            var tokenCache = new TokenCache();

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            tokenCache.tokenCacheDictionary[key] = ex;
            
            var result = new AuthenticationResult("Bearer", "some-access-token",
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)))
            {
                User =
                    new User
                    {
                        UniqueId = TestConstants.DefaultUniqueId+"more",
                        DisplayableId = TestConstants.DefaultDisplayableId
                    },
                ScopeSet = new HashSet<string>(new string[] { "r1/scope5", "r1/scope7" })
            };

            AuthenticationResultEx resultEx = new AuthenticationResultEx
            {
                Result = result,
                RefreshToken = "someRT"
            };
            try
            {
                tokenCache.StoreToCache(resultEx, TestConstants.DefaultAuthorityGuestTenant, TestConstants.DefaultClientId,
                    TestConstants.DefaultPolicy, true, null);
                Assert.Fail("MsalException should be thrown here");
            }
            catch (MsalException me)
            {
                Assert.AreEqual(MsalError.InvalidCacheOperation, me.ErrorCode);
                Assert.AreEqual("Cannot add more than 1 user with a different unique id when RestrictToSingleUser is set to TRUE.", me.Message);
            }
        }
        public void GetUsersTest()
        {
            PublicClientApplication app = new PublicClientApplication(TestConstants.DefaultClientId);
            IEnumerable<User> users = app.Users;
            Assert.IsNotNull(users);
            Assert.IsFalse(users.Any());
            app.UserTokenCache = TokenCacheHelper.CreateCacheWithItems();
            users = app.Users;
            Assert.IsNotNull(users);
            Assert.AreEqual(1, users.Count());
            foreach (var user in users)
            {
                Assert.AreEqual(TestConstants.DefaultClientId, user.ClientId);
                Assert.IsNotNull(user.TokenCache);
            }

            // another cache entry for different home object id. user count should be 2.
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.ScopeForAnotherResource, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId+"more",
                TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3600)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId = TestConstants.DefaultUniqueId,
                HomeObjectId = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.DefaultScope;

            ex.Result.FamilyId = "1";
            ex.RefreshToken = "someRT";
            app.UserTokenCache.tokenCacheDictionary[key] = ex;

            users = app.Users;
            Assert.IsNotNull(users);
            Assert.AreEqual(2, users.Count());
            foreach (var user in users)
            {
                Assert.AreEqual(TestConstants.DefaultClientId, user.ClientId);
                Assert.IsNotNull(user.TokenCache);
            }
        }
        public void TestScopeEquals()
        {

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                TestConstants.DefaultScope, TestConstants.DefaultClientId,
                TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                TestConstants.DefaultPolicy);

            HashSet<string> otherScope = null;
            Assert.IsFalse(key.ScopeEquals(otherScope));

            otherScope = new HashSet<string>(TestConstants.DefaultScope.ToArray());
            Assert.IsTrue(key.ScopeEquals(otherScope));

            otherScope.Add("anotherscope");
            Assert.IsFalse(key.ScopeEquals(otherScope));

            otherScope.Clear();
            Assert.IsFalse(key.ScopeEquals(otherScope));
        }