MTLS Without Tokens Support - MicrosoftIdentityMessageHandler Support#3815
Merged
Conversation
neha-bhargava
left a comment
Contributor
There was a problem hiding this comment.
Left some comments
Co-authored-by: Neha Bhargava <61847233+neha-bhargava@users.noreply.github.com>
…essageHandler.cs Co-authored-by: Neha Bhargava <61847233+neha-bhargava@users.noreply.github.com>
Co-authored-by: Neha Bhargava <61847233+neha-bhargava@users.noreply.github.com>
…com/AzureAD/microsoft-identity-web into MicrosoftIdentityMessageHandlerMtls
bgavrilMS
reviewed
May 19, 2026
bgavrilMS
reviewed
May 19, 2026
bgavrilMS
reviewed
May 19, 2026
bgavrilMS
reviewed
May 19, 2026
bgavrilMS
approved these changes
May 19, 2026
… dispatch - Add missing 'using Microsoft.Identity.Web.Diagnostics' to DownstreamApi.cs so UnauthorizedHttpRequestException resolves. - Fix Invoke()/invoke() casing in CertificatesObserverTests (3 sites). - Rename SendAsync_WithMtlsPop_NullMtlsFactory_UsesBaseSendAsync to *_Throws and assert InvalidOperationException, matching the deliberate behavior change introduced when the mTLS dispatch was tightened to require an IMsalMtlsHttpClientFactory whenever a binding certificate is present. - Wire SendAsync_CertificateFailureRetry_ClonesRequest through a real mTLS factory so the retry-clone path it covers is reachable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…g with internal cert-failure retry For ProtocolScheme=MTLS there is no token to refresh with WWW-Authenticate claims, and SendWithCertRetryAsync already retried credential acquisition on the initial 401. Allowing the outer claims-challenge retry to also fire would issue a redundant third send and another GetCredentialAsync call, which may hit disk or Key Vault, for no semantic benefit. Add SendAsync_MtlsOnly_PersistentUnauthorizedWithClaims_DoesNotComposeRetries to pin the gating: exactly two sends and two GetCredentialAsync calls when the server keeps returning 401 + claims challenge in pure-mTLS mode. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Extends the existing mTLS “without tokens” work (previously added for DownstreamApi) to MicrosoftIdentityMessageHandler, including DI wiring and shared-constant refactoring into Microsoft.Identity.Web.TokenAcquisition.
Changes:
- Adds mTLS-only dispatch + bounded cert-failure retry behavior to
MicrosoftIdentityMessageHandler, and updates tests accordingly. - Refactors shared protocol/status-code constants into
Microsoft.Identity.Web.TokenAcquisition/Constants.csand updates DownstreamApi/TokenAcquisition to consume them. - Updates HttpClient builder extensions to resolve configured
IMsalMtlsHttpClientFactory, pass a logger, and optionally construct/use anICredentialsProvider.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Microsoft.Identity.Web.Test/MicrosoftIdentityMessageHandlerTokenBindingTests.cs | Updates/extends handler tests for mTLS-only retry and cloning behavior. |
| tests/Microsoft.Identity.Web.Test/MicrosoftIdentityHttpClientBuilderExtensionsTests.cs | Minor formatting change in tests. |
| tests/Microsoft.Identity.Web.Test/CertificatesObserverTests.cs | Expands observer test coverage to include handler-based mTLS path. |
| src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs | Updates reference to renamed certificate-related STS error-code constant. |
| src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/NetFramework/PublicAPI.Unshipped.txt | Records new public handler constructor overload for .NET Framework targets. |
| src/Microsoft.Identity.Web.TokenAcquisition/PublicAPI/NetCore/PublicAPI.Unshipped.txt | Records new public handler constructor overload for .NET (Core) targets. |
| src/Microsoft.Identity.Web.TokenAcquisition/Properties/InternalsVisibleTo.cs | Grants DownstreamApi access to TokenAcquisition internals used by the refactor. |
| src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs | Implements mTLS-only support + cert-failure retry orchestration in the handler. |
| src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityHttpClientBuilderExtensions.cs | Improves DI resolution for logger, mTLS factory, and credentials provider. |
| src/Microsoft.Identity.Web.TokenAcquisition/GlobalSuppressions.cs | Adds analyzer suppression for the new overload signature. |
| src/Microsoft.Identity.Web.TokenAcquisition/Constants.cs | Centralizes protocol names and auth-failure status code set. |
| src/Microsoft.Identity.Web.DownstreamApi/Microsoft.Identity.Web.DownstreamApi.csproj | Removes AOT attribute polyfill include (affects older TFMs). |
| src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs | Switches to shared constants and uses moved diagnostics exception. |
| src/Microsoft.Identity.Web.Diagnostics/UnauthorizedHttpRequestException.cs | Introduces moved exception type used for certificate-failure reporting. |
Comments suppressed due to low confidence (1)
src/Microsoft.Identity.Web.DownstreamApi/Microsoft.Identity.Web.DownstreamApi.csproj:18
Microsoft.Identity.Web.DownstreamApitargetsnet462/net472/netstandard2.0(see the PublicAPI conditional), but the csproj no longer linkssrc/Shared/CodeAnalysisAttributes.cs. This file polyfillsRequiresUnreferencedCodeAttribute/RequiresDynamicCodeAttributefor NETFRAMEWORK/NETSTANDARD2_0, and DownstreamApi uses these attributes unconditionally inDownstreamApi.cs. Without the polyfill, older TFMs will fail to compile. Re-add the conditional<Compile Include="..\Shared\CodeAnalysisAttributes.cs" ...>item group (as done in TokenAcquisition) or gate the attribute usages behind#iffor TFMs that provide them.
<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…com/AzureAD/microsoft-identity-web into MicrosoftIdentityMessageHandlerMtls
This was referenced Jun 24, 2026
Closed
Open
Open
Merged
Merged
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MTLS Without Tokens Support - MicrosoftIdentityMessageHandler Support
Continuation of the PR #3747 , this adds the same level of support to MicrosoftIdentityMessageHandler.
Description
Microsoft.Identity.Web.TokenAcquisition/Constants.csMicrosoft.Identity.Web.TokenAcquisition(Internal class)Microsoft.Identity.Web.TokenAcquisitionandMicrosoft.Identity.Web.DownstreamApiso that the above changes are accessible.MicrosoftIdentityHttpClientBuilderExtensions:MicrosoftIdentityMessageHandler. Now, it will pass one if configured.IMsalMtlsHttpFactoryeven if one were configured. Now, it will use a configured one if available.