diff --git a/Directory.Build.props b/Directory.Build.props
index f32f61f62..a490d7512 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -175,4 +175,8 @@
runtime; build; native; contentfiles; analyzers
+
+
+ $(DefineConstants);SUPPORTS_MTLS;
+
diff --git a/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs b/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
index 4886ebc82..d506c3bd8 100644
--- a/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
+++ b/src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
@@ -9,6 +9,7 @@
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Security.Claims;
+using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
@@ -25,7 +26,7 @@ namespace Microsoft.Identity.Web
internal partial class DownstreamApi : IDownstreamApi
{
private readonly IAuthorizationHeaderProvider _authorizationHeaderProvider;
- private readonly IHttpClientFactory _httpClientFactory;
+ private readonly IMsalHttpClientFactory _httpClientFactory;
private readonly IOptionsMonitor _namedDownstreamApiOptions;
private const string Authorization = "Authorization";
protected readonly ILogger _logger;
@@ -36,17 +37,17 @@ internal partial class DownstreamApi : IDownstreamApi
///
/// Authorization header provider.
/// Named options provider.
- /// HTTP client factory.
+ /// MSAL HTTP client factory.
/// Logger.
public DownstreamApi(
IAuthorizationHeaderProvider authorizationHeaderProvider,
IOptionsMonitor namedDownstreamApiOptions,
- IHttpClientFactory httpClientFactory,
+ IMsalHttpClientFactory msalHttpClientFactory,
ILogger logger)
{
_authorizationHeaderProvider = authorizationHeaderProvider;
_namedDownstreamApiOptions = namedDownstreamApiOptions;
- _httpClientFactory = httpClientFactory;
+ _httpClientFactory = msalHttpClientFactory;
_logger = logger;
}
@@ -514,11 +515,13 @@ public Task CallApiForAppAsync(
new HttpMethod(effectiveOptions.HttpMethod),
apiUrl);
- await UpdateRequestAsync(httpRequestMessage, content, effectiveOptions, appToken, user, cancellationToken);
+ var authorizationHeaderInformation = await UpdateRequestAsync(httpRequestMessage, content, effectiveOptions, appToken, user, cancellationToken);
- using HttpClient client = string.IsNullOrEmpty(serviceName) ? _httpClientFactory.CreateClient() : _httpClientFactory.CreateClient(serviceName);
+ using HttpClient client = _httpClientFactory is IMsalMtlsHttpClientFactory msalMtlsHttpClientFactory && authorizationHeaderInformation ?.BindingCertificate != null
+ ? msalMtlsHttpClientFactory.GetHttpClient(authorizationHeaderInformation.BindingCertificate)
+ : _httpClientFactory.GetHttpClient();
- // Send the HTTP message
+ // Send the HTTP message
var downstreamApiResult = await client.SendAsync(httpRequestMessage, cancellationToken).ConfigureAwait(false);
// Retry only if the resource sent 401 Unauthorized with WWW-Authenticate header and claims
@@ -541,7 +544,7 @@ public Task CallApiForAppAsync(
return downstreamApiResult;
}
- internal /* internal for test */ async Task UpdateRequestAsync(
+ internal /* internal for test */ async Task UpdateRequestAsync(
HttpRequestMessage httpRequestMessage,
HttpContent? content,
DownstreamApiOptions effectiveOptions,
@@ -558,16 +561,19 @@ public Task CallApiForAppAsync(
effectiveOptions.RequestAppToken = appToken;
+ AuthorizationHeaderInformation? authorizationHeaderInformation = null;
+
// Obtention of the authorization header (except when calling an anonymous endpoint
// which is done by not specifying any scopes
if (effectiveOptions.Scopes != null && effectiveOptions.Scopes.Any())
{
- string authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderAsync(
+ authorizationHeaderInformation = await _authorizationHeaderProvider.CreateAuthorizationHeaderAsync(
effectiveOptions.Scopes,
effectiveOptions,
user,
cancellationToken).ConfigureAwait(false);
+ var authorizationHeader = authorizationHeaderInformation.AuthorizationHeaderValue!;
if (authorizationHeader.StartsWith(AuthSchemeDstsSamlBearer, StringComparison.OrdinalIgnoreCase))
{
// TryAddWithoutValidation method bypasses strict validation, allowing non-standard headers to be added for custom Header schemes that cannot be parsed.
@@ -625,6 +631,8 @@ public Task CallApiForAppAsync(
// Opportunity to change the request message
effectiveOptions.CustomizeHttpRequestMessage?.Invoke(httpRequestMessage);
+
+ return authorizationHeaderInformation;
}
internal /* for test */ static Dictionary CallerSDKDetails { get; } = new()
diff --git a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net462/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net462/InternalAPI.Unshipped.txt
index 7dc5c5811..4697d02e4 100644
--- a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net462/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net462/InternalAPI.Unshipped.txt
@@ -1 +1,3 @@
#nullable enable
+Microsoft.Identity.Web.DownstreamApi.DownstreamApi(Microsoft.Identity.Abstractions.IAuthorizationHeaderProvider! authorizationHeaderProvider, Microsoft.Extensions.Options.IOptionsMonitor! namedDownstreamApiOptions, Microsoft.Identity.Client.IMsalHttpClientFactory! msalHttpClientFactory, Microsoft.Extensions.Logging.ILogger! logger) -> void
+Microsoft.Identity.Web.DownstreamApi.UpdateRequestAsync(System.Net.Http.HttpRequestMessage! httpRequestMessage, System.Net.Http.HttpContent? content, Microsoft.Identity.Abstractions.DownstreamApiOptions! effectiveOptions, bool appToken, System.Security.Claims.ClaimsPrincipal? user, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net472/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net472/InternalAPI.Unshipped.txt
index 7dc5c5811..4697d02e4 100644
--- a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net472/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net472/InternalAPI.Unshipped.txt
@@ -1 +1,3 @@
#nullable enable
+Microsoft.Identity.Web.DownstreamApi.DownstreamApi(Microsoft.Identity.Abstractions.IAuthorizationHeaderProvider! authorizationHeaderProvider, Microsoft.Extensions.Options.IOptionsMonitor! namedDownstreamApiOptions, Microsoft.Identity.Client.IMsalHttpClientFactory! msalHttpClientFactory, Microsoft.Extensions.Logging.ILogger! logger) -> void
+Microsoft.Identity.Web.DownstreamApi.UpdateRequestAsync(System.Net.Http.HttpRequestMessage! httpRequestMessage, System.Net.Http.HttpContent? content, Microsoft.Identity.Abstractions.DownstreamApiOptions! effectiveOptions, bool appToken, System.Security.Claims.ClaimsPrincipal? user, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net8.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net8.0/InternalAPI.Unshipped.txt
index 7dc5c5811..4697d02e4 100644
--- a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net8.0/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net8.0/InternalAPI.Unshipped.txt
@@ -1 +1,3 @@
#nullable enable
+Microsoft.Identity.Web.DownstreamApi.DownstreamApi(Microsoft.Identity.Abstractions.IAuthorizationHeaderProvider! authorizationHeaderProvider, Microsoft.Extensions.Options.IOptionsMonitor! namedDownstreamApiOptions, Microsoft.Identity.Client.IMsalHttpClientFactory! msalHttpClientFactory, Microsoft.Extensions.Logging.ILogger! logger) -> void
+Microsoft.Identity.Web.DownstreamApi.UpdateRequestAsync(System.Net.Http.HttpRequestMessage! httpRequestMessage, System.Net.Http.HttpContent? content, Microsoft.Identity.Abstractions.DownstreamApiOptions! effectiveOptions, bool appToken, System.Security.Claims.ClaimsPrincipal? user, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net9.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net9.0/InternalAPI.Unshipped.txt
index 7dc5c5811..4697d02e4 100644
--- a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net9.0/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/net9.0/InternalAPI.Unshipped.txt
@@ -1 +1,3 @@
#nullable enable
+Microsoft.Identity.Web.DownstreamApi.DownstreamApi(Microsoft.Identity.Abstractions.IAuthorizationHeaderProvider! authorizationHeaderProvider, Microsoft.Extensions.Options.IOptionsMonitor! namedDownstreamApiOptions, Microsoft.Identity.Client.IMsalHttpClientFactory! msalHttpClientFactory, Microsoft.Extensions.Logging.ILogger! logger) -> void
+Microsoft.Identity.Web.DownstreamApi.UpdateRequestAsync(System.Net.Http.HttpRequestMessage! httpRequestMessage, System.Net.Http.HttpContent? content, Microsoft.Identity.Abstractions.DownstreamApiOptions! effectiveOptions, bool appToken, System.Security.Claims.ClaimsPrincipal? user, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt
index 7dc5c5811..4697d02e4 100644
--- a/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.DownstreamApi/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt
@@ -1 +1,3 @@
#nullable enable
+Microsoft.Identity.Web.DownstreamApi.DownstreamApi(Microsoft.Identity.Abstractions.IAuthorizationHeaderProvider! authorizationHeaderProvider, Microsoft.Extensions.Options.IOptionsMonitor! namedDownstreamApiOptions, Microsoft.Identity.Client.IMsalHttpClientFactory! msalHttpClientFactory, Microsoft.Extensions.Logging.ILogger! logger) -> void
+Microsoft.Identity.Web.DownstreamApi.UpdateRequestAsync(System.Net.Http.HttpRequestMessage! httpRequestMessage, System.Net.Http.HttpContent? content, Microsoft.Identity.Abstractions.DownstreamApiOptions! effectiveOptions, bool appToken, System.Security.Claims.ClaimsPrincipal? user, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs b/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs
index 947a44770..208160678 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/BaseAuthorizationHeaderProvider.cs
@@ -33,19 +33,19 @@ public BaseAuthorizationHeaderProvider(IServiceProvider serviceProvider)
private readonly IAuthorizationHeaderProvider _headerProvider;
///
- public virtual Task CreateAuthorizationHeaderForUserAsync(IEnumerable scopes, AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, ClaimsPrincipal? claimsPrincipal = null, CancellationToken cancellationToken = default)
+ public virtual Task CreateAuthorizationHeaderForUserAsync(IEnumerable scopes, AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, ClaimsPrincipal? claimsPrincipal = null, CancellationToken cancellationToken = default)
{
return _headerProvider.CreateAuthorizationHeaderForUserAsync(scopes, authorizationHeaderProviderOptions, claimsPrincipal, cancellationToken);
}
///
- public virtual Task CreateAuthorizationHeaderForAppAsync(string scopes, AuthorizationHeaderProviderOptions? downstreamApiOptions = null, CancellationToken cancellationToken = default)
+ public virtual Task CreateAuthorizationHeaderForAppAsync(string scopes, AuthorizationHeaderProviderOptions? downstreamApiOptions = null, CancellationToken cancellationToken = default)
{
return _headerProvider.CreateAuthorizationHeaderForAppAsync(scopes, downstreamApiOptions, cancellationToken);
}
///
- public virtual Task CreateAuthorizationHeaderAsync(
+ public virtual Task CreateAuthorizationHeaderAsync(
IEnumerable scopes,
AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null,
ClaimsPrincipal? claimsPrincipal = null,
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/ConfidentialClientApplicationBuilderExtension.cs b/src/Microsoft.Identity.Web.TokenAcquisition/ConfidentialClientApplicationBuilderExtension.cs
index 324f0e458..43382eba9 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/ConfidentialClientApplicationBuilderExtension.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/ConfidentialClientApplicationBuilderExtension.cs
@@ -30,7 +30,8 @@ public static async Task WithClientCredent
IEnumerable clientCredentials,
ILogger logger,
ICredentialsLoader credentialsLoader,
- CredentialSourceLoaderParameters? credentialSourceLoaderParameters)
+ CredentialSourceLoaderParameters? credentialSourceLoaderParameters,
+ bool isTokenBinding = false)
{
var credential = await LoadCredentialForMsalOrFailAsync(
clientCredentials,
@@ -44,6 +45,17 @@ public static async Task WithClientCredent
return builder;
}
+ // regardless of credential type being set, bound token requires a certificate
+ if (isTokenBinding)
+ {
+ if (credential.Certificate == null)
+ {
+ logger.LogError("Loaded credentials for token binding doesn't contain a certificate");
+ }
+
+ return builder.WithCertificate(credential.Certificate);
+ }
+
switch (credential.CredentialType)
{
case CredentialType.SignedAssertion:
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs b/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs
index a3db6ad04..3467eec70 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/DefaultAuthorizationHeaderProvider.cs
@@ -21,7 +21,7 @@ public DefaultAuthorizationHeaderProvider(ITokenAcquisition tokenAcquisition)
}
///
- public async Task CreateAuthorizationHeaderForUserAsync(
+ public async Task CreateAuthorizationHeaderForUserAsync(
IEnumerable scopes,
AuthorizationHeaderProviderOptions? downstreamApiOptions = null,
ClaimsPrincipal? claimsPrincipal = null,
@@ -41,7 +41,7 @@ public async Task CreateAuthorizationHeaderForUserAsync(
}
///
- public async Task CreateAuthorizationHeaderForAppAsync(
+ public async Task CreateAuthorizationHeaderForAppAsync(
string scopes,
AuthorizationHeaderProviderOptions? downstreamApiOptions = null,
CancellationToken cancellationToken = default)
@@ -56,7 +56,7 @@ public async Task CreateAuthorizationHeaderForAppAsync(
}
///
- public async Task CreateAuthorizationHeaderAsync(
+ public async Task CreateAuthorizationHeaderAsync(
IEnumerable scopes,
AuthorizationHeaderProviderOptions? downstreamApiOptions = null,
ClaimsPrincipal? claimsPrincipal = null,
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/MsalMtlsHttpClientFactory.cs b/src/Microsoft.Identity.Web.TokenAcquisition/MsalMtlsHttpClientFactory.cs
new file mode 100644
index 000000000..7544aa0d6
--- /dev/null
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/MsalMtlsHttpClientFactory.cs
@@ -0,0 +1,120 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Concurrent;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Security.Cryptography.X509Certificates;
+using Microsoft.Identity.Client;
+
+namespace Microsoft.Identity.Web
+{
+ ///
+ /// Provides a factory for creating HTTP clients configured for mTLS authentication with using binding certificate.
+ /// It uses a hybrid approach with leveraging IHttpClientFactory for non-mTLS HTTL clients and maintaining
+ /// a pool of mTLS clients with using certificate as a key.
+ ///
+ public sealed class MsalMtlsHttpClientFactory : IMsalMtlsHttpClientFactory
+ {
+ private const long MaxMtlsHttpClientCountInPool = 1000;
+ private const long MaxResponseContentBufferSizeInBytes = 1024 * 1024;
+
+ // Please see (https://aka.ms/msal-httpclient-info) for important information regarding the HttpClient.
+ private static readonly ConcurrentDictionary s_mtlsHttpClientPool = new ConcurrentDictionary();
+ private static readonly object s_cacheLock = new object();
+
+ private readonly IHttpClientFactory _httpClientFactory;
+
+ ///
+ /// Initializes a new instance of the MsalMtlsHttpClientFactory class using the specified HTTP client factory.
+ ///
+ /// The factory used to create HttpClient instances for mutual TLS (mTLS) operations. Cannot be null.
+ public MsalMtlsHttpClientFactory(IHttpClientFactory httpClientFactory)
+ {
+ _httpClientFactory = httpClientFactory;
+ }
+
+ ///
+ /// Creates and configures a new instance of with telemetry headers applied.
+ ///
+ ///
+ /// The returned includes a telemetry header for tracking or
+ /// diagnostics purposes. Callers are responsible for disposing the instance when it is
+ /// no longer needed.
+ ///
+ /// A new instance with telemetry information included in the default request headers.
+ public HttpClient GetHttpClient()
+ {
+ HttpClient httpClient = _httpClientFactory.CreateClient();
+ httpClient.DefaultRequestHeaders.Add(Constants.TelemetryHeaderKey, IdHelper.CreateTelemetryInfo());
+ return httpClient;
+ }
+
+ ///
+ /// Returns an instance of configured to use the specified X.509 client certificate for
+ /// mutual TLS authentication.
+ ///
+ ///
+ /// The returned instance is pooled and reused for the given certificate.
+ /// The client includes a telemetry header in each request. Callers should not modify the default
+ /// request headers or dispose the returned instance.
+ ///
+ /// The X.509 certificate to use for client authentication. If , a default instance without client certificate authentication is returned.
+ /// A instance configured for mutual TLS authentication using the specified certificate or default instance.
+ public HttpClient GetHttpClient(X509Certificate2 x509Certificate2)
+ {
+ if (x509Certificate2 == null)
+ {
+ return GetHttpClient();
+ }
+
+ string key = x509Certificate2.Thumbprint;
+ HttpClient httpClient = CreateMtlsHttpClient(x509Certificate2);
+ httpClient = s_mtlsHttpClientPool.GetOrAdd(key, httpClient);
+ httpClient.DefaultRequestHeaders.Add(Constants.TelemetryHeaderKey, IdHelper.CreateTelemetryInfo());
+ return httpClient;
+ }
+
+ private HttpClient CreateMtlsHttpClient(X509Certificate2 bindingCertificate)
+ {
+#if SUPPORTS_MTLS
+ CheckAndManageCache();
+
+ if (bindingCertificate == null)
+ {
+ throw new ArgumentNullException(nameof(bindingCertificate), "A valid X509 certificate must be provided for mTLS.");
+ }
+
+ HttpClientHandler handler = new();
+ handler.ClientCertificates.Add(bindingCertificate);
+
+ // HTTP client factory can't be used there because HTTP client handler needs to be configured
+ // before a HTTP client instance is created
+ var httpClient = new HttpClient(handler);
+ ConfigureRequestHeadersAndSize(httpClient);
+ return httpClient;
+#else
+ throw new NotSupportedException("mTLS is not supported on this platform.");
+#endif
+ }
+
+ private static void CheckAndManageCache()
+ {
+ lock (s_cacheLock)
+ {
+ if (s_mtlsHttpClientPool.Count >= 1000)
+ {
+ s_mtlsHttpClientPool.Clear();
+ }
+ }
+ }
+
+ private static void ConfigureRequestHeadersAndSize(HttpClient httpClient)
+ {
+ httpClient.MaxResponseContentBufferSize = MaxResponseContentBufferSizeInBytes;
+ httpClient.DefaultRequestHeaders.Accept.Clear();
+ httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+ }
+ }
+}
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt
index 7dc5c5811..f2fa32ead 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/InternalAPI.Unshipped.txt
@@ -1 +1,5 @@
#nullable enable
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ConfidentialClientApplicationBuilderExtension.WithClientCredentialsAsync(this Microsoft.Identity.Client.ConfidentialClientApplicationBuilder! builder, System.Collections.Generic.IEnumerable! clientCredentials, Microsoft.Extensions.Logging.ILogger! logger, Microsoft.Identity.Abstractions.ICredentialsLoader! credentialsLoader, Microsoft.Identity.Abstractions.CredentialSourceLoaderParameters? credentialSourceLoaderParameters, bool isTokenBinding = false) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Shipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Shipped.txt
index fbcd9c5aa..7ba4c692c 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Shipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Shipped.txt
@@ -155,7 +155,6 @@ Microsoft.Identity.Web.TokenAcquisitionOptions.PoPConfiguration.set -> void
Microsoft.Identity.Web.TokenAcquisitionOptions.TokenAcquisitionOptions() -> void
static Microsoft.Identity.Web.Internal.WebApiBuilders.EnableTokenAcquisition(System.Action! configureConfidentialClientApplicationOptions, string! authenticationScheme, Microsoft.Extensions.DependencyInjection.IServiceCollection! services, Microsoft.Extensions.Configuration.IConfigurationSection? configuration) -> Microsoft.Identity.Web.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder!
static Microsoft.Identity.Web.PrincipalExtensionsForSecurityTokens.GetBootstrapToken(this System.Security.Principal.IPrincipal! claimsPrincipal) -> Microsoft.IdentityModel.Tokens.SecurityToken?
-static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
static Microsoft.Identity.Web.TestOnly.TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest() -> void
static Microsoft.Identity.Web.TokenAcquirerExtensions.GetFicTokenAsync(this Microsoft.Identity.Abstractions.ITokenAcquirer! tokenAcquirer, Microsoft.Identity.Abstractions.AcquireTokenOptions? options = null, string? clientAssertion = null, string! scope = "api://AzureAdTokenExchange/.default", System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
static Microsoft.Identity.Web.TokenAcquirerExtensions.WithClientAssertion(this Microsoft.Identity.Abstractions.AcquireTokenOptions! options, string! clientAssertion) -> Microsoft.Identity.Abstractions.AcquireTokenOptions!
@@ -164,8 +163,5 @@ static Microsoft.Identity.Web.TokenAcquirerFactory.GetDefaultInstance(string!
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForApp.Invoke(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUserAsync.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.DefineConfiguration(Microsoft.Extensions.Configuration.IConfigurationBuilder! builder) -> string!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.PreBuild() -> void
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt
index 7dc5c5811..5469ce14a 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt
@@ -1 +1,9 @@
#nullable enable
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient() -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2! x509Certificate2) -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.MsalMtlsHttpClientFactory(System.Net.Http.IHttpClientFactory! httpClientFactory) -> void
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false, bool isTokenBinding = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt
index 7dc5c5811..f2fa32ead 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/InternalAPI.Unshipped.txt
@@ -1 +1,5 @@
#nullable enable
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ConfidentialClientApplicationBuilderExtension.WithClientCredentialsAsync(this Microsoft.Identity.Client.ConfidentialClientApplicationBuilder! builder, System.Collections.Generic.IEnumerable! clientCredentials, Microsoft.Extensions.Logging.ILogger! logger, Microsoft.Identity.Abstractions.ICredentialsLoader! credentialsLoader, Microsoft.Identity.Abstractions.CredentialSourceLoaderParameters? credentialSourceLoaderParameters, bool isTokenBinding = false) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Shipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Shipped.txt
index fbcd9c5aa..7ba4c692c 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Shipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Shipped.txt
@@ -155,7 +155,6 @@ Microsoft.Identity.Web.TokenAcquisitionOptions.PoPConfiguration.set -> void
Microsoft.Identity.Web.TokenAcquisitionOptions.TokenAcquisitionOptions() -> void
static Microsoft.Identity.Web.Internal.WebApiBuilders.EnableTokenAcquisition(System.Action! configureConfidentialClientApplicationOptions, string! authenticationScheme, Microsoft.Extensions.DependencyInjection.IServiceCollection! services, Microsoft.Extensions.Configuration.IConfigurationSection? configuration) -> Microsoft.Identity.Web.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder!
static Microsoft.Identity.Web.PrincipalExtensionsForSecurityTokens.GetBootstrapToken(this System.Security.Principal.IPrincipal! claimsPrincipal) -> Microsoft.IdentityModel.Tokens.SecurityToken?
-static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
static Microsoft.Identity.Web.TestOnly.TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest() -> void
static Microsoft.Identity.Web.TokenAcquirerExtensions.GetFicTokenAsync(this Microsoft.Identity.Abstractions.ITokenAcquirer! tokenAcquirer, Microsoft.Identity.Abstractions.AcquireTokenOptions? options = null, string? clientAssertion = null, string! scope = "api://AzureAdTokenExchange/.default", System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
static Microsoft.Identity.Web.TokenAcquirerExtensions.WithClientAssertion(this Microsoft.Identity.Abstractions.AcquireTokenOptions! options, string! clientAssertion) -> Microsoft.Identity.Abstractions.AcquireTokenOptions!
@@ -164,8 +163,5 @@ static Microsoft.Identity.Web.TokenAcquirerFactory.GetDefaultInstance(string!
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForApp.Invoke(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUserAsync.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.DefineConfiguration(Microsoft.Extensions.Configuration.IConfigurationBuilder! builder) -> string!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.PreBuild() -> void
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt
index 7dc5c5811..5469ce14a 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt
@@ -1 +1,9 @@
#nullable enable
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient() -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2! x509Certificate2) -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.MsalMtlsHttpClientFactory(System.Net.Http.IHttpClientFactory! httpClientFactory) -> void
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false, bool isTokenBinding = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt
index 7dc5c5811..f2fa32ead 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/InternalAPI.Unshipped.txt
@@ -1 +1,5 @@
#nullable enable
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ConfidentialClientApplicationBuilderExtension.WithClientCredentialsAsync(this Microsoft.Identity.Client.ConfidentialClientApplicationBuilder! builder, System.Collections.Generic.IEnumerable! clientCredentials, Microsoft.Extensions.Logging.ILogger! logger, Microsoft.Identity.Abstractions.ICredentialsLoader! credentialsLoader, Microsoft.Identity.Abstractions.CredentialSourceLoaderParameters? credentialSourceLoaderParameters, bool isTokenBinding = false) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Shipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Shipped.txt
index 63e8bdb52..20ab61adf 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Shipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Shipped.txt
@@ -156,7 +156,6 @@ Microsoft.Identity.Web.TokenAcquisitionOptions.TokenAcquisitionOptions() -> void
static Microsoft.Identity.Web.ApplicationBuilderExtensions.UseTokenAcquirerFactory(this Microsoft.AspNetCore.Builder.IApplicationBuilder! applicationBuilder) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
static Microsoft.Identity.Web.Internal.WebApiBuilders.EnableTokenAcquisition(System.Action! configureConfidentialClientApplicationOptions, string! authenticationScheme, Microsoft.Extensions.DependencyInjection.IServiceCollection! services, Microsoft.Extensions.Configuration.IConfigurationSection? configuration) -> Microsoft.Identity.Web.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder!
static Microsoft.Identity.Web.PrincipalExtensionsForSecurityTokens.GetBootstrapToken(this System.Security.Principal.IPrincipal! claimsPrincipal) -> Microsoft.IdentityModel.Tokens.SecurityToken?
-static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
static Microsoft.Identity.Web.TestOnly.TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest() -> void
static Microsoft.Identity.Web.TokenAcquirerExtensions.GetFicTokenAsync(this Microsoft.Identity.Abstractions.ITokenAcquirer! tokenAcquirer, Microsoft.Identity.Abstractions.AcquireTokenOptions? options = null, string? clientAssertion = null, string! scope = "api://AzureAdTokenExchange/.default", System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
static Microsoft.Identity.Web.TokenAcquirerExtensions.WithClientAssertion(this Microsoft.Identity.Abstractions.AcquireTokenOptions! options, string! clientAssertion) -> Microsoft.Identity.Abstractions.AcquireTokenOptions!
@@ -165,8 +164,5 @@ static Microsoft.Identity.Web.TokenAcquirerFactory.GetDefaultInstance(string!
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForApp.Invoke(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUserAsync.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.DefineConfiguration(Microsoft.Extensions.Configuration.IConfigurationBuilder! builder) -> string!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.PreBuild() -> void
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt
index 7dc5c5811..5469ce14a 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net8.0/PublicAPI.Unshipped.txt
@@ -1 +1,9 @@
#nullable enable
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient() -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2! x509Certificate2) -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.MsalMtlsHttpClientFactory(System.Net.Http.IHttpClientFactory! httpClientFactory) -> void
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false, bool isTokenBinding = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt
index 7dc5c5811..f2fa32ead 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/InternalAPI.Unshipped.txt
@@ -1 +1,5 @@
#nullable enable
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ConfidentialClientApplicationBuilderExtension.WithClientCredentialsAsync(this Microsoft.Identity.Client.ConfidentialClientApplicationBuilder! builder, System.Collections.Generic.IEnumerable! clientCredentials, Microsoft.Extensions.Logging.ILogger! logger, Microsoft.Identity.Abstractions.ICredentialsLoader! credentialsLoader, Microsoft.Identity.Abstractions.CredentialSourceLoaderParameters? credentialSourceLoaderParameters, bool isTokenBinding = false) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Shipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Shipped.txt
index 63e8bdb52..20ab61adf 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Shipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Shipped.txt
@@ -156,7 +156,6 @@ Microsoft.Identity.Web.TokenAcquisitionOptions.TokenAcquisitionOptions() -> void
static Microsoft.Identity.Web.ApplicationBuilderExtensions.UseTokenAcquirerFactory(this Microsoft.AspNetCore.Builder.IApplicationBuilder! applicationBuilder) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
static Microsoft.Identity.Web.Internal.WebApiBuilders.EnableTokenAcquisition(System.Action! configureConfidentialClientApplicationOptions, string! authenticationScheme, Microsoft.Extensions.DependencyInjection.IServiceCollection! services, Microsoft.Extensions.Configuration.IConfigurationSection? configuration) -> Microsoft.Identity.Web.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder!
static Microsoft.Identity.Web.PrincipalExtensionsForSecurityTokens.GetBootstrapToken(this System.Security.Principal.IPrincipal! claimsPrincipal) -> Microsoft.IdentityModel.Tokens.SecurityToken?
-static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
static Microsoft.Identity.Web.TestOnly.TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest() -> void
static Microsoft.Identity.Web.TokenAcquirerExtensions.GetFicTokenAsync(this Microsoft.Identity.Abstractions.ITokenAcquirer! tokenAcquirer, Microsoft.Identity.Abstractions.AcquireTokenOptions? options = null, string? clientAssertion = null, string! scope = "api://AzureAdTokenExchange/.default", System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
static Microsoft.Identity.Web.TokenAcquirerExtensions.WithClientAssertion(this Microsoft.Identity.Abstractions.AcquireTokenOptions! options, string! clientAssertion) -> Microsoft.Identity.Abstractions.AcquireTokenOptions!
@@ -165,8 +164,5 @@ static Microsoft.Identity.Web.TokenAcquirerFactory.GetDefaultInstance(string!
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForApp.Invoke(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUserAsync.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.DefineConfiguration(Microsoft.Extensions.Configuration.IConfigurationBuilder! builder) -> string!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.PreBuild() -> void
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Unshipped.txt
index 7dc5c5811..5469ce14a 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net9.0/PublicAPI.Unshipped.txt
@@ -1 +1,9 @@
#nullable enable
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient() -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2! x509Certificate2) -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.MsalMtlsHttpClientFactory(System.Net.Http.IHttpClientFactory! httpClientFactory) -> void
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false, bool isTokenBinding = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt
index 7dc5c5811..f2fa32ead 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/InternalAPI.Unshipped.txt
@@ -1 +1,5 @@
#nullable enable
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ConfidentialClientApplicationBuilderExtension.WithClientCredentialsAsync(this Microsoft.Identity.Client.ConfidentialClientApplicationBuilder! builder, System.Collections.Generic.IEnumerable! clientCredentials, Microsoft.Extensions.Logging.ILogger! logger, Microsoft.Identity.Abstractions.ICredentialsLoader! credentialsLoader, Microsoft.Identity.Abstractions.CredentialSourceLoaderParameters? credentialSourceLoaderParameters, bool isTokenBinding = false) -> System.Threading.Tasks.Task!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt
index fbcd9c5aa..7ba4c692c 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt
@@ -155,7 +155,6 @@ Microsoft.Identity.Web.TokenAcquisitionOptions.PoPConfiguration.set -> void
Microsoft.Identity.Web.TokenAcquisitionOptions.TokenAcquisitionOptions() -> void
static Microsoft.Identity.Web.Internal.WebApiBuilders.EnableTokenAcquisition(System.Action! configureConfidentialClientApplicationOptions, string! authenticationScheme, Microsoft.Extensions.DependencyInjection.IServiceCollection! services, Microsoft.Extensions.Configuration.IConfigurationSection? configuration) -> Microsoft.Identity.Web.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder!
static Microsoft.Identity.Web.PrincipalExtensionsForSecurityTokens.GetBootstrapToken(this System.Security.Principal.IPrincipal! claimsPrincipal) -> Microsoft.IdentityModel.Tokens.SecurityToken?
-static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
static Microsoft.Identity.Web.TestOnly.TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest() -> void
static Microsoft.Identity.Web.TokenAcquirerExtensions.GetFicTokenAsync(this Microsoft.Identity.Abstractions.ITokenAcquirer! tokenAcquirer, Microsoft.Identity.Abstractions.AcquireTokenOptions? options = null, string? clientAssertion = null, string! scope = "api://AzureAdTokenExchange/.default", System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
static Microsoft.Identity.Web.TokenAcquirerExtensions.WithClientAssertion(this Microsoft.Identity.Abstractions.AcquireTokenOptions! options, string! clientAssertion) -> Microsoft.Identity.Abstractions.AcquireTokenOptions!
@@ -164,8 +163,5 @@ static Microsoft.Identity.Web.TokenAcquirerFactory.GetDefaultInstance(string!
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForApp.Invoke(Microsoft.Identity.Client.AcquireTokenForClientParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUser.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> void
virtual Microsoft.Identity.Web.BeforeTokenAcquisitionForTestUserAsync.Invoke(Microsoft.Identity.Client.AcquireTokenByUsernameAndPasswordConfidentialParameterBuilder! builder, Microsoft.Identity.Abstractions.AcquireTokenOptions? acquireTokenOptions, System.Security.Claims.ClaimsPrincipal! user) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
-virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.DefineConfiguration(Microsoft.Extensions.Configuration.IConfigurationBuilder! builder) -> string!
virtual Microsoft.Identity.Web.TokenAcquirerFactory.PreBuild() -> void
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
index 7dc5c5811..5469ce14a 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
@@ -1 +1,9 @@
#nullable enable
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient() -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2! x509Certificate2) -> System.Net.Http.HttpClient!
+Microsoft.Identity.Web.MsalMtlsHttpClientFactory.MsalMtlsHttpClientFactory(System.Net.Http.IHttpClientFactory! httpClientFactory) -> void
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForAppAsync(string! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? downstreamApiOptions = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+virtual Microsoft.Identity.Web.Extensibility.BaseAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(System.Collections.Generic.IEnumerable! scopes, Microsoft.Identity.Abstractions.AuthorizationHeaderProviderOptions? authorizationHeaderProviderOptions = null, System.Security.Claims.ClaimsPrincipal? claimsPrincipal = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!
+static Microsoft.Identity.Web.ServiceCollectionExtensions.AddTokenAcquisition(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, bool isTokenAcquisitionSingleton = false, bool isTokenBinding = false) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/ServiceCollectionExtensions.cs b/src/Microsoft.Identity.Web.TokenAcquisition/ServiceCollectionExtensions.cs
index 71368cc29..aa8e76d3b 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/ServiceCollectionExtensions.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/ServiceCollectionExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.Linq;
+using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
@@ -22,6 +23,7 @@ public static class ServiceCollectionExtensions
///
/// Service collection.
/// Specifies if an instance of should be a singleton.
+ /// Specifies if token binding support needs to be configured.
/// The service collection.
///
/// This method is typically called from the ConfigureServices(IServiceCollection services) in Startup.cs.
@@ -37,7 +39,8 @@ public static class ServiceCollectionExtensions
///
public static IServiceCollection AddTokenAcquisition(
this IServiceCollection services,
- bool isTokenAcquisitionSingleton = false)
+ bool isTokenAcquisitionSingleton = false,
+ bool isTokenBinding = false)
{
_ = Throws.IfNull(services);
@@ -63,14 +66,20 @@ public static IServiceCollection AddTokenAcquisition(
services.TryAddSingleton, ConfidentialClientApplicationOptionsMerger>();
}
- ServiceDescriptor? tokenAcquisitionService = services.FirstOrDefault(s => s.ServiceType == typeof(ITokenAcquisition));
+ if (isTokenBinding)
+ {
+ services.TryAddSingleton(s =>
+ new MsalMtlsHttpClientFactory(s.GetRequiredService()));
+ }
+
+ ServiceDescriptor? tokenAcquisitionService = services.FirstOrDefault(s => s.ServiceType == typeof(ITokenAcquisition));
ServiceDescriptor? tokenAcquisitionInternalService = services.FirstOrDefault(s => s.ServiceType == typeof(ITokenAcquisitionInternal));
ServiceDescriptor? tokenAcquisitionhost = services.FirstOrDefault(s => s.ServiceType == typeof(ITokenAcquisitionHost));
ServiceDescriptor? authenticationHeaderCreator = services.FirstOrDefault(s => s.ServiceType == typeof(IAuthorizationHeaderProvider));
ServiceDescriptor? tokenAcquirerFactory = services.FirstOrDefault(s => s.ServiceType == typeof(ITokenAcquirerFactory));
ServiceDescriptor? authSchemeInfoProvider = services.FirstOrDefault(s => s.ServiceType == typeof(Abstractions.IAuthenticationSchemeInformationProvider));
-
- if (tokenAcquisitionService != null && tokenAcquisitionInternalService != null &&
+
+ if (tokenAcquisitionService != null && tokenAcquisitionInternalService != null &&
tokenAcquisitionhost != null && authenticationHeaderCreator != null && authSchemeInfoProvider != null)
{
if (isTokenAcquisitionSingleton ^ (tokenAcquisitionService.Lifetime == ServiceLifetime.Singleton))
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquirer.cs b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquirer.cs
index 9d0d1ce1e..26676da84 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquirer.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquirer.cs
@@ -65,7 +65,10 @@ async Task ITokenAcquirer.GetTokenForAppAsync(string scope,
result.IdToken,
result.Scopes,
result.CorrelationId,
- result.TokenType);
+ result.TokenType)
+ {
+ BindingCertificate = result.BindingCertificate
+ };
}
private static TokenAcquisitionOptions? GetEffectiveTokenAcquisitionOptions(AcquireTokenOptions? tokenAcquisitionOptions, string? authenticationScheme, CancellationToken cancellationToken)
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
index 37f2a8e68..41733c92b 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
@@ -19,6 +19,7 @@
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.Extensibility;
+using Microsoft.Identity.Client.PlatformsCommon.Shared;
using Microsoft.Identity.Web.Experimental;
using Microsoft.Identity.Web.TestOnly;
using Microsoft.Identity.Web.TokenCacheProviders;
@@ -526,7 +527,7 @@ public async Task GetAuthenticationResultForAppAsync(
MergedOptions mergedOptions = GetMergedOptions(authenticationScheme, tokenAcquisitionOptions);
- // If using managed identity
+ // If using managed identity
if (tokenAcquisitionOptions != null && tokenAcquisitionOptions.ManagedIdentity != null)
{
try
@@ -570,6 +571,14 @@ public async Task GetAuthenticationResultForAppAsync(
.AcquireTokenForClient(new[] { scope }.Except(_scopesRequestedByMsal))
.WithSendX5C(mergedOptions.SendX5C);
+ // TODO: read this setting from `mergedOptions`
+ bool isTokenBinding = true;
+
+ if (isTokenBinding)
+ {
+ builder.WithMtlsProofOfPossession();
+ }
+
if (addInOptions != null)
{
addInOptions.InvokeOnBeforeTokenAcquisitionForApp(builder, tokenAcquisitionOptions);
@@ -966,11 +975,15 @@ private async Task BuildConfidentialClientApplic
try
{
+ // TODO: read this setting from `mergedOptions`
+ bool isTokenBinding = true;
+
await builder.WithClientCredentialsAsync(
mergedOptions.ClientCredentials!,
_logger,
_credentialsLoader,
- new CredentialSourceLoaderParameters(mergedOptions.ClientId!, authority));
+ new CredentialSourceLoaderParameters(mergedOptions.ClientId!, authority),
+ isTokenBinding);
}
catch (ArgumentException ex) when (ex.Message == IDWebErrorMessage.ClientCertificatesHaveExpiredOrCannotBeLoaded)
{
diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs
index faae19acf..d52029b08 100644
--- a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs
+++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/DownstreamWebApi.cs
@@ -99,9 +99,11 @@ public async Task CallWebApiForUserAsync(
httpRequestMessage.Content = content;
}
+ var authorizationHeaderInformation = authResult.CreateAuthorizationHeader();
+
httpRequestMessage.Headers.Add(
Constants.Authorization,
- authResult.CreateAuthorizationHeader());
+ authorizationHeaderInformation.AuthorizationHeaderValue);
effectiveOptions.CustomizeHttpRequestMessage?.Invoke(httpRequestMessage);
return await _httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
}
@@ -186,9 +188,11 @@ public async Task CallWebApiForAppAsync(
httpRequestMessage.Content = content;
}
+ var authorizationHeaderInformation = authResult.CreateAuthorizationHeader();
+
httpRequestMessage.Headers.Add(
Constants.Authorization,
- authResult.CreateAuthorizationHeader());
+ authorizationHeaderInformation.AuthorizationHeaderValue);
effectiveOptions.CustomizeHttpRequestMessage?.Invoke(httpRequestMessage);
response = await _httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
}
diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAppAuthenticationMessageHandler.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAppAuthenticationMessageHandler.cs
index e697da158..89355775d 100644
--- a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAppAuthenticationMessageHandler.cs
+++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityAppAuthenticationMessageHandler.cs
@@ -51,9 +51,11 @@ protected override async Task SendAsync(HttpRequestMessage
request.Headers.Remove(Constants.Authorization);
}
+ var authorizationHeaderInformation = authResult.CreateAuthorizationHeader();
+
request.Headers.Add(
Constants.Authorization,
- authResult.CreateAuthorizationHeader());
+ authorizationHeaderInformation.AuthorizationHeaderValue);
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
diff --git a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityUserAuthenticationMessageHandler.cs b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityUserAuthenticationMessageHandler.cs
index e5a37b61e..641d7dc96 100644
--- a/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityUserAuthenticationMessageHandler.cs
+++ b/src/Microsoft.Identity.Web/DownstreamWebApiSupport/MicrosoftIdentityUserAuthenticationMessageHandler.cs
@@ -63,9 +63,11 @@ protected override async Task SendAsync(HttpRequestMessage
request.Headers.Remove(Constants.Authorization);
}
+ var authorizationHeaderInformation = authResult.CreateAuthorizationHeader();
+
request.Headers.Add(
Constants.Authorization,
- authResult.CreateAuthorizationHeader());
+ authorizationHeaderInformation.AuthorizationHeaderValue);
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}