From f14d53fbe436fb368b87c03a642830e0b8978547 Mon Sep 17 00:00:00 2001 From: avdunn Date: Mon, 3 Nov 2025 10:53:28 -0800 Subject: [PATCH] Handle deprecation of WithExtraQueryParameters APIs in MSAL.NET --- .../net462/InternalAPI.Unshipped.txt | 1 + .../net472/InternalAPI.Unshipped.txt | 1 + .../net8.0/InternalAPI.Unshipped.txt | 1 + .../net9.0/InternalAPI.Unshipped.txt | 1 + .../netstandard2.0/InternalAPI.Unshipped.txt | 1 + .../TokenAcquisition.cs | 42 ++++++++++++------- .../TokenAcquisitionAuthorityTests.cs | 10 ++--- 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt index 7dc5c5811..62d5c481d 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Microsoft.Identity.Web.TokenAcquisition.MergeExtraQueryParameters(Microsoft.Identity.Web.MergedOptions! mergedOptions, Microsoft.Identity.Web.TokenAcquisitionOptions? tokenAcquisitionOptions) -> System.Collections.Generic.Dictionary? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt index 7dc5c5811..62d5c481d 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Microsoft.Identity.Web.TokenAcquisition.MergeExtraQueryParameters(Microsoft.Identity.Web.MergedOptions! mergedOptions, Microsoft.Identity.Web.TokenAcquisitionOptions? tokenAcquisitionOptions) -> System.Collections.Generic.Dictionary? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt index 7dc5c5811..62d5c481d 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Microsoft.Identity.Web.TokenAcquisition.MergeExtraQueryParameters(Microsoft.Identity.Web.MergedOptions! mergedOptions, Microsoft.Identity.Web.TokenAcquisitionOptions? tokenAcquisitionOptions) -> System.Collections.Generic.Dictionary? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt index 7dc5c5811..62d5c481d 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Microsoft.Identity.Web.TokenAcquisition.MergeExtraQueryParameters(Microsoft.Identity.Web.MergedOptions! mergedOptions, Microsoft.Identity.Web.TokenAcquisitionOptions? tokenAcquisitionOptions) -> System.Collections.Generic.Dictionary? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt index 7dc5c5811..62d5c481d 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt +++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +static Microsoft.Identity.Web.TokenAcquisition.MergeExtraQueryParameters(Microsoft.Identity.Web.MergedOptions! mergedOptions, Microsoft.Identity.Web.TokenAcquisitionOptions? tokenAcquisitionOptions) -> System.Collections.Generic.Dictionary? diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs index 2513b3270..45b0a4518 100644 --- a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs +++ b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs @@ -154,7 +154,7 @@ public async Task AddAccountToCacheFromAuthorizationCodeAsyn if (mergedOptions.ExtraQueryParameters != null) { - builder.WithExtraQueryParameters((Dictionary)mergedOptions.ExtraQueryParameters); + builder.WithExtraQueryParameters(MergeExtraQueryParameters(mergedOptions, null)); } if (!string.IsNullOrEmpty(authCodeRedemptionParameters.Tenant)) @@ -1145,8 +1145,8 @@ private void NotifyCertificateSelection( // Special case when the OBO inbound token is composite (for instance PFT) if (dict.ContainsKey(assertionConstant) && dict.ContainsKey(subAssertionConstant)) { - string assertion = dict[assertionConstant]; - string subAssertion = dict[subAssertionConstant]; + string assertion = dict[assertionConstant].value; + string subAssertion = dict[subAssertionConstant].value; // Check assertion and sub_assertion passed from merging extra query parameters to ensure they do not contain unsupported character(s). CheckAssertionsForInjectionAttempt(assertion, subAssertion); @@ -1164,7 +1164,6 @@ private void NotifyCertificateSelection( dict.Remove(assertionConstant); dict.Remove(subAssertionConstant); } - builder.WithExtraQueryParameters(dict); } if (tokenAcquisitionOptions.ExtraHeadersParameters != null) @@ -1362,25 +1361,40 @@ private Task GetAuthenticationResultForWebAppWithAccountFr return builder.ExecuteAsync(tokenAcquisitionOptions != null ? tokenAcquisitionOptions.CancellationToken : CancellationToken.None); } - internal static Dictionary? MergeExtraQueryParameters( + internal static Dictionary? MergeExtraQueryParameters( MergedOptions mergedOptions, - TokenAcquisitionOptions tokenAcquisitionOptions) + TokenAcquisitionOptions? tokenAcquisitionOptions) { - if (tokenAcquisitionOptions.ExtraQueryParameters != null) + // Return null if both sources are empty + if (tokenAcquisitionOptions?.ExtraQueryParameters == null && mergedOptions.ExtraQueryParameters == null) { - var mergedDict = new Dictionary(tokenAcquisitionOptions.ExtraQueryParameters); - if (mergedOptions.ExtraQueryParameters != null) + return null; + } + + var mergedDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + // Add from tokenAcquisitionOptions first (these take precedence) + if (tokenAcquisitionOptions?.ExtraQueryParameters != null) + { + foreach (var pair in tokenAcquisitionOptions.ExtraQueryParameters) + { + mergedDict[pair.Key] = (pair.Value, true); + } + } + + // Add from mergedOptions without overriding existing keys + if (mergedOptions.ExtraQueryParameters != null) + { + foreach (var pair in mergedOptions.ExtraQueryParameters) { - foreach (var pair in mergedOptions!.ExtraQueryParameters) + if (!mergedDict.ContainsKey(pair.Key)) { - if (!mergedDict!.ContainsKey(pair.Key)) - mergedDict.Add(pair.Key, pair.Value); + mergedDict.Add(pair.Key, (pair.Value, true)); } } - return mergedDict; } - return (Dictionary?)mergedOptions.ExtraQueryParameters; + return mergedDict; } protected static bool AcceptedTokenVersionMismatch(MsalUiRequiredException msalServiceException) diff --git a/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAuthorityTests.cs b/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAuthorityTests.cs index a516dd240..b998d57a2 100644 --- a/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAuthorityTests.cs +++ b/tests/Microsoft.Identity.Web.Test/TokenAcquisitionAuthorityTests.cs @@ -385,9 +385,9 @@ public void MergeExtraQueryParametersTest() // Assert Assert.Equal(3, mergedDict!.Count); - Assert.Equal("newvalue1", mergedDict["key1"]); - Assert.Equal("value2", mergedDict["key2"]); - Assert.Equal("value3", mergedDict["key3"]); + Assert.Equal("newvalue1", mergedDict["key1"].value); + Assert.Equal("value2", mergedDict["key2"].value); + Assert.Equal("value3", mergedDict["key3"].value); } [Fact] @@ -411,8 +411,8 @@ public void MergeExtraQueryParameters_TokenAcquisitionOptionsNull_Test() var mergedDict = TokenAcquisition.MergeExtraQueryParameters(mergedOptions, tokenAcquisitionOptions); // Assert - Assert.Equal("value1", mergedDict!["key1"]); - Assert.Equal("value2", mergedDict["key2"]); + Assert.Equal("value1", mergedDict!["key1"].value); + Assert.Equal("value2", mergedDict["key2"].value); } [Fact]