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, }); } }