Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions sdk/identity/Azure.Identity/src/TenantIdResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public override string Resolve(string explicitTenantId, TokenRequestContext cont
{
bool disableMultiTenantAuth = IdentityCompatSwitches.DisableTenantDiscovery;

if (context.TenantId != explicitTenantId && context.TenantId != null && explicitTenantId != null)
if (!string.Equals(context.TenantId, explicitTenantId, StringComparison.OrdinalIgnoreCase) && context.TenantId != null && explicitTenantId != null)
{
if (disableMultiTenantAuth || explicitTenantId == Constants.AdfsTenantId)
if (disableMultiTenantAuth || string.Equals(explicitTenantId, Constants.AdfsTenantId, StringComparison.OrdinalIgnoreCase))
{
AzureIdentityEventSource.Singleton.TenantIdDiscoveredAndNotUsed(explicitTenantId, context.TenantId);
}
Expand All @@ -36,11 +36,11 @@ public override string Resolve(string explicitTenantId, TokenRequestContext cont
string resolvedTenantId = disableMultiTenantAuth switch
{
true => explicitTenantId,
false when explicitTenantId == Constants.AdfsTenantId => explicitTenantId,
false when string.Equals(explicitTenantId, Constants.AdfsTenantId, StringComparison.OrdinalIgnoreCase) => explicitTenantId,
_ => context.TenantId ?? explicitTenantId
};

if (explicitTenantId != null && resolvedTenantId != explicitTenantId && additionallyAllowedTenantIds != AllTenants && Array.BinarySearch(additionallyAllowedTenantIds, resolvedTenantId, StringComparer.OrdinalIgnoreCase) < 0)
if (explicitTenantId != null && !string.Equals(resolvedTenantId, explicitTenantId, StringComparison.OrdinalIgnoreCase) && additionallyAllowedTenantIds != AllTenants && Array.BinarySearch(additionallyAllowedTenantIds, resolvedTenantId, StringComparer.OrdinalIgnoreCase) < 0)
{
throw new AuthenticationFailedException($"The current credential is not configured to acquire tokens for tenant {resolvedTenantId}. To enable acquiring tokens for this tenant add it to the AdditionallyAllowedTenants on the credential options, or add \"*\" to AdditionallyAllowedTenants to allow acquiring tokens for any tenant. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/multitenant/troubleshoot");
}
Expand Down
59 changes: 59 additions & 0 deletions sdk/identity/Azure.Identity/tests/TenantIdResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,64 @@ public static void AssertAllowedTenantIdsEnforcedAsync(string tenantId, TokenReq
StringAssert.Contains($"The current credential is not configured to acquire tokens for tenant {tokenRequestContext.TenantId}", ex.Message);
}
}

[Test]
public void ResolveWithCaseInsensitiveTenantIdComparison()
{
const string upperCaseTenantId = "CLIENT-TENANT";
const string lowerCaseTenantId = "client-tenant";
const string mixedCaseTenantId = "Client-Tenant";

var contextWithUpperCase = new TokenRequestContext(Array.Empty<string>(), tenantId: upperCaseTenantId);
var contextWithLowerCase = new TokenRequestContext(Array.Empty<string>(), tenantId: lowerCaseTenantId);
var contextWithMixedCase = new TokenRequestContext(Array.Empty<string>(), tenantId: mixedCaseTenantId);

// Test that different case variations of the same tenant ID are considered equal
var result1 = TenantIdResolverBase.Default.Resolve(lowerCaseTenantId, contextWithUpperCase, TenantIdResolverBase.AllTenants);
var result2 = TenantIdResolverBase.Default.Resolve(upperCaseTenantId, contextWithLowerCase, TenantIdResolverBase.AllTenants);
var result3 = TenantIdResolverBase.Default.Resolve(mixedCaseTenantId, contextWithLowerCase, TenantIdResolverBase.AllTenants);

// All should resolve to the context tenant ID as that takes precedence
Assert.AreEqual(upperCaseTenantId, result1);
Assert.AreEqual(lowerCaseTenantId, result2);
Assert.AreEqual(lowerCaseTenantId, result3);
}

[Test]
public void ResolveWithCaseInsensitiveAdfsTenantId()
{
const string upperCaseAdfs = "ADFS";
const string mixedCaseAdfs = "Adfs";
const string lowerCaseAdfs = "adfs";

var contextWithHint = new TokenRequestContext(Array.Empty<string>(), tenantId: "some-hint");

// Test that different case variations of ADFS are all recognized
var result1 = TenantIdResolverBase.Default.Resolve(upperCaseAdfs, contextWithHint, TenantIdResolverBase.AllTenants);
var result2 = TenantIdResolverBase.Default.Resolve(mixedCaseAdfs, contextWithHint, TenantIdResolverBase.AllTenants);
var result3 = TenantIdResolverBase.Default.Resolve(lowerCaseAdfs, contextWithHint, TenantIdResolverBase.AllTenants);

// For ADFS, the explicit tenant ID should be returned regardless of case
Assert.AreEqual(upperCaseAdfs, result1);
Assert.AreEqual(mixedCaseAdfs, result2);
Assert.AreEqual(lowerCaseAdfs, result3);
}

[Test]
public void ResolveWithCaseInsensitiveComparisonForAllowedTenants()
{
const string explicitTenantId = "explicit-tenant";
const string upperCaseContextTenant = "CONTEXT-TENANT";
const string lowerCaseContextTenant = "context-tenant";

var contextWithUpperCase = new TokenRequestContext(Array.Empty<string>(), tenantId: upperCaseContextTenant);
var additionallyAllowedTenants = new[] { lowerCaseContextTenant };

// The context tenant ID (uppercase) should be allowed because it matches
// the additionally allowed tenant (lowercase) in a case-insensitive manner
var result = TenantIdResolverBase.Default.Resolve(explicitTenantId, contextWithUpperCase, additionallyAllowedTenants);

Assert.AreEqual(upperCaseContextTenant, result);
}
}
}