Skip to content

Commit 01c977b

Browse files
authored
Fix instance discovery for multi-cloud https://github.com/AzureAD/mic… (#1049)
* Fix instance discovery for multi-cloud #1048 * Add more pre-validated hosts
1 parent 5cecef0 commit 01c977b

File tree

10 files changed

+31
-46
lines changed

10 files changed

+31
-46
lines changed

src/Microsoft.Identity.Client/Instance/AadAuthority.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,31 @@
3131
using System.Linq;
3232
using System.Threading.Tasks;
3333
using Microsoft.Identity.Client.Core;
34+
using Microsoft.Identity.Client.Utils;
3435

3536
namespace Microsoft.Identity.Client.Instance
3637
{
3738
internal class AadAuthority : Authority
3839
{
39-
internal static readonly HashSet<string> TrustedHostList = new HashSet<string>()
40+
public const string DefaultTrustedHost = "login.microsoftonline.com";
41+
public const string AADCanonicalAuthorityTemplate = "https://{0}/{1}/";
42+
43+
private static readonly HashSet<string> s_trustedHostList = new HashSet<string>()
4044
{
41-
"login.windows.net", // Microsoft Azure Worldwide - Used in validation scenarios where host is not this list
42-
"login.chinacloudapi.cn", // Microsoft Azure China
45+
"login.partner.microsoftonline.cn", // Microsoft Azure China
46+
"login.chinacloudapi.cn",
4347
"login.microsoftonline.de", // Microsoft Azure Blackforest
4448
"login-us.microsoftonline.com", // Microsoft Azure US Government - Legacy
4549
"login.microsoftonline.us", // Microsoft Azure US Government
46-
"login.microsoftonline.com", // Microsoft Azure Worldwide
47-
"login.cloudgovapi.us" // Microsoft Azure US Government
50+
DefaultTrustedHost, // Microsoft Azure Worldwide
51+
"login.windows.net"
4852
};
4953

5054
internal static bool IsInTrustedHostList(string host)
5155
{
52-
return !string.IsNullOrEmpty(
53-
TrustedHostList.FirstOrDefault(a => string.Compare(host, a, StringComparison.OrdinalIgnoreCase) == 0));
56+
return s_trustedHostList.ContainsOrdinalIgnoreCase(host);
5457
}
5558

56-
public const string DefaultTrustedHost = "login.microsoftonline.com";
57-
public const string AADCanonicalAuthorityTemplate = "https://{0}/{1}/";
58-
5959
internal AadAuthority(
6060
IServiceBundle serviceBundle,
6161
AuthorityInfo authorityInfo) : base(serviceBundle, authorityInfo)

src/Microsoft.Identity.Client/Instance/AadInstanceDiscovery.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ private void CacheInstanceDiscoveryMetadata(string host, InstanceDiscoveryRespon
133133
{
134134
foreach (var entry in instanceDiscoveryResponse.Metadata ?? Enumerable.Empty<InstanceDiscoveryMetadataEntry>())
135135
{
136-
entry.TenantDiscoveryEndpoint = instanceDiscoveryResponse.TenantDiscoveryEndpoint;
137136
foreach (string aliasedAuthority in entry.Aliases ?? Enumerable.Empty<string>())
138137
{
139138
TryAddValue(aliasedAuthority, entry);
@@ -146,9 +145,8 @@ private void CacheInstanceDiscoveryMetadata(string host, InstanceDiscoveryRespon
146145
{
147146
PreferredNetwork = host,
148147
PreferredCache = host,
149-
TenantDiscoveryEndpoint = instanceDiscoveryResponse.TenantDiscoveryEndpoint,
150148
Aliases = null
151149
});
152150
}
153151
}
154-
}
152+
}

src/Microsoft.Identity.Client/Instance/AadOpenIdConfigurationEndpointManager.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,17 @@ public AadOpenIdConfigurationEndpointManager(IServiceBundle serviceBundle)
4141
}
4242

4343
/// <inheritdoc />
44-
public async Task<string> GetOpenIdConfigurationEndpointAsync(
44+
public async Task<string> ValidateAuthorityAndGetOpenIdDiscoveryEndpointAsync(
4545
AuthorityInfo authorityInfo,
4646
string userPrincipalName,
4747
RequestContext requestContext)
4848
{
4949
var authorityUri = new Uri(authorityInfo.CanonicalAuthority);
5050
if (authorityInfo.ValidateAuthority && !AadAuthority.IsInTrustedHostList(authorityUri.Host))
5151
{
52-
var discoveryResponse = await _serviceBundle.AadInstanceDiscovery.GetMetadataEntryAsync(
52+
await _serviceBundle.AadInstanceDiscovery.GetMetadataEntryAsync(
5353
authorityUri,
5454
requestContext).ConfigureAwait(false);
55-
56-
return discoveryResponse.TenantDiscoveryEndpoint;
5755
}
5856

5957
return authorityInfo.CanonicalAuthority + Constants.OpenIdConfigurationEndpoint;

src/Microsoft.Identity.Client/Instance/AdfsOpenIdConfigurationEndpointManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public AdfsOpenIdConfigurationEndpointManager(IServiceBundle serviceBundle)
4545
_serviceBundle = serviceBundle;
4646
}
4747

48-
public async Task<string> GetOpenIdConfigurationEndpointAsync(
48+
public async Task<string> ValidateAuthorityAndGetOpenIdDiscoveryEndpointAsync(
4949
AuthorityInfo authorityInfo,
5050
string userPrincipalName,
5151
RequestContext requestContext)

src/Microsoft.Identity.Client/Instance/AuthorityEndpointResolutionManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public async Task<AuthorityEndpoints> ResolveEndpointsAsync(
8181

8282
var endpointManager = OpenIdConfigurationEndpointManagerFactory.Create(authorityInfo, _serviceBundle);
8383

84-
string openIdConfigurationEndpoint = await endpointManager.GetOpenIdConfigurationEndpointAsync(
84+
string openIdConfigurationEndpoint = await endpointManager.ValidateAuthorityAndGetOpenIdDiscoveryEndpointAsync(
8585
authorityInfo,
8686
userPrincipalName,
8787
requestContext).ConfigureAwait(false);

src/Microsoft.Identity.Client/Instance/B2COpenIdConfigurationEndpointManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace Microsoft.Identity.Client.Instance
3535
internal class B2COpenIdConfigurationEndpointManager : IOpenIdConfigurationEndpointManager
3636
{
3737
/// <inheritdoc />
38-
public Task<string> GetOpenIdConfigurationEndpointAsync(
38+
public Task<string> ValidateAuthorityAndGetOpenIdDiscoveryEndpointAsync(
3939
AuthorityInfo authorityInfo,
4040
string userPrincipalName,
4141
RequestContext requestContext)

src/Microsoft.Identity.Client/Instance/IOpenIdConfigurationEndpointManager.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ namespace Microsoft.Identity.Client.Instance
3232
{
3333
internal interface IOpenIdConfigurationEndpointManager
3434
{
35-
Task<string> GetOpenIdConfigurationEndpointAsync(
35+
/// <summary>
36+
/// Validates the authority if required and returns the OpenId discovery endpoint
37+
/// for the given tenant. This is specific to each authority type.
38+
/// </summary>
39+
Task<string> ValidateAuthorityAndGetOpenIdDiscoveryEndpointAsync(
3640
AuthorityInfo authorityInfo,
3741
string userPrincipalName,
3842
RequestContext requestContext);

src/Microsoft.Identity.Client/Instance/InstanceDiscoveryMetadataEntry.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ internal sealed class InstanceDiscoveryMetadataEntry
3636
public string PreferredNetwork { get; set; }
3737

3838
[DataMember(Name = "preferred_cache")]
39-
public string PreferredCache { get; set; }
40-
41-
[DataMember(Name = "tenant_discovery_endpoint", IsRequired = false)]
42-
public string TenantDiscoveryEndpoint { get; set; }
39+
public string PreferredCache { get; set; }
4340

4441
[DataMember(Name = "aliases")]
4542
public string[] Aliases { get; set; }

tests/Microsoft.Identity.Test.Unit.net45/AuthorityAliasesTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void TestInitialize()
5757
#if !NET_CORE
5858
[TestMethod]
5959
[Description("Test authority migration")]
60-
public async Task AuthorityMigration_IntegrationTestAsync()
60+
public async Task AuthorityMigrationTestAsync()
6161
{
6262
// make sure that for all network calls "preferred_cache" environment is used
6363
// (it is taken from metadata in instance discovery response),

tests/Microsoft.Identity.Test.Unit.net45/CoreTests/InstanceTests/AadAuthorityTests.cs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ namespace Microsoft.Identity.Test.Unit.CoreTests.InstanceTests
4747
[DeploymentItem("Resources\\OpenidConfiguration.json")]
4848
[DeploymentItem("Resources\\OpenidConfiguration-MissingFields.json")]
4949
public class AadAuthorityTests
50-
{
50+
{
51+
[TestInitialize]
52+
public void Init()
53+
{
54+
TestCommon.ResetStateAndInitMsal();
55+
}
56+
5157
[TestMethod]
5258
[TestCategory("AadAuthorityTests")]
5359
public void SuccessfulValidationTest()
@@ -77,7 +83,7 @@ public void SuccessfulValidationTest()
7783
new MockHttpMessageHandler
7884
{
7985
ExpectedMethod = HttpMethod.Get,
80-
ExpectedUrl = "https://login.microsoftonline.in/mytenant.com/.well-known/openid-configuration",
86+
ExpectedUrl = "https://login.microsoftonline.in/mytenant.com/v2.0/.well-known/openid-configuration",
8187
ResponseMessage = MockHelpers.CreateSuccessResponseMessage(
8288
File.ReadAllText(ResourceHelper.GetTestResourceRelativePath("OpenidConfiguration.json")))
8389
});
@@ -290,23 +296,5 @@ public void CanonicalAuthorityInitTest()
290296
authority = Authority.CreateAuthority(serviceBundle, UriCustomPort);
291297
Assert.AreEqual(UriCustomPortTailSlash, authority.AuthorityInfo.CanonicalAuthority);
292298
}
293-
294-
/*
295-
[TestMethod]
296-
[TestCategory("AadAuthorityTests")]
297-
public void DeprecatedAuthorityTest()
298-
{
299-
const string uriNoPort = "https://login.windows.net/mytenant.com";
300-
const string uriCustomPort = "https://login.windows.net:444/mytenant.com/";
301-
var authority = Authority.CreateAuthority(uriNoPort, false);
302-
Assert.AreEqual("https://login.microsoftonline.com/mytenant.com/", authority.CanonicalAuthority);
303-
authority = Authority.CreateAuthority(uriCustomPort, false);
304-
Assert.AreEqual("https://login.microsoftonline.com:444/mytenant.com/", authority.CanonicalAuthority);
305-
authority = Authority.CreateAuthority("https://login.windows.net/tfp/tenant/policy", false);
306-
Assert.AreEqual("https://login.microsoftonline.com/tfp/tenant/policy/", authority.CanonicalAuthority);
307-
authority = Authority.CreateAuthority("https://login.windows.net:444/tfp/tenant/policy", false);
308-
Assert.AreEqual("https://login.microsoftonline.com:444/tfp/tenant/policy/", authority.CanonicalAuthority);
309-
}
310-
*/
311299
}
312300
}

0 commit comments

Comments
 (0)