Skip to content
Merged
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
14 changes: 14 additions & 0 deletions src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,8 @@ public async Task<AuthenticationResult> GetAuthenticationResultForAppAsync(
builder.WithExtraHttpHeaders(tokenAcquisitionOptions.ExtraHeadersParameters);
}

AddExtraBodyParametersIfNeeded(tokenAcquisitionOptions, builder);

// Extra Parameters are not meant to be used by Token but by extensions

if (tokenAcquisitionOptions.CorrelationId != null)
Expand Down Expand Up @@ -688,6 +690,18 @@ public async Task<AuthenticationResult> GetAuthenticationResultForAppAsync(
}
}

private void AddExtraBodyParametersIfNeeded(TokenAcquisitionOptions tokenAcquisitionOptions, AcquireTokenForClientParameterBuilder builder)
{
if (tokenAcquisitionOptions.ExtraParameters != null
&& tokenAcquisitionOptions.ExtraParameters.TryGetValue("EXTRA_BODY_PARAMETERS", out object? parameters))
{
if (parameters is Dictionary<string, Func<CancellationToken, Task<string>>> keyValuePairs)
{
builder.WithExtraBodyParameters(keyValuePairs);
}
}
}

private MergedOptions GetMergedOptions(string? authenticationScheme, TokenAcquisitionOptions? tokenAcquisitionOptions)
{
MergedOptions mergedOptions;
Expand Down
71 changes: 71 additions & 0 deletions tests/Microsoft.Identity.Web.Test/TokenAcquisitionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Client;
using Microsoft.Identity.Web.Test.Common.Mocks;
using Microsoft.Identity.Web.TestOnly;
using Xunit;


namespace Microsoft.Identity.Web.Test
{
public class TokenAcquisitionTests
Expand Down Expand Up @@ -77,5 +86,67 @@ public void TestManagedIdentityWithCommonTenantShouldNotCallResolveTenant()
var exception = Assert.Throws<ArgumentException>(() => TokenAcquisition.ResolveTenant(null, mergedOptions));
Assert.StartsWith(IDWebErrorMessage.ClientCredentialTenantShouldBeTenanted, exception.Message, StringComparison.Ordinal);
}

[Fact]
public async Task ExtraBodyParametersAreSentToEndpointTest()
{
// Arrange
var tokenAcquirerFactory = InitTokenAcquirerFactory();
IServiceProvider serviceProvider = tokenAcquirerFactory.Build();
var mockHttpClient = serviceProvider.GetRequiredService<IMsalHttpClientFactory>() as MockHttpClientFactory;

mockHttpClient!.AddMockHandler(MockHttpCreator.CreateHandlerToValidatePostData(
HttpMethod.Post,
new Dictionary<string, string>() {
{ "custom_param1", "value1" },
{ "custom_param2", "value2" }
}));

IAuthorizationHeaderProvider authorizationHeaderProvider = serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>();

var options = new AcquireTokenOptions();
options.ExtraParameters = new Dictionary<string, object>
{
{ "EXTRA_BODY_PARAMETERS", new Dictionary<string, Func<CancellationToken, Task<string>>>
{
["custom_param1"] = _ => Task.FromResult("value1"),
["custom_param2"] = _ => Task.FromResult("value2")
}
}
};

// Act
string result = await authorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync("https://graph.microsoft.com/.default",
new AuthorizationHeaderProviderOptions() { AcquireTokenOptions = options });

// Assert
Assert.NotNull(result);
Assert.Equal("Bearer header.payload.signature", result);
}

private TokenAcquirerFactory InitTokenAcquirerFactory()
{
TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest();
TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Services.Configure<MicrosoftIdentityApplicationOptions>(options =>
{
options.Instance = "https://login.microsoftonline.com/";
options.TenantId = "f645ad92-e38d-4d1a-b510-d1b09a74a8ca";
options.ClientId = "idu773ld-e38d-jud3-45lk-d1b09a74a8ca";
options.ExtraQueryParameters = new Dictionary<string, string>
{
{ "dc", "ESTS-PUB-SCUS-LZ1-FD000-TEST1" }
};
options.ClientCredentials = [ new CredentialDescription() {
SourceType = CredentialSource.ClientSecret,
ClientSecret = "someSecret"
}];
});

// Add MockedHttpClientFactory
tokenAcquirerFactory.Services.AddSingleton<IMsalHttpClientFactory, MockHttpClientFactory>();

return tokenAcquirerFactory;
}
}
}
Loading