Skip to content

MTLS Without Tokens Support - MicrosoftIdentityMessageHandler Support#3815

Merged
tlupes merged 27 commits into
masterfrom
MicrosoftIdentityMessageHandlerMtls
Jun 15, 2026
Merged

MTLS Without Tokens Support - MicrosoftIdentityMessageHandler Support#3815
tlupes merged 27 commits into
masterfrom
MicrosoftIdentityMessageHandlerMtls

Conversation

@tlupes

@tlupes tlupes commented May 13, 2026

Copy link
Copy Markdown
Collaborator

MTLS Without Tokens Support - MicrosoftIdentityMessageHandler Support

Continuation of the PR #3747 , this adds the same level of support to MicrosoftIdentityMessageHandler.

Description

  • Moved shared constants from DownstreamAPI to Microsoft.Identity.Web.TokenAcquisition/Constants.cs
  • Moved UnauthorizedHttpRequestException to Microsoft.Identity.Web.TokenAcquisition (Internal class)
  • Add InternalsVisibleTo between Microsoft.Identity.Web.TokenAcquisition and Microsoft.Identity.Web.DownstreamApi so that the above changes are accessible.
  • Minor changes to MicrosoftIdentityHttpClientBuilderExtensions:
    • Previously this would always pass a null logger to the MicrosoftIdentityMessageHandler. Now, it will pass one if configured.
    • Previously it would always make a new IMsalMtlsHttpFactory even if one were configured. Now, it will use a configured one if available.
    • Support to pass a ICredentialsProvider to the handler.
  • Support within MicrosoftIdentityMessageHandler for mTLS without tokens

@tlupes tlupes requested a review from a team as a code owner May 13, 2026 16:24

@neha-bhargava neha-bhargava left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments

Comment thread src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs Outdated
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs Outdated
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs Outdated
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/Constants.cs Outdated
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/GlobalSuppressions.cs Outdated
Comment thread tests/Microsoft.Identity.Web.Test/CertificatesObserverTests.cs Outdated
tlupes and others added 5 commits May 19, 2026 10:56
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>
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/Constants.cs Outdated
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs Outdated
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs Outdated
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs Outdated
tlupes and others added 6 commits May 25, 2026 15:17
… 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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.cs and updates DownstreamApi/TokenAcquisition to consume them.
  • Updates HttpClient builder extensions to resolve configured IMsalMtlsHttpClientFactory, pass a logger, and optionally construct/use an ICredentialsProvider.

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.DownstreamApi targets net462/net472/netstandard2.0 (see the PublicAPI conditional), but the csproj no longer links src/Shared/CodeAnalysisAttributes.cs. This file polyfills RequiresUnreferencedCodeAttribute / RequiresDynamicCodeAttribute for NETFRAMEWORK/NETSTANDARD2_0, and DownstreamApi uses these attributes unconditionally in DownstreamApi.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 #if for 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>

Comment thread src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
Comment thread src/Microsoft.Identity.Web.TokenAcquisition/MicrosoftIdentityMessageHandler.cs Outdated
Comment thread tests/Microsoft.Identity.Web.Test/CertificatesObserverTests.cs Outdated
tlupes and others added 4 commits May 25, 2026 21:10
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This was referenced Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants