Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.415",
"version": "9.0.306",
"rollForward": "latestFeature"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
namespace Microsoft.Identity.Client
{
/// <summary>
/// Internal factory responsible for creating HttpClient instances configured for mutual TLS (MTLS).
/// This factory is specifically intended for use within the MSAL library for secure communication with Azure AD using MTLS.
/// A factory responsible for creating HttpClient instances configured for mutual TLS (MTLS).
/// This factory is intended for use to secure communication with Azure AD using MTLS.
/// For more details on HttpClient instancing, see https://learn.microsoft.com/dotnet/api/system.net.http.httpclient?view=net-7.0#instancing.
/// </summary>
/// <remarks>
/// Implementations of this interface must be thread-safe.
/// It is important to reuse HttpClient instances to avoid socket exhaustion.
/// Do not create a new HttpClient for each call to <see cref="GetHttpClient(X509Certificate2)"/>.
/// If your application requires Integrated Windows Authentication, set <see cref="HttpClientHandler.UseDefaultCredentials"/> to true.
/// This interface is intended for internal use by MSAL only and is designed to support MTLS scenarios.
/// This interface is designed to support MTLS scenarios.
/// </remarks>
internal interface IMsalMtlsHttpClientFactory : IMsalHttpClientFactory
public interface IMsalMtlsHttpClientFactory : IMsalHttpClientFactory
{
/// <summary>
/// Returns an HttpClient configured with a certificate for mutual TLS authentication.
Expand Down
58 changes: 53 additions & 5 deletions src/client/Microsoft.Identity.Client/AuthenticationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Client.AuthScheme;
using Microsoft.Identity.Client.Cache;
using Microsoft.Identity.Client.Cache.Items;
using Microsoft.Identity.Client.TelemetryCore.Internal.Events;
using Microsoft.Identity.Client.Utils;
using System.Security.Cryptography.X509Certificates;

namespace Microsoft.Identity.Client
{
Expand Down Expand Up @@ -123,7 +121,30 @@ public AuthenticationResult(
tokenType,
authenticationResultMetadata)
{
}

internal AuthenticationResult(
MsalAccessTokenCacheItem msalAccessTokenCacheItem,
MsalIdTokenCacheItem msalIdTokenCacheItem,
IAuthenticationOperation authenticationScheme,
Guid correlationID,
TokenSource tokenSource,
ApiEvent apiEvent,
Account account,
string spaAuthCode,
IReadOnlyDictionary<string, string> additionalResponseParameters) :
this(
msalAccessTokenCacheItem,
msalIdTokenCacheItem,
authenticationScheme,
correlationID,
tokenSource,
apiEvent,
account,
spaAuthCode,
additionalResponseParameters,
bindingCertificate: null)
{
}

internal AuthenticationResult(
Expand All @@ -135,7 +156,8 @@ internal AuthenticationResult(
ApiEvent apiEvent,
Account account,
string spaAuthCode,
IReadOnlyDictionary<string, string> additionalResponseParameters)
IReadOnlyDictionary<string, string> additionalResponseParameters,
X509Certificate2 bindingCertificate)
{
_authenticationScheme = authenticationScheme ?? throw new ArgumentNullException(nameof(authenticationScheme));

Expand Down Expand Up @@ -198,6 +220,7 @@ internal AuthenticationResult(

AuthenticationResultMetadata.DurationCreatingExtendedTokenInUs = measuredResultDuration.Microseconds;
AuthenticationResultMetadata.TelemetryTokenType = authenticationScheme.TelemetryTokenType;
BindingCertificate = bindingCertificate;
}

//Default constructor for testing
Expand Down Expand Up @@ -336,5 +359,30 @@ public string CreateAuthorizationHeader()
{
return $"{_authenticationScheme?.AuthorizationHeaderPrefix ?? TokenType} {AccessToken}";
}

/// <summary>
/// Creates the content for an HTTP authorization header from this authentication result, so
/// that you can call a protected API with using certificate binding (aka mTLS PoP).
/// </summary>
/// <returns>Created authorization header of the form "Bearer {AccessToken}" with bound certificate</returns>
/// <example>
/// Here is how you can call a protected API from this authentication result:
/// <code>
/// var authHeader = result.CreateAuthorizationHeaderBound();
/// HttpClientHandler handler = new();
/// handler.ClientCertificates.Add(authHeader.BindingCertificate);
/// HttpClient client = new HttpClient(handler);
/// client.DefaultRequestHeaders.Add("Authorization", authHeader.AuthorizationHeaderValue);
/// HttpResponseMessage r = await client.GetAsync(urlOfTheProtectedApi);
/// </code>
/// </example>
public AuthorizationHeaderInformation CreateAuthorizationHeaderBound()
{
return new AuthorizationHeaderInformation()
{
AuthorizationHeaderValue = CreateAuthorizationHeader(),
BindingCertificate = BindingCertificate
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
Expand All @@ -13,17 +11,12 @@
using Microsoft.Identity.Client.Cache;
using Microsoft.Identity.Client.Cache.Items;
using Microsoft.Identity.Client.Core;
using Microsoft.Identity.Client.Internal.Broker;
using Microsoft.Identity.Client.Instance.Discovery;
using Microsoft.Identity.Client.OAuth2;
using Microsoft.Identity.Client.TelemetryCore.Internal.Events;
using Microsoft.Identity.Client.Utils;
using Microsoft.Identity.Client.TelemetryCore;
using Microsoft.IdentityModel.Abstractions;
using Microsoft.Identity.Client.TelemetryCore.TelemetryClient;
using Microsoft.Identity.Client.TelemetryCore.OpenTelemetry;
using Microsoft.Identity.Client.Internal.Broker;
using System.Runtime.ConstrainedExecution;
using Microsoft.Identity.Client.AuthScheme;
using Microsoft.Identity.Client.Utils;

namespace Microsoft.Identity.Client.Internal.Requests
{
Expand Down Expand Up @@ -348,7 +341,8 @@ protected async Task<AuthenticationResult> CacheTokenResponseAndCreateAuthentica
AuthenticationRequestParameters.RequestContext.ApiEvent,
account,
msalTokenResponse.SpaAuthCode,
msalTokenResponse.CreateExtensionDataStringMap());
msalTokenResponse.CreateExtensionDataStringMap(),
AuthenticationRequestParameters.AppConfig.ClientCredentialCertificate);
}

protected virtual void ValidateAccountIdentifiers(ClientInfo fromServer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
</ItemGroup>

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Microsoft.Identity.Client.AuthenticationResult.CreateAuthorizationHeaderBound() -> Microsoft.Identity.Client.AuthorizationHeaderInformation
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2 x509Certificate2) -> System.Net.Http.HttpClient
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Microsoft.Identity.Client.AuthenticationResult.CreateAuthorizationHeaderBound() -> Microsoft.Identity.Client.AuthorizationHeaderInformation
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2 x509Certificate2) -> System.Net.Http.HttpClient
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Microsoft.Identity.Client.AuthenticationResult.CreateAuthorizationHeaderBound() -> Microsoft.Identity.Client.AuthorizationHeaderInformation
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Microsoft.Identity.Client.AuthenticationResult.CreateAuthorizationHeaderBound() -> Microsoft.Identity.Client.AuthorizationHeaderInformation
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Microsoft.Identity.Client.AuthenticationResult.CreateAuthorizationHeaderBound() -> Microsoft.Identity.Client.AuthorizationHeaderInformation
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2 x509Certificate2) -> System.Net.Http.HttpClient
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Microsoft.Identity.Client.AuthenticationResult.CreateAuthorizationHeaderBound() -> Microsoft.Identity.Client.AuthorizationHeaderInformation
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory
Microsoft.Identity.Client.AppConfig.IMsalMtlsHttpClientFactory.GetHttpClient(System.Security.Cryptography.X509Certificates.X509Certificate2 x509Certificate2) -> System.Net.Http.HttpClient
Loading
Loading