public async Task <InstanceDiscoveryMetadataEntry> GetMetadataEntryAsync( string authority, RequestContext requestContext) { var autoDetectRegion = requestContext.ServiceBundle.Config.AuthorityInfo.AutoDetectRegion; if (autoDetectRegion) { try { return(await _regionDiscoveryProvider.TryGetMetadataAsync(new Uri(authority), requestContext).ConfigureAwait(false)); } catch { //If the regional autodetection fails in TryGetMetadataAsync we check for FallbackToGlobal //If FallbackToGlobal is set, this will now fallback to using the metadata acquitition from global if (requestContext.ServiceBundle.Config.AuthorityInfo.FallbackToGlobal) { requestContext.Logger.Info($"Attempting to fall back to global endpoint"); requestContext.ApiEvent.FallbackToGlobal = true; } else { throw; } } } AuthorityType type = Authority.GetAuthorityType(authority); Uri authorityUri = new Uri(authority); string environment = authorityUri.Host; switch (type) { case AuthorityType.Aad: InstanceDiscoveryMetadataEntry entry = _userMetadataProvider?.GetMetadataOrThrow(environment, requestContext.Logger) ?? // if user provided metadata but entry is not found, fail fast await FetchNetworkMetadataOrFallbackAsync(requestContext, authorityUri).ConfigureAwait(false); if (entry == null) { string message = "[Instance Discovery] Instance metadata for this authority could neither be fetched nor found. MSAL will continue regardless. SSO might be broken if authority aliases exist. "; requestContext.Logger.WarningPii(message + "Authority: " + authority, message); entry = CreateEntryForSingleAuthority(authorityUri); } return(entry); // ADFS and B2C do not support instance discovery case AuthorityType.Adfs: case AuthorityType.B2C: requestContext.Logger.Info("[Instance Discovery] Skipping Instance discovery for non-AAD authority. "); return(CreateEntryForSingleAuthority(authorityUri)); default: throw new InvalidOperationException("Unexpected authority type " + type); } }
public async Task <InstanceDiscoveryMetadataEntry> GetMetadataEntryAsync(string authority, RequestContext requestContext) { AuthorityType type = Authority.GetAuthorityType(authority); Uri authorityUri = new Uri(authority); string environment = authorityUri.Host; switch (type) { case AuthorityType.Aad: InstanceDiscoveryMetadataEntry entry = _staticMetadataProvider.GetMetadata(environment); if (entry != null) { return(entry); } InstanceDiscoveryResponse instanceDiscoveryResponse = await _networkMetadataProvider.FetchAllDiscoveryMetadataAsync(authorityUri, requestContext).ConfigureAwait(false); CacheInstanceDiscoveryMetadata(instanceDiscoveryResponse); entry = _staticMetadataProvider.GetMetadata(environment); return(entry ?? CreateEntryForSingleAuthority(authorityUri)); // ADFS and B2C do not support instance discovery case AuthorityType.Adfs: case AuthorityType.B2C: return(CreateEntryForSingleAuthority(authorityUri)); default: throw new InvalidOperationException("Unexpected authority type " + type); } }
static KnownMetadataProvider() { void AddToKnownCache(InstanceDiscoveryMetadataEntry entry) { foreach (string alias in entry.Aliases) { s_knownEntries[alias] = entry; s_knownEnvironments.Add(alias); } } InstanceDiscoveryMetadataEntry publicCloudEntry = new InstanceDiscoveryMetadataEntry() { Aliases = new[] { "login.microsoftonline.com", "login.windows.net", "login.microsoft.com", "sts.windows.net" }, PreferredNetwork = "login.microsoftonline.com", PreferredCache = "login.windows.net" }; InstanceDiscoveryMetadataEntry cloudEntryChina = new InstanceDiscoveryMetadataEntry() { Aliases = new[] { "login.partner.microsoftonline.cn", "login.chinacloudapi.cn" }, PreferredNetwork = "login.partner.microsoftonline.cn", PreferredCache = "login.partner.microsoftonline.cn" }; InstanceDiscoveryMetadataEntry cloudEntryGermanay = new InstanceDiscoveryMetadataEntry() { Aliases = new[] { "login.microsoftonline.de" }, PreferredNetwork = "login.microsoftonline.de", PreferredCache = "login.microsoftonline.de" }; InstanceDiscoveryMetadataEntry usGovCloudEntry = new InstanceDiscoveryMetadataEntry() { Aliases = new[] { "login.microsoftonline.us", "login.usgovcloudapi.net" }, PreferredNetwork = "login.microsoftonline.us", PreferredCache = "login.microsoftonline.us" }; InstanceDiscoveryMetadataEntry usCloudEntry = new InstanceDiscoveryMetadataEntry() { Aliases = new[] { "login-us.microsoftonline.com" }, PreferredNetwork = "login-us.microsoftonline.com", PreferredCache = "login-us.microsoftonline.com" }; AddToKnownCache(publicCloudEntry); AddToKnownCache(cloudEntryChina); AddToKnownCache(cloudEntryGermanay); AddToKnownCache(usGovCloudEntry); AddToKnownCache(usCloudEntry); }
private async Task <InstanceDiscoveryMetadataEntry> FetchNetworkMetadataOrFallbackAsync( RequestContext requestContext, Uri authorityUri, bool autoDetectRegion) { try { return(await _networkMetadataProvider.GetMetadataAsync(authorityUri, requestContext).ConfigureAwait(false)); } catch (MsalServiceException ex) { if (autoDetectRegion) { requestContext.Logger.Info("[Instance Discovery] Instance discovery failed. MSAL will continue to build instance metadata with region and authority."); InstanceDiscoveryMetadataEntry entry = CreateEntryForSingleAuthority(authorityUri); _networkCacheMetadataProvider.AddMetadata(authorityUri.Host, entry); return(entry); } if (!requestContext.ServiceBundle.Config.AuthorityInfo.ValidateAuthority) { requestContext.Logger.Info("[Instance Discovery] Skipping Instance discovery as validate authority is set to false."); return(CreateEntryForSingleAuthority(authorityUri)); } // Validate Authority exception if (ex.ErrorCode == MsalError.InvalidInstance) { throw; } string message = "[Instance Discovery] Instance Discovery failed. Potential cause: no network connection or discovery endpoint is busy. See exception below. MSAL will continue without network instance metadata."; requestContext.Logger.WarningPii(message + " Authority: " + authorityUri, message); requestContext.Logger.WarningPii(ex); return(_knownMetadataProvider.GetMetadata(authorityUri.Host, Enumerable.Empty <string>(), requestContext.Logger)); } }
public async Task <InstanceDiscoveryMetadataEntry> GetMetadataEntryTryAvoidNetworkAsync( string authority, IEnumerable <string> existingEnvironmentsInCache, RequestContext requestContext) { AuthorityType type = Authority.GetAuthorityType(authority); Uri authorityUri = new Uri(authority); string environment = authorityUri.Host; switch (type) { case AuthorityType.Aad: InstanceDiscoveryMetadataEntry entry = _staticMetadataProvider.GetMetadata(environment); if (entry != null) { return(entry); } entry = _knownMetadataProvider.GetMetadata(environment, existingEnvironmentsInCache); if (entry != null) { return(entry); } return(await GetMetadataEntryAsync(authority, requestContext).ConfigureAwait(false)); case AuthorityType.Adfs: case AuthorityType.B2C: return(await GetMetadataEntryAsync(authority, requestContext).ConfigureAwait(false)); default: throw new InvalidOperationException("Unexpected authority type " + type); } }
public async Task <InstanceDiscoveryMetadataEntry> GetMetadataEntryAsync( string authority, RequestContext requestContext) { AuthorityType type = Authority.GetAuthorityType(authority); Uri authorityUri = new Uri(authority); string environment = authorityUri.Host; switch (type) { case AuthorityType.Aad: InstanceDiscoveryMetadataEntry entry = _userMetadataProvider?.GetMetadataOrThrow(environment, requestContext.Logger) ?? // if user provided metadata but entry is not found, fail fast await FetchNetworkMetadataOrFallbackAsync(requestContext, authorityUri).ConfigureAwait(false); if (entry == null) { string message = "[Instance Discovery] Instance metadata for this authority could neither be fetched nor found. MSAL will continue regardless. SSO might be broken if authority aliases exist. "; requestContext.Logger.WarningPii(message + "Authority: " + authority, message); entry = CreateEntryForSingleAuthority(authorityUri); } return(entry); // ADFS and B2C do not support instance discovery case AuthorityType.Adfs: case AuthorityType.B2C: requestContext.Logger.Info("[Instance Discovery] Skipping Instance discovery for non-AAD authority"); return(CreateEntryForSingleAuthority(authorityUri)); default: throw new InvalidOperationException("Unexpected authority type " + type); } }
internal void AddTestValueToStaticProvider(string environment, InstanceDiscoveryMetadataEntry entry) { _networkCacheMetadataProvider.AddMetadata(environment, entry); }
public void AddMetadata(string environment, InstanceDiscoveryMetadataEntry entry) { // Always take the most recent value s_cache.AddOrUpdate(environment, entry, (key, oldValue) => entry); }