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
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public IReadOnlyDictionary<string, string> GetTokenRequestParams()

public void FormatResult(AuthenticationResult authenticationResult)
{
//no-op
authenticationResult.BindingCertificate = _mtlsCert;
}

private static string ComputeX5tS256KeyId(X509Certificate2 certificate)
Expand Down
35 changes: 22 additions & 13 deletions src/client/Microsoft.Identity.Client/AuthenticationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
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 @@ -42,6 +43,8 @@ public partial class AuthenticationResult
/// <param name="claimsPrincipal">Claims from the ID token</param>
/// <param name="spaAuthCode">Auth Code returned by the Microsoft identity platform when you use AcquireTokenByAuthorizationCode.WithSpaAuthorizationCode(). This auth code is meant to be redeemed by the frontend code. See https://aka.ms/msal-net/spa-auth-code</param>
/// <param name="additionalResponseParameters">Other properties from the token response.</param>
[Obsolete("Direct constructor use is deprecated.", error: false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public AuthenticationResult( // for backwards compat with 4.16-
string accessToken,
bool isExtendedLifeTimeToken,
Expand Down Expand Up @@ -95,6 +98,7 @@ public partial class AuthenticationResult
/// <param name="authenticationResultMetadata">Contains metadata related to the Authentication Result.</param>
/// <param name="tokenType">The token type, defaults to Bearer. Note: this property is experimental and may change in future versions of the library.</param>
/// <remarks>For backwards compatibility with MSAL 4.17-4.20 </remarks>
[Obsolete("Direct constructor use is deprecated.", error: false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public AuthenticationResult(
string accessToken,
Expand Down Expand Up @@ -234,14 +238,14 @@ internal AuthenticationResult() { }
/// Guest AAD accounts have different oid claim values in each tenant. Use <see cref="Account.HomeAccountId"/> to uniquely identify users across tenants.
/// See https://docs.microsoft.com/azure/active-directory/develop/id-tokens#payload-claims
/// </remarks>
public string UniqueId { get; }
public string UniqueId { get; set; }

/// <summary>
/// Gets the point in time in which the Access Token returned in the <see cref="AccessToken"/> property ceases to be valid.
/// This value is calculated based on current UTC time measured locally and the value expiresIn received from the
/// service.
/// </summary>
public DateTimeOffset ExpiresOn { get; }
public DateTimeOffset ExpiresOn { get; set; }

/// <summary>
/// Gets the point in time in which the Access Token returned in the AccessToken property ceases to be valid in MSAL's extended LifeTime.
Expand All @@ -255,42 +259,47 @@ internal AuthenticationResult() { }
/// Gets an identifier for the Azure AD tenant from which the token was acquired. This property will be null if tenant information is
/// not returned by the service.
/// </summary>
public string TenantId { get; }
public string TenantId { get; set; }

/// <summary>
/// Gets the account information. Some elements in <see cref="IAccount"/> might be null if not returned by the
/// service. The account can be passed back in some API overloads to identify which account should be used such
/// as <see cref="IClientApplicationBase.AcquireTokenSilent(IEnumerable{string}, IAccount)"/> or
/// <see cref="IClientApplicationBase.RemoveAsync(IAccount)"/> for instance
/// </summary>
public IAccount Account { get; }
public IAccount Account { get; set; }

/// <summary>
/// Gets the Id Token if returned by the service or null if no Id Token is returned.
/// </summary>
public string IdToken { get; }
public string IdToken { get; set; }

/// <summary>
/// Gets the granted scope values returned by the service.
/// </summary>
public IEnumerable<string> Scopes { get; }
public IEnumerable<string> Scopes { get; set; }

/// <summary>
/// Gets the correlation id used for the request.
/// </summary>
public Guid CorrelationId { get; }
public Guid CorrelationId { get; set; }

/// <summary>
/// Identifies the type of access token. By default tokens returned by Azure Active Directory are Bearer tokens.
/// <seealso cref="CreateAuthorizationHeader"/> for getting an HTTP authorization header from an AuthenticationResult.
/// </summary>
public string TokenType { get; }
public string TokenType { get; set; }

/// <summary>
/// Gets the SPA Authorization Code, if it was requested using WithSpaAuthorizationCode method on the
/// AcquireTokenByAuthorizationCode builder. See https://aka.ms/msal-net/spa-auth-code for details.
/// </summary>
public string SpaAuthCode { get; }
public string SpaAuthCode { get; set; }

/// <summary>
/// The X509 certificate bound to the access-token when mTLS-PoP was used.
/// </summary>
public X509Certificate2 BindingCertificate { get; set; }

/// <summary>
/// Exposes additional response parameters returned by the token issuer (AAD).
Expand All @@ -299,19 +308,19 @@ internal AuthenticationResult() { }
/// Not all parameters are added here, only the ones that MSAL doesn't interpret itself and only scalars.
/// Not supported on mobile frameworks (e.g. net8-android or net8-ios)
/// </remarks>
public IReadOnlyDictionary<string, string> AdditionalResponseParameters { get; }
public IReadOnlyDictionary<string, string> AdditionalResponseParameters { get; set; }

/// <summary>
/// All the claims present in the ID token.
/// </summary>
public ClaimsPrincipal ClaimsPrincipal { get; }
public ClaimsPrincipal ClaimsPrincipal { get; set; }

internal ApiEvent ApiEvent { get; }
internal ApiEvent ApiEvent { get; set; }

/// <summary>
/// Contains metadata for the Authentication result.
/// </summary>
public AuthenticationResultMetadata AuthenticationResultMetadata { get; }
public AuthenticationResultMetadata AuthenticationResultMetadata { get; set; }

/// <summary>
/// Creates the content for an HTTP authorization header from this authentication result, so
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string
const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string
Microsoft.Identity.Client.AuthenticationResult.Account.set -> void
Microsoft.Identity.Client.AuthenticationResult.AdditionalResponseParameters.set -> void
Microsoft.Identity.Client.AuthenticationResult.AuthenticationResultMetadata.set -> void
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.set -> void
Microsoft.Identity.Client.AuthenticationResult.ClaimsPrincipal.set -> void
Microsoft.Identity.Client.AuthenticationResult.CorrelationId.set -> void
Microsoft.Identity.Client.AuthenticationResult.ExpiresOn.set -> void
Microsoft.Identity.Client.AuthenticationResult.IdToken.set -> void
Microsoft.Identity.Client.AuthenticationResult.Scopes.set -> void
Microsoft.Identity.Client.AuthenticationResult.SpaAuthCode.set -> void
Microsoft.Identity.Client.AuthenticationResult.TenantId.set -> void
Microsoft.Identity.Client.AuthenticationResult.TokenType.set -> void
Microsoft.Identity.Client.AuthenticationResult.UniqueId.set -> void
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string
const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string
Microsoft.Identity.Client.AuthenticationResult.Account.set -> void
Microsoft.Identity.Client.AuthenticationResult.AdditionalResponseParameters.set -> void
Microsoft.Identity.Client.AuthenticationResult.AuthenticationResultMetadata.set -> void
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.set -> void
Microsoft.Identity.Client.AuthenticationResult.ClaimsPrincipal.set -> void
Microsoft.Identity.Client.AuthenticationResult.CorrelationId.set -> void
Microsoft.Identity.Client.AuthenticationResult.ExpiresOn.set -> void
Microsoft.Identity.Client.AuthenticationResult.IdToken.set -> void
Microsoft.Identity.Client.AuthenticationResult.Scopes.set -> void
Microsoft.Identity.Client.AuthenticationResult.SpaAuthCode.set -> void
Microsoft.Identity.Client.AuthenticationResult.TenantId.set -> void
Microsoft.Identity.Client.AuthenticationResult.TokenType.set -> void
Microsoft.Identity.Client.AuthenticationResult.UniqueId.set -> void
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string
const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string
Microsoft.Identity.Client.AuthenticationResult.Account.set -> void
Microsoft.Identity.Client.AuthenticationResult.AdditionalResponseParameters.set -> void
Microsoft.Identity.Client.AuthenticationResult.AuthenticationResultMetadata.set -> void
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.set -> void
Microsoft.Identity.Client.AuthenticationResult.ClaimsPrincipal.set -> void
Microsoft.Identity.Client.AuthenticationResult.CorrelationId.set -> void
Microsoft.Identity.Client.AuthenticationResult.ExpiresOn.set -> void
Microsoft.Identity.Client.AuthenticationResult.IdToken.set -> void
Microsoft.Identity.Client.AuthenticationResult.Scopes.set -> void
Microsoft.Identity.Client.AuthenticationResult.SpaAuthCode.set -> void
Microsoft.Identity.Client.AuthenticationResult.TenantId.set -> void
Microsoft.Identity.Client.AuthenticationResult.TokenType.set -> void
Microsoft.Identity.Client.AuthenticationResult.UniqueId.set -> void
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string
const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string
Microsoft.Identity.Client.AuthenticationResult.Account.set -> void
Microsoft.Identity.Client.AuthenticationResult.AdditionalResponseParameters.set -> void
Microsoft.Identity.Client.AuthenticationResult.AuthenticationResultMetadata.set -> void
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.set -> void
Microsoft.Identity.Client.AuthenticationResult.ClaimsPrincipal.set -> void
Microsoft.Identity.Client.AuthenticationResult.CorrelationId.set -> void
Microsoft.Identity.Client.AuthenticationResult.ExpiresOn.set -> void
Microsoft.Identity.Client.AuthenticationResult.IdToken.set -> void
Microsoft.Identity.Client.AuthenticationResult.Scopes.set -> void
Microsoft.Identity.Client.AuthenticationResult.SpaAuthCode.set -> void
Microsoft.Identity.Client.AuthenticationResult.TenantId.set -> void
Microsoft.Identity.Client.AuthenticationResult.TokenType.set -> void
Microsoft.Identity.Client.AuthenticationResult.UniqueId.set -> void
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string
const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string
Microsoft.Identity.Client.AuthenticationResult.Account.set -> void
Microsoft.Identity.Client.AuthenticationResult.AdditionalResponseParameters.set -> void
Microsoft.Identity.Client.AuthenticationResult.AuthenticationResultMetadata.set -> void
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.set -> void
Microsoft.Identity.Client.AuthenticationResult.ClaimsPrincipal.set -> void
Microsoft.Identity.Client.AuthenticationResult.CorrelationId.set -> void
Microsoft.Identity.Client.AuthenticationResult.ExpiresOn.set -> void
Microsoft.Identity.Client.AuthenticationResult.IdToken.set -> void
Microsoft.Identity.Client.AuthenticationResult.Scopes.set -> void
Microsoft.Identity.Client.AuthenticationResult.SpaAuthCode.set -> void
Microsoft.Identity.Client.AuthenticationResult.TenantId.set -> void
Microsoft.Identity.Client.AuthenticationResult.TokenType.set -> void
Microsoft.Identity.Client.AuthenticationResult.UniqueId.set -> void
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
const Microsoft.Identity.Client.MsalError.InvalidManagedIdentityIdType = "invalid_managed_identity_id_type" -> string
const Microsoft.Identity.Client.MsalError.MissingManagedIdentityEnvVar = "missing_managed_identity_env_var" -> string
Microsoft.Identity.Client.AuthenticationResult.Account.set -> void
Microsoft.Identity.Client.AuthenticationResult.AdditionalResponseParameters.set -> void
Microsoft.Identity.Client.AuthenticationResult.AuthenticationResultMetadata.set -> void
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.get -> System.Security.Cryptography.X509Certificates.X509Certificate2
Microsoft.Identity.Client.AuthenticationResult.BindingCertificate.set -> void
Microsoft.Identity.Client.AuthenticationResult.ClaimsPrincipal.set -> void
Microsoft.Identity.Client.AuthenticationResult.CorrelationId.set -> void
Microsoft.Identity.Client.AuthenticationResult.ExpiresOn.set -> void
Microsoft.Identity.Client.AuthenticationResult.IdToken.set -> void
Microsoft.Identity.Client.AuthenticationResult.Scopes.set -> void
Microsoft.Identity.Client.AuthenticationResult.SpaAuthCode.set -> void
Microsoft.Identity.Client.AuthenticationResult.TenantId.set -> void
Microsoft.Identity.Client.AuthenticationResult.TokenType.set -> void
Microsoft.Identity.Client.AuthenticationResult.UniqueId.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public async Task Sni_Gets_Pop_Token_Successfully_TestAsync()
Assert.AreEqual(Constants.MtlsPoPTokenType, authResult.TokenType, "Token type should be MTLS PoP");
Assert.IsNotNull(authResult.AccessToken, "Access token should not be null");

Assert.IsNotNull(authResult.BindingCertificate, "BindingCertificate should be set in SNI flow.");
Assert.AreEqual(cert.Thumbprint,
authResult.BindingCertificate.Thumbprint,
"BindingCertificate must match the certificate supplied via WithCertificate().");

// Simulate cache retrieval to verify MTLS configuration is cached properly
authResult = await confidentialApp
.AcquireTokenForClient(settings.AppScopes)
Expand All @@ -66,6 +71,11 @@ public async Task Sni_Gets_Pop_Token_Successfully_TestAsync()

// Assert: Verify that the token was fetched from cache on the second request
Assert.AreEqual(TokenSource.Cache, authResult.AuthenticationResultMetadata.TokenSource, "Token should be retrieved from cache");

Assert.IsNotNull(authResult.BindingCertificate, "BindingCertificate should be set in SNI flow.");
Assert.AreEqual(cert.Thumbprint,
authResult.BindingCertificate.Thumbprint,
"BindingCertificate must match the certificate supplied via WithCertificate().");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ private async Task RunClientCredsAsync(Cloud cloud, CredentialType credentialTyp
GetExpectedCacheKey(settings.ClientId, settings.TenantId),
appCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey);

Assert.IsNull(authResult.BindingCertificate,
"BindingCertificate should be null for bearer tokens.");

// Call again to ensure token cache is hit
authResult = await confidentialApp
.AcquireTokenForClient(settings.AppScopes)
Expand All @@ -330,6 +333,9 @@ private async Task RunClientCredsAsync(Cloud cloud, CredentialType credentialTyp
Assert.AreEqual(
GetExpectedCacheKey(settings.ClientId, settings.TenantId),
appCacheRecorder.LastAfterAccessNotificationArgs.SuggestedCacheKey);

Assert.IsNull(authResult.BindingCertificate,
"BindingCertificate should be null for bearer tokens.");
}

private static IConfidentialClientApplication CreateApp(
Expand Down
Loading
Loading