Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public T WithClaims(string claims)
/// The string needs to be properly URL-encoded and ready to send as a string of segments of the form <c>key=value</c> separated by an ampersand character.
/// </param>
/// <returns>The builder to chain .With methods.</returns>
[Obsolete("This method is deprecated. Please use the WithExtraQueryParameters(IDictionary<string, (string value, bool includeInCacheKey)>) method instead, which provides control over which parameters are included in the cache key.", false)]
public T WithExtraQueryParameters(string extraQueryParameters)
{
if (!string.IsNullOrWhiteSpace(extraQueryParameters))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,49 @@ public T WithCorrelationId(Guid correlationId)
/// as a string of segments of the form <c>key=value</c> separated by an ampersand character.
/// The parameter can be null.</param>
/// <returns>The builder to chain the .With methods.</returns>
[Obsolete("This method is deprecated. Use the WithExtraQueryParameters(IDictionary<string, (string value, bool includeInCacheKey)>) method instead, which provides control over which parameters are included in the cache key.", false)]
public T WithExtraQueryParameters(Dictionary<string, string> extraQueryParameters)
{
CommonParameters.ExtraQueryParameters = extraQueryParameters ??
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
return WithExtraQueryParameters(CoreHelpers.ConvertToTupleParameters(extraQueryParameters));
}

/// <summary>
/// Sets Extra Query Parameters for the query string in the HTTP authentication request with control over which parameters are included in the cache key
/// </summary>
/// <param name="extraQueryParameters">This parameter will be appended as is to the query string in the HTTP authentication request to the authority, and merged with those added to the application-level WithExtraQueryParameters API.
/// Each dictionary entry maps a parameter name to a tuple containing:
/// - Value: The parameter value that will be appended to the query string
/// - IncludeInCacheKey: Whether this parameter should be included when computing the token's cache key.
/// To help ensure the correct token is returned from the cache, IncludeInCacheKey should be true if the parameter affects token content or validity (e.g., resource-specific claims or parameters).
/// The parameter can be null.</param>
/// <returns>The builder to chain .With methods.</returns>
public T WithExtraQueryParameters(IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be an experimental API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bgavrilMS can weigh in on this because I'm not sure how y'all decide what to put behind that experimental flag.

In our initial discussion we also planned on putting certain extensibility APIs behind the experimental flag, but it turned out the relevant API already was using it:

{
if (extraQueryParameters == null)
{
CommonParameters.ExtraQueryParameters = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should you also remove cache keys that were previously set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same as the current behavior:

public T WithExtraQueryParameters(Dictionary<string, string> extraQueryParameters)

If a null extraQueryParameters is passed in then CommonParameters.ExtraQueryParameters gets cleared. I just assumed it was a way of overriding the app-level extra query parameters or something like that, but are you saying that behavior might be a bug?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would clarify the behavior of this new API. Because this one adds the cache key, the previous one didn't.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What sort of clarification do you think it needs? The comments above it explain how to get the query parameters added to the cache key (set that boolean to true).

So if a customer passes in some parameters, we will add those parameters to the cache key. And if a customer passes in nothing, then we will add nothing to the cache key.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, to remove don't you need to add

else
{
    CommonParameters.CacheKeyComponents?.Remove(kvp.Key);
}

again, as I said - I am not looking into the requirements doc, I am just asking if this is a possibility. If you think this is not a valid case, ignore this comment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dictionary builds per request. I don't think we need remove.

Copy link
Contributor Author

@Avery-Dunn Avery-Dunn Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is per-request behavior, so if a customer changes what parameters should be used in the cache key then the new request will have a new cache entry, and the cache entry for the other request will be unaffected.

I just added WithExtraQueryParameters_VaryingCacheKeyInclusion_TestAsync to ExtraQueryParametersTests to show this behavior:

  1. Token request with param1 and param2, both included in the cache key
  2. Token request with param1 and param2 again, but only param1 in the cache key
  3. Token request with just param1, included in the cache key

Requests 1 and 2 result in different tokens even though they would have the same contents, but request 3 finds the token from request 2 even though they have different contents.

In short, the new API allows a caller to recreate the exact behavior that was a problem in the old API, where we aren't uniquely identifying a token based on the query parameters originally used to retrieve it.

However, I don't think this is something we need to fix: the API is meant to give the caller control over how tokens are identified in the cache, and if they want to keep turning the option on and off they then presumably they some reason for it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and the cache entry for the other request will be unaffected

how do we communicate this to the caller?

return this as T;
}

CommonParameters.ExtraQueryParameters = CommonParameters.ExtraQueryParameters ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

// Add each parameter to ExtraQueryParameters and, if requested, to CacheKeyComponents
foreach (var kvp in extraQueryParameters)
{
CommonParameters.ExtraQueryParameters[kvp.Key] = kvp.Value.Value;

if (kvp.Value.IncludeInCacheKey)
{
CommonParameters.CacheKeyComponents = CommonParameters.CacheKeyComponents ?? new SortedList<string, Func<CancellationToken, Task<string>>>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create the SortedList with a stable, case‑insensitive, ordinal comparer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a case sensitive test to validate this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is how the CacheKeyComponents field is set in other parts of the library:

builder.CommonParameters.CacheKeyComponents = new SortedList<string, Func<CancellationToken, Task<string>>>(cacheKeyComponents);

Is there a unique issue here, or should it also be fixed elsewhere? Making it more stable here would mean we each change the existing behavior elsewhere too, or make this version inconsistent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding a case sensitive test should validate if there are existing bugs in the code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the SortedList will use its default comparer if one is not specified. By default, this is Comparer.Default, which for string is StringComparer.Ordinal. The behavior will be same whether or not you add ordinal comparer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can validate this with test cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CommonParameters.CacheKeyComponents = CommonParameters.CacheKeyComponents ?? new SortedList<string, Func<CancellationToken, Task<string>>>();
CommonParameters.CacheKeyComponents ??=
new SortedList<string, Func<CancellationToken, Task<string>>>(StringComparer.OrdinalIgnoreCase);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this when I was first writing it, but as best as I can tell (through Copilot) the "??=" was only introduced in newer frameworks than we support, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, this should work in all current TFMs we have


// Capture the value in a local to avoid closure issues
string valueToCache = kvp.Value.Value;

// Add to cache key components - uses a func that returns the value as a task
CommonParameters.CacheKeyComponents[kvp.Key] = (CancellationToken _) => Task.FromResult(valueToCache);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can someone remove a cache key?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? Like remove a single, specific entry in the token cache?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something like,

Request 1 -
extra param 1 - include in cache = yes
extra param 2 - include in cache = yes

Request 2 -
extra param 1 - include in cache = yes
extra param 2 - include in cache = no

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone selects to not add the extra query param to the cache I think the cache key will be different for that request and the request will go to IDP

Copy link
Contributor Author

@Avery-Dunn Avery-Dunn Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #5536 (comment) for more context, but I I just added WithExtraQueryParameters_VaryingCacheKeyInclusion_TestAsync to ExtraQueryParametersTests to cover this behavior:

  1. Token request with param1 and param2, both included in the cache key
  2. Token request with param1 and param2 again, but only param1 in the cache key
  3. Token request with just param1, included in the cache key


return this as T;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,10 @@ protected T WithOptions(ApplicationOptions applicationOptions)
/// as a string of segments of the form <c>key=value</c> separated by an ampersand character.
/// The parameter can be null.</param>
/// <returns>The builder to chain the .With methods</returns>
[Obsolete("This method is deprecated. Please use the WithExtraQueryParameters(IDictionary<string, (string value, bool includeInCacheKey)>) method instead, which provides control over which parameters are included in the cache key.", false)]
public T WithExtraQueryParameters(IDictionary<string, string> extraQueryParameters)
{
Config.ExtraQueryParameters = extraQueryParameters;
return this as T;
return WithExtraQueryParameters(CoreHelpers.ConvertToTupleParameters(extraQueryParameters));
}

/// <summary>
Expand All @@ -305,6 +305,7 @@ public T WithExtraQueryParameters(IDictionary<string, string> extraQueryParamete
/// The string needs to be properly URL-encoded and ready to send as a string of segments of the form <c>key=value</c> separated by an ampersand character.
/// </param>
/// <returns></returns>
[Obsolete("This method is deprecated. Please use the WithExtraQueryParameters(IDictionary<string, (string value, bool includeInCacheKey)>) method instead, which provides control over which parameters are included in the cache key.", false)]
public T WithExtraQueryParameters(string extraQueryParameters)
{
if (!string.IsNullOrWhiteSpace(extraQueryParameters))
Expand All @@ -314,6 +315,44 @@ public T WithExtraQueryParameters(string extraQueryParameters)
return this as T;
}

/// <summary>
/// Sets Extra Query Parameters for the query string in the HTTP authentication request with control over which parameters are included in the cache key
/// </summary>
/// <param name="extraQueryParameters">This parameter will be appended as is to the query string in the HTTP authentication request to the authority, and merged with those added to the request-level WithExtraQueryParameters API.
/// Each dictionary entry maps a parameter name to a tuple containing:
/// - Value: The parameter value that will be appended to the query string
/// - IncludeInCacheKey: Whether this parameter should be included when computing the token's cache key.
/// To help ensure the correct token is returned from the cache, IncludeInCacheKey should be true if the parameter affects token content or validity (e.g., resource-specific claims or parameters).
/// The parameter can be null.</param>
/// <returns>The builder to chain .With methods.</returns>
public T WithExtraQueryParameters(IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters)
{
if (extraQueryParameters == null)
{
Config.ExtraQueryParameters = null;
return this as T;
}

// Add each parameter to ExtraQueryParameters and, if requested, to CacheKeyComponents
foreach (var kvp in extraQueryParameters)
{
Config.ExtraQueryParameters = Config.ExtraQueryParameters ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

Config.ExtraQueryParameters[kvp.Key] = kvp.Value.Value;

if (kvp.Value.IncludeInCacheKey)
{
// Initialize the cache key components if needed
Config.CacheKeyComponents = Config.CacheKeyComponents ?? new SortedList<string, string>();

// Add to cache key components - uses a func that returns the value as a task
Config.CacheKeyComponents[kvp.Key] = kvp.Value.Value;
}
}

return this as T;
}

/// <summary>
/// Microsoft Identity specific OIDC extension that allows resource challenges to be resolved without interaction.
/// Allows configuration of one or more client capabilities, e.g. "llt"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Abstractions" />
<PackageReference Include="System.ValueTuple" />
</ItemGroup>

<ItemGroup Label="For public api analyzer support">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Microsoft.Identity.Client.AbstractApplicationBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
Microsoft.Identity.Client.BaseAbstractAcquireTokenParameterBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
const Microsoft.Identity.Client.MsalError.CannotSwitchBetweenImdsVersionsForPreview = "cannot_switch_between_imds_versions_for_preview" -> string
const Microsoft.Identity.Client.MsalError.InvalidCertificate = "invalid_certificate" -> string
const Microsoft.Identity.Client.MsalError.MtlsNotSupportedForManagedIdentity = "mtls_not_supported_for_managed_identity" -> string
Expand All @@ -7,4 +9,4 @@ Microsoft.Identity.Client.IMsalMtlsHttpClientFactory.GetHttpClient(System.Securi
Microsoft.Identity.Client.ManagedIdentityApplication.GetManagedIdentitySourceAsync() -> System.Threading.Tasks.Task<Microsoft.Identity.Client.ManagedIdentity.ManagedIdentitySource>
Microsoft.Identity.Client.ManagedIdentity.ManagedIdentitySource.ImdsV2 = 8 -> Microsoft.Identity.Client.ManagedIdentity.ManagedIdentitySource
Microsoft.Identity.Client.ManagedIdentityApplicationBuilder.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, string> extraQueryParameters) -> Microsoft.Identity.Client.ManagedIdentityApplicationBuilder
static Microsoft.Identity.Client.ApplicationBase.ResetStateForTest() -> void
static Microsoft.Identity.Client.ApplicationBase.ResetStateForTest() -> void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be undone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why Github is marking that as a change, that line's the same as it is in the main branch: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/blob/main/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt

Maybe it's just because my lines went to the top instead of the bottom of the file? I just let it merge automatically.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Microsoft.Identity.Client.AbstractApplicationBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
Microsoft.Identity.Client.BaseAbstractAcquireTokenParameterBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
const Microsoft.Identity.Client.MsalError.CannotSwitchBetweenImdsVersionsForPreview = "cannot_switch_between_imds_versions_for_preview" -> string
const Microsoft.Identity.Client.MsalError.InvalidCertificate = "invalid_certificate" -> string
const Microsoft.Identity.Client.MsalError.MtlsNotSupportedForManagedIdentity = "mtls_not_supported_for_managed_identity" -> string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Microsoft.Identity.Client.AbstractApplicationBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
Microsoft.Identity.Client.BaseAbstractAcquireTokenParameterBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
const Microsoft.Identity.Client.MsalError.CannotSwitchBetweenImdsVersionsForPreview = "cannot_switch_between_imds_versions_for_preview" -> string
const Microsoft.Identity.Client.MsalError.InvalidCertificate = "invalid_certificate" -> string
const Microsoft.Identity.Client.MsalError.MtlsNotSupportedForManagedIdentity = "mtls_not_supported_for_managed_identity" -> string
Expand All @@ -7,4 +9,4 @@ Microsoft.Identity.Client.IMsalMtlsHttpClientFactory.GetHttpClient(System.Securi
Microsoft.Identity.Client.ManagedIdentityApplication.GetManagedIdentitySourceAsync() -> System.Threading.Tasks.Task<Microsoft.Identity.Client.ManagedIdentity.ManagedIdentitySource>
Microsoft.Identity.Client.ManagedIdentity.ManagedIdentitySource.ImdsV2 = 8 -> Microsoft.Identity.Client.ManagedIdentity.ManagedIdentitySource
Microsoft.Identity.Client.ManagedIdentityApplicationBuilder.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, string> extraQueryParameters) -> Microsoft.Identity.Client.ManagedIdentityApplicationBuilder
static Microsoft.Identity.Client.ApplicationBase.ResetStateForTest() -> void
static Microsoft.Identity.Client.ApplicationBase.ResetStateForTest() -> void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment like before

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as your other comment, that line here is exactly the same as in the main branch so I'm not sure why Github is saying it changed.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Microsoft.Identity.Client.AbstractApplicationBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
Microsoft.Identity.Client.BaseAbstractAcquireTokenParameterBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
const Microsoft.Identity.Client.MsalError.CannotSwitchBetweenImdsVersionsForPreview = "cannot_switch_between_imds_versions_for_preview" -> string
const Microsoft.Identity.Client.MsalError.InvalidCertificate = "invalid_certificate" -> string
const Microsoft.Identity.Client.MsalError.MtlsNotSupportedForManagedIdentity = "mtls_not_supported_for_managed_identity" -> string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Microsoft.Identity.Client.AbstractApplicationBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
Microsoft.Identity.Client.BaseAbstractAcquireTokenParameterBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
const Microsoft.Identity.Client.MsalError.CannotSwitchBetweenImdsVersionsForPreview = "cannot_switch_between_imds_versions_for_preview" -> string
const Microsoft.Identity.Client.MsalError.InvalidCertificate = "invalid_certificate" -> string
const Microsoft.Identity.Client.MsalError.MtlsNotSupportedForManagedIdentity = "mtls_not_supported_for_managed_identity" -> string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Microsoft.Identity.Client.AbstractApplicationBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
Microsoft.Identity.Client.BaseAbstractAcquireTokenParameterBuilder<T>.WithExtraQueryParameters(System.Collections.Generic.IDictionary<string, (string Value, bool IncludeInCacheKey)> extraQueryParameters) -> T
const Microsoft.Identity.Client.MsalError.CannotSwitchBetweenImdsVersionsForPreview = "cannot_switch_between_imds_versions_for_preview" -> string
const Microsoft.Identity.Client.MsalError.InvalidCertificate = "invalid_certificate" -> string
const Microsoft.Identity.Client.MsalError.MtlsNotSupportedForManagedIdentity = "mtls_not_supported_for_managed_identity" -> string
Expand Down
18 changes: 18 additions & 0 deletions src/client/Microsoft.Identity.Client/Utils/CoreHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ public static Dictionary<string, string> ParseKeyValueList(string input, char de
return ParseKeyValueList(input, delimiter, urlDecode, true, requestContext);
}

// 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)
{
if (parameters == null)
{
return null;
}

var result = new Dictionary<string, (string value, bool includeInCacheKey)>(StringComparer.OrdinalIgnoreCase);
foreach (var kvp in parameters)
{
result[kvp.Key] = (kvp.Value, false); // Exclude all parameters from cache key by default
}
return result;
}

internal static IReadOnlyList<string> SplitWithQuotes(string input, char delimiter)
{
if (string.IsNullOrWhiteSpace(input))
Expand Down
12 changes: 12 additions & 0 deletions tests/Microsoft.Identity.Test.Common/TestConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,18 @@ public static IDictionary<string, string> ExtraQueryParameters
};
}
}
public static IDictionary<string, (string, bool)> ExtraQueryParametersNoAffectOnCacheKeys
{
get
{
return new Dictionary<string, (string, bool)>(StringComparer.OrdinalIgnoreCase)
{
{ "extra", ("qp", false) },
{ "key1", ("value1%20with%20encoded%20space", false) },
{ "key2", ("value2", false) }
};
}
}

public const string MsalCCAKeyVaultUri = "https://id4skeyvault.vault.azure.net/secrets/AzureADIdentityDivisionTestAgentSecret/";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
Expand Down Expand Up @@ -58,7 +59,7 @@ private static async Task AgentUserIdentityGetsTokenForGraphAsync()
.WithAuthority("https://login.microsoftonline.com/", TenantId)
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
.WithExperimentalFeatures(true)
.WithExtraQueryParameters("slice=first")
.WithExtraQueryParameters(new Dictionary<string, (string value, bool includeInCacheKey)> { { "slice", ("first", false) } })
.WithClientAssertion((AssertionRequestOptions _) => GetAppCredentialAsync(AgentIdentity))
.Build();

Expand Down
Loading