diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/ICertificatesObserver.cs b/src/Microsoft.Identity.Web.TokenAcquisition/ICertificatesObserver.cs
index ccd4ed88e..bedf48e89 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/ICertificatesObserver.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/ICertificatesObserver.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
+using System;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Identity.Abstractions;
@@ -46,6 +47,11 @@ public class CertificateChangeEventArg
/// Credential description
///
public CredentialDescription? CredentialDescription { get; set; }
+
+ ///
+ /// Gets the exception thrown during the certificate selection or deselection.
+ ///
+ public Exception? ThrownException { get; set; }
}
///
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 19618d88c..5a19c7818 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net462/PublicAPI.Unshipped.txt
@@ -1,3 +1,5 @@
#nullable enable
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider.GetEffectiveAuthenticationScheme(string? authenticationScheme) -> string!
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.get -> System.Exception?
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.set -> void
\ No newline at end of file
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 19618d88c..5a19c7818 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net472/PublicAPI.Unshipped.txt
@@ -1,3 +1,5 @@
#nullable enable
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider.GetEffectiveAuthenticationScheme(string? authenticationScheme) -> string!
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.get -> System.Exception?
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.set -> void
\ No newline at end of file
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt
index 19618d88c..5a19c7818 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net6.0/PublicAPI.Unshipped.txt
@@ -1,3 +1,5 @@
#nullable enable
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider.GetEffectiveAuthenticationScheme(string? authenticationScheme) -> string!
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.get -> System.Exception?
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.set -> void
\ No newline at end of file
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt
index 19618d88c..5a19c7818 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/net7.0/PublicAPI.Unshipped.txt
@@ -1,3 +1,5 @@
#nullable enable
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider.GetEffectiveAuthenticationScheme(string? authenticationScheme) -> string!
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.get -> System.Exception?
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.set -> void
\ No newline at end of file
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 19618d88c..5a19c7818 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,3 +1,5 @@
#nullable enable
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider.GetEffectiveAuthenticationScheme(string? authenticationScheme) -> string!
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.get -> System.Exception?
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.set -> void
\ No newline at end of file
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 19618d88c..5a19c7818 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,3 +1,5 @@
#nullable enable
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider.GetEffectiveAuthenticationScheme(string? authenticationScheme) -> string!
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.get -> System.Exception?
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.set -> void
\ No newline at end of file
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 19618d88c..5a19c7818 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,3 +1,5 @@
#nullable enable
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider
Microsoft.Identity.Web.IAuthenticationSchemeInformationProvider.GetEffectiveAuthenticationScheme(string? authenticationScheme) -> string!
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.get -> System.Exception?
+Microsoft.Identity.Web.Experimental.CertificateChangeEventArg.ThrownException.set -> void
\ No newline at end of file
diff --git a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
index ad40ec13e..1fb5d41b0 100644
--- a/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
+++ b/src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs
@@ -183,7 +183,7 @@ public async Task AddAccountToCacheFromAuthorizationCodeAsyn
}
catch (MsalServiceException exMsal) when (IsInvalidClientCertificateOrSignedAssertionError(exMsal))
{
- NotifyCertificateSelection(mergedOptions, application!, CerticateObserverAction.Deselected);
+ NotifyCertificateSelection(mergedOptions, application!, CerticateObserverAction.Deselected, exMsal);
DefaultCertificateLoader.ResetCertificates(mergedOptions.ClientCredentials);
_applicationsByAuthorityClientId[GetApplicationKey(mergedOptions)] = null;
@@ -302,7 +302,7 @@ public async Task GetAuthenticationResultForUserAsync(
}
catch (MsalServiceException exMsal) when (IsInvalidClientCertificateOrSignedAssertionError(exMsal))
{
- NotifyCertificateSelection(mergedOptions, application, CerticateObserverAction.Deselected);
+ NotifyCertificateSelection(mergedOptions, application, CerticateObserverAction.Deselected, exMsal);
DefaultCertificateLoader.ResetCertificates(mergedOptions.ClientCredentials);
_applicationsByAuthorityClientId[GetApplicationKey(mergedOptions)] = null;
@@ -620,7 +620,7 @@ public async Task GetAuthenticationResultForAppAsync(
}
catch (MsalServiceException exMsal) when (IsInvalidClientCertificateOrSignedAssertionError(exMsal))
{
- NotifyCertificateSelection(mergedOptions, application, CerticateObserverAction.Deselected);
+ NotifyCertificateSelection(mergedOptions, application, CerticateObserverAction.Deselected, exMsal);
DefaultCertificateLoader.ResetCertificates(mergedOptions.ClientCredentials);
_applicationsByAuthorityClientId[GetApplicationKey(mergedOptions)] = null;
@@ -935,7 +935,7 @@ await builder.WithClientCredentialsAsync(
// If the client application has set certificate observer,
// fire the event to notify the client app that a certificate was selected.
- NotifyCertificateSelection(mergedOptions, app, CerticateObserverAction.Selected);
+ NotifyCertificateSelection(mergedOptions, app, CerticateObserverAction.Selected, null);
// Initialize token cache providers
if (!(_tokenCacheProvider is MsalMemoryTokenCacheProvider))
@@ -962,7 +962,12 @@ await builder.WithClientCredentialsAsync(
///
///
///
- private void NotifyCertificateSelection(MergedOptions mergedOptions, IConfidentialClientApplication app, CerticateObserverAction action)
+ /// The thrown exception, if any.
+ private void NotifyCertificateSelection(
+ MergedOptions mergedOptions,
+ IConfidentialClientApplication app,
+ CerticateObserverAction action,
+ Exception? exception)
{
X509Certificate2 selectedCertificate = app.AppConfig.ClientCredentialCertificate;
if (_certificatesObserver != null
@@ -973,7 +978,8 @@ private void NotifyCertificateSelection(MergedOptions mergedOptions, IConfidenti
{
Action = action,
Certificate = app.AppConfig.ClientCredentialCertificate,
- CredentialDescription = mergedOptions.ClientCredentials?.FirstOrDefault(c => c.Certificate == selectedCertificate)
+ CredentialDescription = mergedOptions.ClientCredentials?.FirstOrDefault(c => c.Certificate == selectedCertificate),
+ ThrownException = exception,
});
}
}