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)); }
internal virtual AuthenticationResultEx LoadFromCache(string authority, HashSet <string> scope, string clientId, User user, string policy, CallState callState) { lock (lockObject) { PlatformPlugin.Logger.Verbose(callState, "Looking up cache for a token..."); AuthenticationResultEx resultEx = null; //get either a matching token or an MRRT supported RT KeyValuePair <TokenCacheKey, AuthenticationResultEx>?kvp = this.LoadSingleItemFromCache(authority, scope, clientId, user, policy, callState); TokenCacheKey cacheKey = null; if (kvp.HasValue) { cacheKey = kvp.Value.Key; resultEx = kvp.Value.Value; bool tokenNearExpiry = (resultEx.Result.ExpiresOn <= DateTime.UtcNow + TimeSpan.FromMinutes(Constant.ExpirationMarginInMinutes)); if (!cacheKey.ScopeContains(scope) || (!Authenticator.IsTenantLess(authority) && !authority.Equals(cacheKey.Authority)) || !clientId.Equals(cacheKey.ClientId)) { //requested scope are not a subset or authority does not match (cross-tenant RT) or client id is not same (FoCI). PlatformPlugin.Logger.Verbose(callState, string.Format(CultureInfo.InvariantCulture, "Refresh token for scope '{0}' will be used to acquire token for '{1}'", cacheKey.Scope.AsSingleString(), scope.AsSingleString())); resultEx = CreateResultExFromCacheResultEx(cacheKey, resultEx); } else if (tokenNearExpiry) { resultEx.Result.Token = null; PlatformPlugin.Logger.Verbose(callState, "An expired or near expiry token was found in the cache"); } else { PlatformPlugin.Logger.Verbose(callState, string.Format(CultureInfo.InvariantCulture, "{0} minutes left until token in cache expires", (resultEx.Result.ExpiresOn - DateTime.UtcNow).TotalMinutes)); } // client credential tokens do not have associated refresh tokens. if (resultEx.Result.Token == null && resultEx.RefreshToken == null) { this.tokenCacheDictionary.Remove(cacheKey); PlatformPlugin.Logger.Information(callState, "An old item was removed from the cache"); this.HasStateChanged = true; resultEx = null; } if (resultEx != null) { PlatformPlugin.Logger.Information(callState, "A matching item (access token or refresh token or both) was found in the cache"); } } return(resultEx); } }