diff --git a/src/client/Microsoft.Identity.Client/Internal/ClientCredential/SignedAssertionDelegateClientCredential.cs b/src/client/Microsoft.Identity.Client/Internal/ClientCredential/SignedAssertionDelegateClientCredential.cs index 75a650cf40..b4031a223d 100644 --- a/src/client/Microsoft.Identity.Client/Internal/ClientCredential/SignedAssertionDelegateClientCredential.cs +++ b/src/client/Microsoft.Identity.Client/Internal/ClientCredential/SignedAssertionDelegateClientCredential.cs @@ -55,18 +55,18 @@ public async Task AddConfidentialClientParametersAsync( TokenEndpoint = tokenEndpoint }; - // Only set client capabilities if they exist and are not empty + // Set client capabilities var configuredCapabilities = requestParameters .RequestContext .ServiceBundle .Config .ClientCapabilities; - if (configuredCapabilities != null && configuredCapabilities.Any()) - { - assertionOptions.ClientCapabilities = configuredCapabilities; - } + assertionOptions.ClientCapabilities = configuredCapabilities; + //Set claims + assertionOptions.Claims = requestParameters.Claims; + // Delegate that uses AssertionRequestOptions string signedAssertion = await _signedAssertionWithInfoDelegate(assertionOptions).ConfigureAwait(false); diff --git a/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs b/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs index 147f3f2b20..db3d293d06 100644 --- a/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs @@ -2019,6 +2019,103 @@ public async Task ConfidentialClient_WithClaims_TestAsync() } } + [TestMethod] + public async Task SignedAssertionDelegateClientCredential_Claims_TestAsync() + { + using (var httpManager = new MockHttpManager()) + { + httpManager.AddInstanceDiscoveryMockHandler(); + + // Mock the expected response and ensure the claims parameter is included in the request + var handler = httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(); + handler.ExpectedPostData = new Dictionary() + { + { "claims", "{\"extra_claim\":\"value\"}" } + }; + + // Create ConfidentialClientApplication with a SignedAssertion delegate + var app = ConfidentialClientApplicationBuilder + .Create(TestConstants.ClientId) + .WithHttpManager(httpManager) + .WithClientAssertion(async (AssertionRequestOptions options) => + { + // Ensure that the claims were properly passed to the assertion options + Assert.AreEqual("{\"extra_claim\":\"value\"}", options.Claims); + return await Task.FromResult("dummy_assertion").ConfigureAwait(false); + }) + .BuildConcrete(); + + // Act: Acquire token with claims + var result = await app.AcquireTokenForClient(TestConstants.s_scope) + .WithClaims("{\"extra_claim\":\"value\"}") + .ExecuteAsync() + .ConfigureAwait(false); + + // Assert: Ensure we got a valid token + Assert.IsNotNull(result); + } + } + + [TestMethod] + public async Task SignedAssertionDelegateClientCredential_NoClaims_TestAsync() + { + using (var httpManager = new MockHttpManager()) + { + httpManager.AddInstanceDiscoveryMockHandler(); + + var handler = httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(); + handler.ExpectedPostData = new Dictionary(); + + var app = ConfidentialClientApplicationBuilder + .Create(TestConstants.ClientId) + .WithHttpManager(httpManager) + .WithClientAssertion(async (AssertionRequestOptions options) => + { + // Ensure claims are set when WithClaims is called + Assert.IsNull(options.Claims); + return await Task.FromResult("dummy_assertion").ConfigureAwait(false); + }) + .BuildConcrete(); + + var result = await app.AcquireTokenForClient(TestConstants.s_scope) + .ExecuteAsync() + .ConfigureAwait(false); + + Assert.IsNotNull(result); + Assert.IsFalse(handler.ActualRequestPostData.ContainsKey("claims")); + } + } + + [TestMethod] + public async Task SignedAssertionDelegateClientCredential_WithClaims_TestAsync() + { + using (var httpManager = new MockHttpManager()) + { + httpManager.AddInstanceDiscoveryMockHandler(); + + var handler = httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage(); + handler.ExpectedPostData = new Dictionary(); + + var app = ConfidentialClientApplicationBuilder + .Create(TestConstants.ClientId) + .WithHttpManager(httpManager) + .WithClientAssertion(async (AssertionRequestOptions options) => + { + // Ensure claims are NOT set when WithClaims is not called + Assert.IsNull(options.Claims); + return await Task.FromResult("dummy_assertion").ConfigureAwait(false); + }) + .BuildConcrete(); + + var result = await app.AcquireTokenForClient(TestConstants.s_scope) + .ExecuteAsync() + .ConfigureAwait(false); + + Assert.IsNotNull(result); + Assert.IsFalse(handler.ActualRequestPostData.ContainsKey("claims")); + } + } + [TestMethod] public async Task AcquireTokenByAuthorizationCode_NullOrEmptyCode_ThrowsAsync() {