Skip to content

Commit 0beac66

Browse files
Copilotgladjohn
andauthored
Validate clientSignedAssertionProvider delegate is non-null in WithClientAssertion (#5956)
* Initial plan * Add null validation for clientSignedAssertionProvider in WithClientAssertion overload Agent-Logs-Url: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/sessions/4fd64a97-abf2-426f-aade-9b0760d58220 Co-authored-by: gladjohn <90415114+gladjohn@users.noreply.github.com> * Move null check before ValidateUseOfExperimentalFeature in WithClientAssertion Agent-Logs-Url: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/sessions/8a0460fe-58a4-4df1-8ed6-c46df4c6da03 Co-authored-by: gladjohn <90415114+gladjohn@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gladjohn <90415114+gladjohn@users.noreply.github.com>
1 parent 36e0c6b commit 0beac66

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

src/client/Microsoft.Identity.Client/AppConfig/ConfidentialClientApplicationBuilder.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,17 @@ public ConfidentialClientApplicationBuilder WithClientAssertion(Func<AssertionRe
329329
/// langword="null"/>.</param>
330330
/// <returns>The <see cref="ConfidentialClientApplicationBuilder"/> instance configured with the specified client
331331
/// assertion.</returns>
332-
/// <exception cref="MsalClientException">Thrown if <paramref name="clientSignedAssertionProvider"/> is <see langword="null"/>.</exception>
332+
/// <exception cref="ArgumentNullException">Thrown if <paramref name="clientSignedAssertionProvider"/> is <see langword="null"/>.</exception>
333333
public ConfidentialClientApplicationBuilder WithClientAssertion(Func<AssertionRequestOptions,
334334
CancellationToken, Task<ClientSignedAssertion>> clientSignedAssertionProvider)
335335
{
336+
if (clientSignedAssertionProvider == null)
337+
{
338+
throw new ArgumentNullException(nameof(clientSignedAssertionProvider));
339+
}
340+
336341
ValidateUseOfExperimentalFeature();
342+
337343
return WithClientAssertionInternal(
338344
clientSignedAssertionProvider: clientSignedAssertionProvider);
339345
}

tests/Microsoft.Identity.Test.Unit/PublicApiTests/ClientAssertionTests.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,29 @@ await AssertException.TaskThrowsAsync<MsalClientException>(() =>
482482
.ConfigureAwait(false);
483483
}
484484

485+
[TestMethod]
486+
public void ClientAssertion_NullClientSignedAssertionProvider_ThrowsArgumentNullException()
487+
{
488+
Func<AssertionRequestOptions, CancellationToken, Task<ClientSignedAssertion>> provider = null;
489+
490+
// Null check must occur before ValidateUseOfExperimentalFeature(), so passing null
491+
// without enabling experimental features should still surface ArgumentNullException
492+
// rather than MsalClientException.
493+
var ex = AssertException.Throws<ArgumentNullException>(() =>
494+
ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
495+
.WithClientAssertion(provider));
496+
497+
Assert.AreEqual("clientSignedAssertionProvider", ex.ParamName);
498+
499+
// Also verify the same when experimental features are explicitly enabled.
500+
var ex2 = AssertException.Throws<ArgumentNullException>(() =>
501+
ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
502+
.WithExperimentalFeatures(true)
503+
.WithClientAssertion(provider));
504+
505+
Assert.AreEqual("clientSignedAssertionProvider", ex2.ParamName);
506+
}
507+
485508
[TestMethod]
486509
public async Task ClientAssertion_CancellationTokenPropagatesAsync()
487510
{

0 commit comments

Comments
 (0)