Skip to content

Commit

Permalink
Fix Instance/Tenant Parsing for V2 Authority (#2954)
Browse files Browse the repository at this point in the history
* Fix Tenant Parsing for V2 Authority

* Consolidate line endings

* Keep existing indexTenant check

* Put back the comment

* use 'is' syntax for null checking

---------

Co-authored-by: jennyf19 <jeferrie@microsoft.com>
  • Loading branch information
jackj-msft and jennyf19 authored Jul 31, 2024
1 parent e9d8a5c commit 0fdfc96
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
33 changes: 19 additions & 14 deletions src/Microsoft.Identity.Web.TokenAcquisition/MergedOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ internal static void UpdateMergedOptionsFromMicrosoftIdentityOptions(MicrosoftId

mergedOptions.SaveTokens |= microsoftIdentityOptions.SaveTokens;
#if NET8_0_OR_GREATER
mergedOptions.TokenHandler ??= microsoftIdentityOptions.TokenHandler;
mergedOptions.TokenHandler ??= microsoftIdentityOptions.TokenHandler;
#else
mergedOptions.SecurityTokenValidator ??= microsoftIdentityOptions.SecurityTokenValidator;
#endif
Expand Down Expand Up @@ -215,12 +215,12 @@ internal static void UpdateMergedOptionsFromMicrosoftIdentityOptions(MicrosoftId
mergedOptions.TimeProvider = microsoftIdentityOptions.TimeProvider;
#endif
#if NET9_0_OR_GREATER
if (microsoftIdentityOptions.AdditionalAuthorizationParameters != null)
{
foreach (var parameter in microsoftIdentityOptions.AdditionalAuthorizationParameters)
{
mergedOptions.AdditionalAuthorizationParameters.Add(parameter.Key, parameter.Value);
}
if (microsoftIdentityOptions.AdditionalAuthorizationParameters is not null)
{
foreach (var parameter in microsoftIdentityOptions.AdditionalAuthorizationParameters)
{
mergedOptions.AdditionalAuthorizationParameters.Add(parameter.Key, parameter.Value);
}
}
#endif
mergedOptions.TokenValidationParameters = microsoftIdentityOptions.TokenValidationParameters.Clone();
Expand All @@ -244,7 +244,7 @@ internal static void UpdateMergedOptionsFromMicrosoftIdentityOptions(MicrosoftId
mergedOptions.AutomaticRefreshInterval = microsoftIdentityOptions.AutomaticRefreshInterval;
#endif
#endif
// Non ASP.NET Core specific
// Non ASP.NET Core specific
if (string.IsNullOrEmpty(mergedOptions.Instance) && !string.IsNullOrEmpty(microsoftIdentityOptions.Instance))
{
mergedOptions.Instance = microsoftIdentityOptions.Instance;
Expand Down Expand Up @@ -432,13 +432,18 @@ internal static void ParseAuthorityIfNecessary(MergedOptions mergedOptions)
{
if (string.IsNullOrEmpty(mergedOptions.TenantId) && string.IsNullOrEmpty(mergedOptions.Instance) && !string.IsNullOrEmpty(mergedOptions.Authority))
{
string authority = mergedOptions.Authority!.TrimEnd('/');
int indexTenant = authority.LastIndexOf('/');
if (indexTenant >= 0)
{
const int StartingIndex = 8; // length of "https://"
ReadOnlySpan<char> authoritySpan = mergedOptions.Authority.AsSpan().TrimEnd('/');

int indexTenant = authoritySpan.Slice(StartingIndex).IndexOf('/') + StartingIndex;
if (indexTenant >= 0)
{
int indexVersion = authoritySpan.Slice(indexTenant + 1).IndexOf('/') + indexTenant + 1;
int indexEndOfTenant = indexVersion == -1 ? authoritySpan.Length : indexVersion;

// In CIAM and B2C, customers will use "authority", not Instance and TenantId
mergedOptions.Instance = mergedOptions.PreserveAuthority ? mergedOptions.Authority : authority.Substring(0, indexTenant);
mergedOptions.TenantId = mergedOptions.PreserveAuthority ? null : authority.Substring(indexTenant + 1);
mergedOptions.Instance = mergedOptions.PreserveAuthority ? mergedOptions.Authority : authoritySpan.Slice(0, indexTenant).ToString();
mergedOptions.TenantId = mergedOptions.PreserveAuthority ? null : authoritySpan.Slice(indexTenant + 1, indexEndOfTenant - indexTenant - 1).ToString();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,22 @@ public void TestParseAuthorityIfNecessary_CIAM()
Assert.Null(mergedOptions.TenantId);
}

[Fact]
public void TestParseAuthorityIfNecessary_V2Authority()
{
MergedOptions mergedOptions = new()
{
Authority = TC.AuthorityWithTenantSpecifiedWithV2,
PreserveAuthority = false
};

MergedOptions.ParseAuthorityIfNecessary(mergedOptions);

Assert.Equal(TC.AuthorityWithTenantSpecifiedWithV2, mergedOptions.Authority);
Assert.Equal(TC.AadInstance, mergedOptions.Instance);
Assert.Equal(TC.TenantIdAsGuid, mergedOptions.TenantId);
}

[Fact]
public void MergeExtraQueryParametersTest()
{
Expand Down

0 comments on commit 0fdfc96

Please sign in to comment.