-
Notifications
You must be signed in to change notification settings - Fork 379
Add extensibility APIs #5573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add extensibility APIs #5573
Conversation
src/client/Microsoft.Identity.Client/AppConfig/ApplicationConfiguration.cs
Outdated
Show resolved
Hide resolved
src/client/Microsoft.Identity.Client/AppConfig/ApplicationConfiguration.cs
Outdated
Show resolved
Hide resolved
...nt/Microsoft.Identity.Client/Extensibility/ConfidentialClientApplicationBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
...nt/Microsoft.Identity.Client/Extensibility/ConfidentialClientApplicationBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
...nt/Microsoft.Identity.Client/Extensibility/ConfidentialClientApplicationBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces extensibility APIs for client credential flows, enabling dynamic certificate provisioning, custom retry logic for service failures, and execution observation. The changes support scenarios like certificate rotation from Azure Key Vault and custom telemetry collection.
- Dynamic certificate provider callback that's invoked before each token request
- Retry callback for handling service failures with custom logic
- Execution observer for tracking token acquisition results (success or failure)
Reviewed Changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
src/client/Microsoft.Identity.Client/Extensibility/ClientCredentialExtensionParameters.cs |
New parameter class providing application context to extensibility callbacks |
src/client/Microsoft.Identity.Client/Extensibility/ExecutionResult.cs |
New result class containing either successful AuthenticationResult or exception |
src/client/Microsoft.Identity.Client/Extensibility/ConfidentialClientApplicationBuilderExtensions.cs |
Extension methods for WithCertificate, OnMsalServiceFailure, and OnSuccess |
src/client/Microsoft.Identity.Client/AppConfig/ApplicationConfiguration.cs |
Adds storage for three new extensibility callback properties |
src/client/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs |
Implements retry loop and callback invocation logic for token acquisition |
src/client/Microsoft.Identity.Client/Internal/ClientCredential/CertificateAndClaimsClientCredential.cs |
Adds dynamic certificate resolution via provider callback |
src/client/Microsoft.Identity.Client/ApiConfig/AbstractConfidentialClientAcquireTokenParameterBuilder.cs |
Updates validation to allow dynamic certificate provider |
src/client/Microsoft.Identity.Client/MsalError.cs |
Adds error constant for invalid client credential configuration |
tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationExtensibilityTests.cs |
Comprehensive integration tests for all three extensibility points |
tests/Microsoft.Identity.Test.Unit/AppConfigTests/ConfidentialClientApplicationExtensibilityApiTests.cs |
Unit tests for builder API and configuration storage |
src/client/Microsoft.Identity.Client/PublicApi/*/PublicAPI.Unshipped.txt |
Documents new public API surface for all target frameworks |
src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj |
Adds new extensibility files to project |
src/client/Microsoft.Identity.Client/ManagedIdentity/AbstractManagedIdentity.cs |
Modifies exception handling pattern (appears unrelated to extensibility) |
...nt/Microsoft.Identity.Client/Extensibility/ConfidentialClientApplicationBuilderExtensions.cs
Show resolved
Hide resolved
src/client/Microsoft.Identity.Client/ManagedIdentity/AbstractManagedIdentity.cs
Show resolved
Hide resolved
.../Microsoft.Identity.Client/Internal/ClientCredential/CertificateAndClaimsClientCredential.cs
Show resolved
Hide resolved
...nt/Microsoft.Identity.Client/Extensibility/ConfidentialClientApplicationBuilderExtensions.cs
Show resolved
Hide resolved
...soft.Identity.Test.Unit/AppConfigTests/ConfidentialClientApplicationExtensibilityApiTests.cs
Show resolved
Hide resolved
...soft.Identity.Test.Unit/AppConfigTests/ConfidentialClientApplicationExtensibilityApiTests.cs
Show resolved
Hide resolved
...soft.Identity.Test.Unit/AppConfigTests/ConfidentialClientApplicationExtensibilityApiTests.cs
Show resolved
Hide resolved
...crosoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationExtensibilityTests.cs
Outdated
Show resolved
Hide resolved
src/client/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs
Show resolved
Hide resolved
src/client/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs
Show resolved
Hide resolved
Co-authored-by: Copilot <[email protected]>
| /// Represents the result of a token acquisition attempt. | ||
| /// Used by the execution observer configured via <see cref="ConfidentialClientApplicationBuilderExtensions.OnSuccess"/>. | ||
| /// </summary> | ||
| public class ExecutionResult |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this include the credential used (primarily care about the exact certificate used). If that information is in AuthenticationResult then that is fine.
| } | ||
|
|
||
| // Invoke OnSuccess callback with failure result | ||
| await InvokeOnSuccessCallbackAsync(authResult: null, exception: serviceEx, logger).ConfigureAwait(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems OnSuccess is a misnomer if it is called both for failures and success; perhaps it should be renamed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I feel this can be renamed to OnCompletion. Since OnServiceFailure only handles certain service exceptions this can be triggered when either the request succeeds or if there are any other failures that are not being used to retry. @bgavrilMS thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, or use OnSuccess since failure is alreay covered via OnMsalServiceException
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only the service exceptions that are handled in the callback will be handled there. Rest can still throw exception back. Will rename it to OnCompletion for clarity.
| } | ||
|
|
||
| [TestMethod] | ||
| public void WithCertificate_AllowsMultipleCallbackRegistrations_LastOneWins() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this how the rest of the APIs currently work? If you call WithCertificate multiple times, it just overwrites?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now that is how it is. The test case was generated by copilot. I am going to propose another PR that will validate and throw if the cert is being set twice. Or if the dynamic cert is used then avoid static cert.
src/client/Microsoft.Identity.Client/Extensibility/ClientCredentialExtensionParameters.cs
Outdated
Show resolved
Hide resolved
…D/microsoft-authentication-library-for-dotnet into nebharg/certExtensibility
src/client/Microsoft.Identity.Client/Internal/Requests/ClientCredentialRequest.cs
Show resolved
Hide resolved
...icrosoft.Identity.Client/ApiConfig/AbstractConfidentialClientAcquireTokenParameterBuilder.cs
Show resolved
Hide resolved
src/client/Microsoft.Identity.Client/AppConfig/AssertionRequestOptions.cs
Show resolved
Hide resolved
| /// MSAL service failure callback that determines whether to retry after a token acquisition failure from the identity provider. | ||
| /// Only invoked for MsalServiceException (errors from the Security Token Service). | ||
| /// </summary> | ||
| public Func<AssertionRequestOptions, MsalException, Task<bool>> OnMsalServiceFailureCallback { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming: I believe the convention for these callbacks is to not use the "callback" suffix. So maybe "OnBeforeMsalServiceException"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or OnMsalServiceExceptionProvider?
| /// <summary> | ||
| /// Success callback that receives the result of token acquisition attempts (typically successful, but can include failures after retries are exhausted). | ||
| /// </summary> | ||
| public Func<AssertionRequestOptions, ExecutionResult, Task> OnSuccessCallback { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this ExecutionResult object? It seems to me that OnMsalServiceFailure takes care of the error sceanrio. And so this can be Func<AssertionRequestOptions, AuthenticationResult> OnTokenAcquisitionSuccess
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the OnMsalServiceFailure wll only handle the exceptions defined in the callback. There can be other exceptions as well that can be thrown.
.../Microsoft.Identity.Client/Internal/ClientCredential/CertificateAndClaimsClientCredential.cs
Show resolved
Hide resolved
| // Log the incoming request parameters for diagnostic purposes | ||
| requestParameters.RequestContext.Logger.Verbose(() => $"Building assertion from certificate with clientId: {clientId} at endpoint: {tokenEndpoint}"); | ||
|
|
||
| if (requestParameters.MtlsCertificate == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for Bearer tokens, but it is going to require a bit of work for mTLS POP tokens, which is an important scenario.
In case of MTLS POP tokens, the certificate is used to talk to Entra via mTLS.
I recommend you use a follow-up PR to address this sceanrio. There are integration tests for mtls POP.
bgavrilMS
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TenantId is probably not correctly set, as it can be overridden
Fixes #5568
Changes proposed in this request
Testing
Performance impact
Documentation