Esempio n. 1
0
        public Dictionary <string, string> GetPreviousRequestRecord(CallState callState)
        {
            Dictionary <string, string> parameters;

            if (callState != null && callState.AuthorityType == AuthorityType.AAD)
            {
                parameters = GetClientMetricsParameters();
            }
            else
            {
                parameters = new Dictionary <string, string>();
            }

            return(parameters);
        }
Esempio n. 2
0
        public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            try
            {
#if MAC
                var windowController = new AuthenticationAgentNSWindowController(authorizationUri.AbsoluteUri, redirectUri.OriginalString, CallbackMethod);
                windowController.Run(parameters.CallerWindow);
#else
                this.parameters.CallerViewController.PresentViewController(new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri, redirectUri.OriginalString, CallbackMethod), false, null);
#endif
            }
            catch (Exception ex)
            {
                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }
        }
Esempio n. 3
0
 public void EndClientMetricsRecord(string endpoint, CallState callState)
 {
     if (callState != null && callState.AuthorityType == AuthorityType.AAD && metricsTimer != null)
     {
         metricsTimer.Stop();
         lastResponseTime  = metricsTimer.ElapsedMilliseconds;
         lastCorrelationId = callState.CorrelationId;
         lastEndpoint      = endpoint;
         lock (PendingClientMetricsLock)
         {
             if (pendingClientMetrics == null)
             {
                 pendingClientMetrics = this;
             }
         }
     }
 }
        public async Task UpdateFromTemplateAsync(CallState callState)
        {
            if (!this.updatedFromTemplate)
            {
                var    authorityUri = new Uri(this.Authority);
                string host         = authorityUri.Authority;
                string path         = authorityUri.AbsolutePath.Substring(1);
                string tenant       = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal));

                AuthenticatorTemplate matchingTemplate = await AuthenticatorTemplateList.FindMatchingItemAsync(this.ValidateAuthority, host, tenant, callState);

                this.AuthorizationUri      = matchingTemplate.AuthorizeEndpoint.Replace("{tenant}", tenant);
                this.DeviceCodeUri         = matchingTemplate.DeviceCodeEndpoint.Replace("{tenant}", tenant);
                this.TokenUri              = matchingTemplate.TokenEndpoint.Replace("{tenant}", tenant);
                this.UserRealmUri          = CanonicalizeUri(matchingTemplate.UserRealmEndpoint);
                this.IsTenantless          = (string.Compare(tenant, TenantlessTenantName, StringComparison.OrdinalIgnoreCase) == 0);
                this.SelfSignedJwtAudience = matchingTemplate.Issuer.Replace("{tenant}", tenant);
                this.updatedFromTemplate   = true;
            }
        }
        public static Dictionary <string, string> ParseKeyValueList(string input, char delimiter, bool urlDecode, bool lowercaseKeys,
                                                                    CallState callState)
        {
            var response = new Dictionary <string, string>();

            List <string> queryPairs = SplitWithQuotes(input, delimiter);

            foreach (string queryPair in queryPairs)
            {
                List <string> pair = SplitWithQuotes(queryPair, '=');

                if (pair.Count == 2 && !string.IsNullOrWhiteSpace(pair[0]) && !string.IsNullOrWhiteSpace(pair[1]))
                {
                    string key   = pair[0];
                    string value = pair[1];

                    // Url decoding is needed for parsing OAuth response, but not for parsing WWW-Authenticate header in 401 challenge
                    if (urlDecode)
                    {
                        key   = UrlDecode(key);
                        value = UrlDecode(value);
                    }

                    if (lowercaseKeys)
                    {
                        key = key.Trim().ToLower();
                    }

                    value = value.Trim().Trim(new[] { '\"' }).Trim();

                    if (response.ContainsKey(key) && callState != null)
                    {
                        PlatformPlugin.Logger.Warning(callState, string.Format(CultureInfo.CurrentCulture, "Key/value pair list contains redundant key '{0}'.", key));
                    }

                    response[key] = value;
                }
            }

            return(response);
        }
        public override async Task <bool> IsUserLocalAsync(CallState callState)
        {
            if (!UserInformation.NameAccessAllowed)
            {
                // The access is not allowed and we cannot determine whether this is a local user or not. So, we do NOT add form auth parameter.
                // This is the case where we can advise customers to add extra query parameter if they want.

                PlatformPlugin.Logger.Information(callState, "Cannot access user information to determine whether it is a local user or not due to machine's privacy setting.");
                return(false);
            }

            try
            {
                return(string.IsNullOrEmpty(await UserInformation.GetDomainNameAsync()));
            }
            catch (UnauthorizedAccessException)
            {
                PlatformPlugin.Logger.Information(callState, "Cannot try Windows Integrated Authentication due to lack of Enterprise capability.");
                // This mostly means Enterprise capability is missing, so WIA cannot be used and
                // we return true to add form auth parameter in the caller.
                return(true);
            }
        }
Esempio n. 7
0
        public static string ReadErrorResponse(XDocument responseDocument, CallState callState)
        {
            string errorMessage = null;

            try
            {
                XElement body = responseDocument.Descendants(XmlNamespace.SoapEnvelope + "Body").FirstOrDefault();

                if (body != null)
                {
                    XElement fault = body.Elements(XmlNamespace.SoapEnvelope + "Fault").FirstOrDefault();
                    if (fault != null)
                    {
                        XElement reason = fault.Elements(XmlNamespace.SoapEnvelope + "Reason").FirstOrDefault();
                        if (reason != null)
                        {
                            XElement text = reason.Elements(XmlNamespace.SoapEnvelope + "Text").FirstOrDefault();
                            if (text != null)
                            {
                                using (var reader = text.CreateReader())
                                {
                                    reader.MoveToContent();
                                    errorMessage = reader.ReadInnerXml();
                                }
                            }
                        }
                    }
                }
            }
            catch (XmlException ex)
            {
                throw new AdalException(AdalError.ParsingWsTrustResponseFailed, ex);
            }

            return(errorMessage);
        }
        internal static WsTrustAddress ExtractWsTrustAddressFromMex(XDocument mexDocument, UserAuthType userAuthType, CallState callState)
        {
            WsTrustAddress address = null;
            MexPolicy      policy  = null;

            try
            {
                Dictionary <string, MexPolicy> policies = ReadPolicies(mexDocument);
                Dictionary <string, MexPolicy> bindings = ReadPolicyBindings(mexDocument, policies);
                SetPolicyEndpointAddresses(mexDocument, bindings);
                Random random = new Random();
                //try ws-trust 1.3 first
                policy = policies.Values.Where(p => p.Url != null && p.AuthType == userAuthType && p.Version == WsTrustVersion.WsTrust13).OrderBy(p => random.Next()).FirstOrDefault() ??
                         policies.Values.Where(p => p.Url != null && p.AuthType == userAuthType).OrderBy(p => random.Next()).FirstOrDefault();

                if (policy != null)
                {
                    address         = new WsTrustAddress();
                    address.Uri     = policy.Url;
                    address.Version = policy.Version;
                }
                else if (userAuthType == UserAuthType.IntegratedAuth)
                {
                    throw new AdalException(AdalError.IntegratedAuthFailed, new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument));
                }
                else
                {
                    throw new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument);
                }
            }
            catch (XmlException ex)
            {
                throw new AdalException(AdalError.ParsingWsMetadataExchangeFailed, ex);
            }

            return(address);
        }
 internal abstract void Error(CallState callState, Exception ex, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "");
        public static async Task <WsTrustAddress> FetchWsTrustAddressFromMexAsync(string federationMetadataUrl, UserAuthType userAuthType, CallState callState)
        {
            XDocument mexDocument = await FetchMexAsync(federationMetadataUrl, callState);

            return(ExtractWsTrustAddressFromMex(mexDocument, userAuthType, callState));
        }
 public static Dictionary <string, string> ParseKeyValueList(string input, char delimiter, bool urlDecode, CallState callState)
 {
     return(ParseKeyValueList(input, delimiter, urlDecode, true, callState));
 }
        internal static async Task <XDocument> FetchMexAsync(string federationMetadataUrl, CallState callState)
        {
            XDocument mexDocument;

            try
            {
                IHttpClient request = PlatformPlugin.HttpClientFactory.Create(federationMetadataUrl, callState);
                using (var response = await request.GetResponseAsync())
                {
                    mexDocument = XDocument.Load(response.ResponseStream, LoadOptions.None);
                }
            }
            catch (WebException ex)
            {
                throw new AdalServiceException(AdalError.AccessingWsMetadataExchangeFailed, ex);
            }
            catch (XmlException ex)
            {
                throw new AdalException(AdalError.ParsingWsMetadataExchangeFailed, ex);
            }

            return(mexDocument);
        }
 public HttpClientWrapper(string uri, CallState callState)
 {
     this.uri       = uri;
     this.Headers   = new Dictionary <string, string>();
     this.CallState = callState;
 }
Esempio n. 14
0
 public IHttpClient Create(string uri, CallState callState)
 {
     return(new HttpClientWrapper(uri, callState));
 }
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            bool ssoMode = ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri);

            if (this.promptBehavior == PromptBehavior.Never && !ssoMode && redirectUri.Scheme != Constant.MsAppScheme)
            {
                throw new ArgumentException(AdalErrorMessageEx.RedirectUriUnsupportedWithPromptBehaviorNever, "redirectUri");
            }

            WebAuthenticationResult webAuthenticationResult;

            WebAuthenticationOptions options = (this.useCorporateNetwork && (ssoMode || redirectUri.Scheme == Constant.MsAppScheme)) ? WebAuthenticationOptions.UseCorporateNetwork : WebAuthenticationOptions.None;

            if (this.promptBehavior == PromptBehavior.Never)
            {
                options |= WebAuthenticationOptions.SilentMode;
            }

            try
            {
                if (ssoMode)
                {
                    webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri);
                }
                else
                {
                    webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri, redirectUri);
                }
            }
            catch (FileNotFoundException ex)
            {
                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }
            catch (Exception ex)
            {
                if (this.promptBehavior == PromptBehavior.Never)
                {
                    throw new AdalException(AdalError.UserInteractionRequired, ex);
                }

                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }

            AuthorizationResult result = ProcessAuthorizationResult(webAuthenticationResult, callState);

            return(result);
        }
 public async virtual Task <bool> IsUserLocalAsync(CallState callState)
 {
     return(await Task.Factory.StartNew(() => false));
 }
 internal abstract void Warning(CallState callState, string message, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "");
 public virtual string GetRedirectUriAsString(Uri redirectUri, CallState callState)
 {
     return(redirectUri.OriginalString);
 }
Esempio n. 19
0
        public static async Task <WsTrustResponse> SendRequestAsync(WsTrustAddress wsTrustAddress, UserCredential credential, CallState callState)
        {
            IHttpClient request = PlatformPlugin.HttpClientFactory.Create(wsTrustAddress.Uri.AbsoluteUri, callState);

            request.ContentType = "application/soap+xml";
            if (credential.UserAuthType == UserAuthType.IntegratedAuth)
            {
                SetKerberosOption(request);
            }

            StringBuilder messageBuilder = BuildMessage(DefaultAppliesTo, wsTrustAddress, credential);
            string        soapAction     = XmlNamespace.Issue.ToString();

            if (wsTrustAddress.Version == WsTrustVersion.WsTrust2005)
            {
                soapAction = XmlNamespace.Issue2005.ToString();
            }

            WsTrustResponse wstResponse;

            try
            {
                request.BodyParameters        = new StringRequestParameters(messageBuilder);
                request.Headers["SOAPAction"] = soapAction;
                IHttpWebResponse response = await request.GetResponseAsync();

                wstResponse = WsTrustResponse.CreateFromResponse(response.ResponseStream, wsTrustAddress.Version);
            }
            catch (WebException ex)
            {
                string errorMessage;

                try
                {
                    XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.Response.GetResponseStream());
                    errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState);
                }
                catch (AdalException)
                {
                    errorMessage = "See inner exception for detail.";
                }

                throw new AdalServiceException(
                          AdalError.FederatedServiceReturnedError,
                          string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, wsTrustAddress.Uri, errorMessage),
                          null,
                          ex);
            }

            return(wstResponse);
        }
        internal static string PrepareLogMessage(CallState callState, string classOrComponent, string message)
        {
            string correlationId = (callState != null) ? callState.CorrelationId.ToString() : string.Empty;

            return(string.Format(CultureInfo.CurrentCulture, "{0}: {1} - {2}: {3}", DateTime.UtcNow, correlationId, classOrComponent, message));
        }
        private static AuthorizationResult ProcessAuthorizationResult(WebAuthenticationResult webAuthenticationResult, CallState callState)
        {
            AuthorizationResult result;

            switch (webAuthenticationResult.ResponseStatus)
            {
            case WebAuthenticationStatus.Success:
                result = new AuthorizationResult(AuthorizationStatus.Success, webAuthenticationResult.ResponseData);
                break;

            case WebAuthenticationStatus.ErrorHttp:
                result = new AuthorizationResult(AuthorizationStatus.ErrorHttp, webAuthenticationResult.ResponseErrorDetail.ToString(CultureInfo.CurrentCulture));
                break;

            case WebAuthenticationStatus.UserCancel:
                result = new AuthorizationResult(AuthorizationStatus.UserCancel, null);
                break;

            default:
                result = new AuthorizationResult(AuthorizationStatus.UnknownError, null);
                break;
            }

            return(result);
        }
        public async Task <AuthenticatorTemplate> FindMatchingItemAsync(bool validateAuthority, string host, string tenant, CallState callState)
        {
            AuthenticatorTemplate matchingAuthenticatorTemplate = null;

            if (validateAuthority)
            {
                matchingAuthenticatorTemplate = this.FirstOrDefault(a => string.Compare(host, a.Host, StringComparison.OrdinalIgnoreCase) == 0);
                if (matchingAuthenticatorTemplate == null)
                {
                    // We only check with the first trusted authority (login.windows.net) for instance discovery
                    await this.First().VerifyAnotherHostByInstanceDiscoveryAsync(host, tenant, callState);
                }
            }

            return(matchingAuthenticatorTemplate ?? AuthenticatorTemplate.CreateFromHost(host));
        }
 public override string GetRedirectUriAsString(Uri redirectUri, CallState callState)
 {
     return(ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri) ?
            WebAuthenticationBroker.GetCurrentApplicationCallbackUri().OriginalString :
            redirectUri.OriginalString);
 }
        internal static async Task <UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState)
        {
            string userRealmEndpoint = userRealmUri;

            userRealmEndpoint += (userName + "?api-version=1.0");

            PlatformPlugin.Logger.Information(callState, string.Format(CultureInfo.CurrentCulture, " Sending user realm discovery request to '{0}'", userRealmEndpoint));

            var client = new AdalHttpClient(userRealmEndpoint, callState)
            {
                Client = { Accept = "application/json" }
            };

            return(await client.GetResponseAsync <UserRealmDiscoveryResponse>(ClientMetricsEndpointType.UserRealmDiscovery));
        }
        public async Task VerifyAnotherHostByInstanceDiscoveryAsync(string host, string tenant, CallState callState)
        {
            string instanceDiscoveryEndpoint = this.InstanceDiscoveryEndpoint;

            instanceDiscoveryEndpoint += ("?api-version=1.0&authorization_endpoint=" + AuthorizeEndpointTemplate);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{host}", host);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{tenant}", tenant);

            try
            {
                var client = new AdalHttpClient(instanceDiscoveryEndpoint, callState);
                InstanceDiscoveryResponse discoveryResponse = await client.GetResponseAsync <InstanceDiscoveryResponse>(ClientMetricsEndpointType.InstanceDiscovery);

                if (discoveryResponse.TenantDiscoveryEndpoint == null)
                {
                    throw new AdalException(AdalError.AuthorityNotInValidList);
                }
            }
            catch (AdalServiceException ex)
            {
                throw new AdalException((ex.ErrorCode == "invalid_instance") ? AdalError.AuthorityNotInValidList : AdalError.AuthorityValidationFailed, ex);
            }
        }
Esempio n. 26
0
        internal AuthenticationResultEx LoadFromCache(CacheQueryData cacheQueryData, CallState callState)
        {
            lock (cacheLock)
            {
                PlatformPlugin.Logger.Verbose(callState, "Looking up cache for a token...");

                AuthenticationResultEx resultEx = null;

                KeyValuePair <TokenCacheKey, AuthenticationResultEx>?kvp = this.LoadSingleItemFromCache(cacheQueryData, callState);

                if (kvp.HasValue)
                {
                    TokenCacheKey cacheKey = kvp.Value.Key;
                    resultEx = kvp.Value.Value;
                    bool tokenNearExpiry = (resultEx.Result.ExpiresOn <=
                                            DateTime.UtcNow + TimeSpan.FromMinutes(ExpirationMarginInMinutes));

                    if (tokenNearExpiry)
                    {
                        resultEx.Result.AccessToken = null;
                        PlatformPlugin.Logger.Verbose(callState,
                                                      "An expired or near expiry token was found in the cache");
                    }
                    else if (!cacheKey.ResourceEquals(cacheQueryData.Resource))
                    {
                        PlatformPlugin.Logger.Verbose(callState,
                                                      string.Format(CultureInfo.CurrentCulture,
                                                                    "Multi resource refresh token for resource '{0}' will be used to acquire token for '{1}'",
                                                                    cacheKey.Resource, cacheQueryData.Resource));
                        var newResultEx = new AuthenticationResultEx
                        {
                            Result             = new AuthenticationResult(null, null, DateTimeOffset.MinValue),
                            RefreshToken       = resultEx.RefreshToken,
                            ResourceInResponse = resultEx.ResourceInResponse
                        };

                        newResultEx.Result.UpdateTenantAndUserInfo(resultEx.Result.TenantId, resultEx.Result.IdToken,
                                                                   resultEx.Result.UserInfo);
                        resultEx = newResultEx;
                    }
                    else
                    {
                        PlatformPlugin.Logger.Verbose(callState,
                                                      string.Format(CultureInfo.CurrentCulture, "{0} minutes left until token in cache expires",
                                                                    (resultEx.Result.ExpiresOn - DateTime.UtcNow).TotalMinutes));
                    }

                    if (resultEx.Result.AccessToken == 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");
                    }
                }
                else
                {
                    PlatformPlugin.Logger.Information(callState, "No matching token was found in the cache");
                }

                return(resultEx);
            }
        }
Esempio n. 27
0
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            returnedUriReady = new SemaphoreSlim(0);
            Authenticate(authorizationUri, redirectUri, callState);
            await returnedUriReady.WaitAsync();

            return(authorizationResult);
        }
Esempio n. 28
0
        internal void StoreToCache(AuthenticationResultEx result, string authority, string resource, string clientId, TokenSubjectType subjectType, CallState callState)
        {
            lock (cacheLock)
            {
                PlatformPlugin.Logger.Verbose(callState, "Storing token in the cache...");

                string uniqueId      = (result.Result.UserInfo != null) ? result.Result.UserInfo.UniqueId : null;
                string displayableId = (result.Result.UserInfo != null) ? result.Result.UserInfo.DisplayableId : null;

                this.OnBeforeWrite(new TokenCacheNotificationArgs
                {
                    Resource      = resource,
                    ClientId      = clientId,
                    UniqueId      = uniqueId,
                    DisplayableId = displayableId
                });

                TokenCacheKey tokenCacheKey = new TokenCacheKey(authority, resource, clientId, subjectType,
                                                                result.Result.UserInfo);
                this.tokenCacheDictionary[tokenCacheKey] = result;
                PlatformPlugin.Logger.Verbose(callState, "An item was stored in the cache");
                this.UpdateCachedMrrtRefreshTokens(result, clientId, subjectType);

                this.HasStateChanged = true;
            }
        }
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            returnedUriReady = new SemaphoreSlim(0);

            try
            {
                var agentIntent = new Intent(this.parameters.CallerActivity, typeof(AuthenticationAgentActivity));
                agentIntent.PutExtra("Url", authorizationUri.AbsoluteUri);
                agentIntent.PutExtra("Callback", redirectUri.AbsoluteUri);
                this.parameters.CallerActivity.StartActivityForResult(agentIntent, 0);
            }
            catch (Exception ex)
            {
                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }

            await returnedUriReady.WaitAsync();

            return(authorizationResult);
        }
Esempio n. 30
0
        private KeyValuePair <TokenCacheKey, AuthenticationResultEx>?LoadSingleItemFromCache(CacheQueryData cacheQueryData, CallState callState)
        {
            lock (cacheLock)
            {
                // First identify all potential tokens.
                List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > items = this.QueryCache(cacheQueryData.Authority, cacheQueryData.ClientId, cacheQueryData.SubjectType, cacheQueryData.UniqueId, cacheQueryData.DisplayableId);

                List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > resourceSpecificItems =
                    items.Where(p => p.Key.ResourceEquals(cacheQueryData.Resource)).ToList();
                int resourceValuesCount = resourceSpecificItems.Count();

                //multiple tokens matched. scope down the results to the matching userAssertion Hash, if provided
                if (resourceValuesCount > 1 && cacheQueryData.AssertionHash != null)
                {
                    resourceSpecificItems =
                        resourceSpecificItems.Where(p => p.Value.UserAssertionHash.Equals(cacheQueryData.AssertionHash))
                        .ToList();
                    resourceValuesCount = resourceSpecificItems.Count();
                }

                KeyValuePair <TokenCacheKey, AuthenticationResultEx>?returnValue = null;
                switch (resourceValuesCount)
                {
                case 1:
                    PlatformPlugin.Logger.Information(callState,
                                                      "An item matching the requested resource was found in the cache");
                    returnValue = resourceSpecificItems.First();
                    break;

                case 0:
                {
                    // There are no resource specific tokens.  Choose any of the MRRT tokens if there are any.
                    List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > mrrtItems =
                        items.Where(p => p.Value.IsMultipleResourceRefreshToken).ToList();

                    if (mrrtItems.Any())
                    {
                        returnValue = mrrtItems.First();
                        PlatformPlugin.Logger.Information(callState,
                                                          "A Multi Resource Refresh Token for a different resource was found which can be used");
                    }
                }
                break;

                default:
                    throw new AdalException(AdalError.MultipleTokensMatched);
                }

                // check for tokens issued to same client_id/user_id combination, but any tenant.
                if (returnValue == null)
                {
                    List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > itemsForAllTenants = this.QueryCache(null, cacheQueryData.ClientId, cacheQueryData.SubjectType, cacheQueryData.UniqueId, cacheQueryData.DisplayableId);
                    if (itemsForAllTenants.Count != 0)
                    {
                        returnValue = itemsForAllTenants.First();
                    }

                    // check if the token was issued by AAD
                    if (returnValue != null &&
                        Authenticator.DetectAuthorityType(returnValue.Value.Key.Authority) != AuthorityType.ADFS)
                    {
                        //remove access token to redeem refresh token against a different tenant.
                        returnValue.Value.Value.Result.AccessToken = null;
                    }
                    else
                    {
                        returnValue = null;
                    }
                }

                return(returnValue);
            }
        }