- 
                Notifications
    
You must be signed in to change notification settings  - Fork 378
 
Adjust WithExtraQueryParameters APIs and cache key behavior #5536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… deprecate existing WithExtraQueryParameters APIs
        
          
                src/client/Microsoft.Identity.Client/ApiConfig/BaseAbstractAcquireTokenParameterBuilder.cs
              
                Outdated
          
            Show resolved
            Hide resolved
        
              
          
                src/client/Microsoft.Identity.Client/ApiConfig/BaseAbstractAcquireTokenParameterBuilder.cs
              
                Outdated
          
            Show resolved
            Hide resolved
        
      There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but the tuple in public API is not going to work
…uireTokenParameterBuilder.cs Co-authored-by: Bogdan Gavril <bogavril@microsoft.com>
        
          
                src/client/Microsoft.Identity.Client/ApiConfig/BaseAbstractAcquireTokenParameterBuilder.cs
              
                Outdated
          
            Show resolved
            Hide resolved
        
      There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, minor option
| CreateOrUpdatePublicClientApp(InteractiveAuthority, ApplicationId); | ||
| 
               | 
          ||
| AuthenticationResult result; | ||
| #pragma warning disable CS0618 // Type or member is obsolete | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe replace these with the new method and remove this line everywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the only file where I suppressed the warnings instead of making the actual change. Unlike all the other places, using the new API here would've meant multiple method signature changes, then changes to everything that referenced those methods, then changes to fields in different classes...
It was already started to be a big PR, and those suppressions seemed to be used in a lot of tests, so I figured I'd take a shortcut on this one test app.
        
          
                src/client/Microsoft.Identity.Client/ApiConfig/BaseAbstractAcquireTokenParameterBuilder.cs
              
                Outdated
          
            Show resolved
            Hide resolved
        
      | // Add each parameter to ExtraQueryParameters and, if requested, to CacheKeyComponents | ||
| foreach (var kvp in extraQueryParameters) | ||
| { | ||
| CommonParameters.ExtraQueryParameters = CommonParameters.ExtraQueryParameters ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, setting a value to itself seems like an odd way to check if something is null and then initializing it. It can be misleading potentially. I would simply add a normal if check.
if (CommonParameters.ExtraQueryParameters is null)
{...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One the one hand it does seem weird, but on the other hand I couldn't find any guidance saying not to do it like that.
However, after trying out the if statement option I don't think it made it more readable: since CommonParameters.CacheKeyComponents does the same thing a few lines down it'd be 3 if statements in one small method, some of which were wrapped up in a loop.
But I did move the null check/initialization outside of the for loop in the latest commit, since we don't need to do it multiple times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR addresses an issue where extra query parameters could affect token validity but were not included in cache keys, potentially causing invalid cached tokens to be returned when parameters changed between requests.
- Introduces a new 
WithExtraQueryParametersAPI acceptingIDictionary<string, (string value, bool includeInCacheKey)>for granular cache key control - Deprecates existing 
WithExtraQueryParametersmethods that accept string orIDictionary<string, string>parameters - Updates test code and dev apps to use the new API or suppress deprecation warnings
 
Reviewed Changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description | 
|---|---|
| tests/devapps/NetFxConsoleTestApp/Program.cs | Updated to use new tuple-based API | 
| tests/devapps/NetCoreTestApp/Program.cs | Updated to use new tuple-based API | 
| tests/devapps/DesktopTestApp/PublicClientHandler.cs | Added deprecation warning suppressions for old API usage | 
| tests/Microsoft.Identity.Test.Unit/TelemetryTests/OTelInstrumentationTests.cs | Updated tests to use new tuple-based API | 
| tests/Microsoft.Identity.Test.Unit/TelemetryTests/HttpTelemetryTests.cs | Updated tests to use new tuple-based API | 
| tests/Microsoft.Identity.Test.Unit/RequestsTests/IntegratedWindowsAuthUsernamePasswordTests.cs | Updated to use new test constant | 
| tests/Microsoft.Identity.Test.Unit/PublicApiTests/ExtraQueryParametersTests.cs | New test class demonstrating cache key behavior | 
| tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs | Updated to use new test constant | 
| tests/Microsoft.Identity.Test.Unit/PublicApiTests/CacheKeyExtensionTests.cs | Added tests for API interaction | 
| tests/Microsoft.Identity.Test.Unit/ParallelRequestsTests.cs | Updated to use new tuple-based API | 
| tests/Microsoft.Identity.Test.Unit/OAuthClientTests.cs | Updated to use new tuple-based API | 
| tests/Microsoft.Identity.Test.Unit/ApiConfigTests/AcquireTokenInteractiveBuilderTests.cs | Updated to use new tuple-based API | 
| tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/FmiIntegrationTests.cs | Updated integration tests to use new API | 
| tests/Microsoft.Identity.Test.Integration.netcore/HeadlessTests/Agentic.cs | Updated to use new tuple-based API | 
| tests/Microsoft.Identity.Test.Common/TestConstants.cs | Added new test constant for tuple-based parameters | 
| src/client/Microsoft.Identity.Client/Utils/CoreHelpers.cs | Added helper method to convert old dictionary format to new tuple format | 
| src/client/Microsoft.Identity.Client/PublicApi/*/PublicAPI.Unshipped.txt | Documents new public API methods | 
| src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj | Added System.ValueTuple package reference | 
| src/client/Microsoft.Identity.Client/AppConfig/AbstractApplicationBuilder.cs | Implemented new API and deprecated old ones | 
| src/client/Microsoft.Identity.Client/ApiConfig/BaseAbstractAcquireTokenParameterBuilder.cs | Implemented new API and deprecated old ones | 
| src/client/Microsoft.Identity.Client/ApiConfig/AbstractAcquireTokenParameterBuilder.cs | Deprecated old string-based API | 
        
          
                tests/Microsoft.Identity.Test.Unit/PublicApiTests/ExtraQueryParametersTests.cs
              
                Outdated
          
            Show resolved
            Hide resolved
        
      …rametersTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…b.com/AzureAD/microsoft-authentication-library-for-dotnet into avdunn/extra-query-params-api-changes
| // Helper method intended to help deprecate some WithExtraQueryParameters APIs. | ||
| // Convert from Dictionary<string, string> to Dictionary<string, (string value, bool includeInCacheKey)>, | ||
| // with all includeInCacheKey set to false by default to maintain existing behavior of those older APIs. | ||
| internal static IDictionary<string, (string value, bool includeInCacheKey)> ConvertToTupleParameters(IDictionary<string, string> parameters) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: It's not really a "core helper" and could be included in ApiConfig or AppConfig
btw, you can rewrite this in 1-liner
 return (parameters ?? Enumerable.Empty<KeyValuePair<string, string>>())
        .ToDictionary(
            kvp => kvp.Key,
            kvp => (kvp.Value, false),
            StringComparer.OrdinalIgnoreCase);
This PR is for KR 3310905 and issue #5361.
In short, there is a problem in our existing
WithExtraQueryParametersbehavior: the extra query parameters could affect tokens but were not used as part of the cache keys, so if theWithExtraQueryParametersvalues changed between requests we could return cached tokens that were not valid for the new request. However, simply adding the extra query parameters to the cache key would not work: it would break existing cache lookup behavior, and not all parameters should be cached.This PR tries to solve that problem with the following changes:
WithExtraQueryParametersthat takes in aIDictionary<string, (string value, bool includeInCacheKey)>CacheKeyComponentsfield, which already does the task of adding extra parameters to the cache keyBaseAbstractAcquireTokenParameterBuilder,AbstractApplicationBuilderWithExtraQueryParametersAPIs, and have them call the new API to set theExtraQueryParametersfieldsAbstractAcquireTokenParameterBuilder,BaseAbstractAcquireTokenParameterBuilder,AbstractApplicationBuilderCoreHelpersto covert the old Dictionary style to the new oneThis PR also adds some new tests to cover the new behavior, and makes some small changes to existing tests:
ExtraQueryParametersTests: A new test class with tests covering the new cache key behavior, as well as demonstrating the behavior of the deprecatedWithExtraQueryParametersAPIsCacheKeyExtensionTests: A new test to show the newWithExtraQueryParametersAPI does not conflict with the existingWithAdditionalCacheKeyComponentsAPI from the extensibility package