You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tell a reader of the Windows Authentication article that, on Kestrel over HTTPS, Negotiate now cryptographically binds the Kerberos/NTLM exchange to the TLS channel automatically — a security hardening (Extended Protection for Authentication) they get for free in .NET 11. The Kestrel section of security/authentication/windowsauth.md says nothing about it today, and the one channel-binding note that does exist in the article is about a different server (HTTP.sys) and a different, opt-in mechanism, so leaving this undocumented invites readers to conflate the two.
This is a behavior change with no new public API. Searching the docset for a new type or member finds nothing; the feature element is the behavior itself, verified against product source.
✅ Coverage status summary
Legend: ✅ already documented · ✏️ update needed · 🟣 could not determine
#
Feature element from What's New
Status
Where
1
Negotiate on Kestrel uses the TLS endpoint channel binding token for HTTPS connections
The handler supplies the token to the Kerberos/NTLM exchange and retains it across multi-round authentication
✏️
1. Update — same note
3
No configuration required; non-HTTPS connections and HTTPS connections without a channel binding token keep the previous behavior
✏️
1. Update — same note
—
Existing article CBT note applies to this feature
✅ (distinct)
The L265–L266 note is HTTP.sys-specific (opt-in EnableCBTHardening AppContext switch) — it does not cover the new Kestrel behavior. Must be kept distinct.
🔢 Version applicability
Applies to:CURRENT-ONLY Target moniker:>= aspnetcore-11.0 Earlier versions affected: None — automatic TLS channel binding for Negotiate on Kestrel is new in .NET 11.
Article
monikerRange
Moniker state
security/authentication/windowsauth.md
'>= aspnetcore-3.1' (front matter)
State D — the insertion point (L175, Kestrel section) sits inside the broader >= aspnetcore-6.0 body zone (L16–L313). A full four-directive split is required: close >= aspnetcore-6.0, open >= aspnetcore-11.0, add the note, close it, reopen >= aspnetcore-6.0.
The article's body has exactly two zones — >= aspnetcore-6.0 (L16–L313) and < aspnetcore-6.0 (L315–L619). There are no tab groups anywhere in the file, so the split carries no tab-nesting hazard.
📋 Coverage gap summary
The Kestrel section opens at L169 and runs through a WARNING about proxy connection affinity (L173–L174) and a NOTE about native Windows Authentication detection (L176–L177), then into the Program.cs sample — with no mention of channel binding. A developer hardening a Kestrel-hosted intranet app against NTLM relay has no way to learn from this article that .NET 11 already does it for them on HTTPS. The only channel-binding text in the article, at L265–L266, sits in the HTTP.sys section and describes the opt-in Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening AppContext switch — a separate feature on a separate server that is off by default. Presenting the two without distinction would mislead.
Feature announced in What's New:
Negotiate authentication on Kestrel uses the TLS endpoint channel binding token for HTTPS connections. The authentication handler supplies the token to the underlying Kerberos or NTLM exchange and retains it across multi-round authentication.
No configuration changes are required. Non-HTTPS connections and HTTPS connections where a channel binding token isn't available continue to use the existing behavior.
Product source confirms the mechanism: the Negotiate handler reads the token from the connection's TLS feature — ITlsConnectionFeature.TryGetChannelBindingBytes(ChannelBindingKind.Endpoint, out …) — and wraps it for the Kerberos/NTLM exchange. It is automatic and unconditional for HTTPS connections that expose an endpoint CBT; there is no option to configure.
Breaking change: No — additive hardening with a documented fallback to prior behavior.
✏️ 1. Update — security/authentication/windowsauth.md, add a channel-binding note to the Kestrel section (State D split at line 175)
Applies to:>= aspnetcore-11.0 Location:Lines 173–177, between the Kestrel WARNING block (ends L174) and the "native Windows Authentication detection" NOTE (starts L176).
Before (lines 173–177):
> [!WARNING]> Credentials can be persisted across requests on a connection. *Negotiate authentication must not be used with proxies unless the proxy maintains a 1:1 connection affinity (a persistent connection) with Kestrel.*> [!NOTE]> The Negotiate handler detects if the underlying server supports Windows Authentication natively and if it is enabled. If the server supports Windows Authentication but it is disabled, an error is thrown asking you to enable the server implementation. When Windows Authentication is enabled in the server, the Negotiate handler transparently forwards authentication requests to it.
After:
> [!WARNING]> Credentials can be persisted across requests on a connection. *Negotiate authentication must not be used with proxies unless the proxy maintains a 1:1 connection affinity (a persistent connection) with Kestrel.*:::moniker-end
:::moniker range=">= aspnetcore-11.0"
> [!NOTE]> Beginning with .NET 11, Negotiate authentication on Kestrel binds the authentication exchange to the connection using the [TLS endpoint channel binding token](/dotnet/api/system.security.authentication.extendedprotection.channelbinding) for HTTPS connections. The handler supplies the token to the underlying Kerberos or NTLM exchange and retains it across multi-round authentication, which helps mitigate NTLM relay and man-in-the-middle attacks. No configuration is required. Non-HTTPS connections, and HTTPS connections where a channel binding token isn't available, continue to use the previous behavior.:::moniker-end
:::moniker range=">= aspnetcore-6.0"
> [!NOTE]> The Negotiate handler detects if the underlying server supports Windows Authentication natively and if it is enabled. If the server supports Windows Authentication but it is disabled, an error is thrown asking you to enable the server implementation. When Windows Authentication is enabled in the server, the Negotiate handler transparently forwards authentication requests to it.
Rationale: The behavior is Kestrel-specific (on HTTP.sys, Windows Authentication is handled in kernel mode, not by the Negotiate handler), so the Kestrel section is the correct home. The note is scoped >= aspnetcore-11.0 because the automatic binding is new in .NET 11, and the surrounding content must remain >= aspnetcore-6.0 — hence the four-directive split. The wording deliberately parallels, but does not merge with, the HTTP.sys CBT-hardening note at L265–L266 so readers don't confuse the automatic Kestrel behavior with the opt-in HTTP.sys AppContext switch.
✅ 2. Update — TOC
No TOC change required. The edit adds a note to an article already in the TOC.
✅ Action plan
Confirm the coverage status summary — element 1 is a genuine gap; the L265–L266 note is HTTP.sys-only and must stay distinct.
Apply change 1 as a State D four-directive split. After editing, verify moniker balance: the file should have 4 :::moniker range= openers and 4 :::moniker-end closers (up from 2 and 2), with the reopened >= aspnetcore-6.0 range copied character-for-character.
Confirm the /dotnet/api/system.security.authentication.extendedprotection.channelbinding link resolves; if a more specific conceptual target is preferred, substitute it.
Build and confirm the new NOTE renders only under the .NET 11 selector while the detection NOTE renders for 6.0+.
Resolve any OpenPublishing.Build warnings.
⚠️ Review considerations
🟣 Depth of cross-reference to ITlsConnectionFeature.TryGetChannelBindingBytes. The enabling server-side API (RFC 5929 endpoint CBT exposure) is documented for HTTP.sys in breaking-changes/11/httpsys-channel-binding-token-enabled.md. Whether the Kestrel note should cross-link that breaking-change article (different server, but the same underlying ITlsConnectionFeature API) is an editorial call; the proposed note keeps it simple and omits the link to avoid implying the HTTP.sys opt-out applies to Kestrel.
Out of scope: the corresponding Miscellaneous-area feature that exposes ITlsConnectionFeature.TryGetChannelBindingBytes to application code — not yet analyzed at the time of filing; this issue covers only the Negotiate-on-Kestrel consumer behavior. If that feature is filed later, cross-link the two.
Note
This is an AI-assisted coverage analysis created by wadepickett.
Target repository:
dotnet/AspNetCore.DocsAnalyzed at commit:
4986136881f2bbf1879f10106467769df5a49932Product source verified at:
dotnet/aspnetcore@1fcd7ef305697a1888f3ede076010350ae9f4f8dSource release note: Negotiate authentication uses TLS channel binding
🎯 Goal
Tell a reader of the Windows Authentication article that, on Kestrel over HTTPS, Negotiate now cryptographically binds the Kerberos/NTLM exchange to the TLS channel automatically — a security hardening (Extended Protection for Authentication) they get for free in .NET 11. The Kestrel section of
security/authentication/windowsauth.mdsays nothing about it today, and the one channel-binding note that does exist in the article is about a different server (HTTP.sys) and a different, opt-in mechanism, so leaving this undocumented invites readers to conflate the two.This is a behavior change with no new public API. Searching the docset for a new type or member finds nothing; the feature element is the behavior itself, verified against product source.
✅ Coverage status summary
Legend: ✅ already documented · ✏️ update needed · 🟣 could not determine
security/authentication/windowsauth.mdL173–L177 (Kestrel section)EnableCBTHardeningAppContext switch) — it does not cover the new Kestrel behavior. Must be kept distinct.🔢 Version applicability
Applies to:
CURRENT-ONLYTarget moniker:
>= aspnetcore-11.0Earlier versions affected: None — automatic TLS channel binding for Negotiate on Kestrel is new in .NET 11.
monikerRangesecurity/authentication/windowsauth.md'>= aspnetcore-3.1'(front matter)>= aspnetcore-6.0body zone (L16–L313). A full four-directive split is required: close>= aspnetcore-6.0, open>= aspnetcore-11.0, add the note, close it, reopen>= aspnetcore-6.0.The article's body has exactly two zones —
>= aspnetcore-6.0(L16–L313) and< aspnetcore-6.0(L315–L619). There are no tab groups anywhere in the file, so the split carries no tab-nesting hazard.📋 Coverage gap summary
The Kestrel section opens at L169 and runs through a WARNING about proxy connection affinity (L173–L174) and a NOTE about native Windows Authentication detection (L176–L177), then into the
Program.cssample — with no mention of channel binding. A developer hardening a Kestrel-hosted intranet app against NTLM relay has no way to learn from this article that .NET 11 already does it for them on HTTPS. The only channel-binding text in the article, at L265–L266, sits in the HTTP.sys section and describes the opt-inMicrosoft.AspNetCore.Server.HttpSys.EnableCBTHardeningAppContext switch — a separate feature on a separate server that is off by default. Presenting the two without distinction would mislead.Feature announced in What's New:
Product source confirms the mechanism: the Negotiate handler reads the token from the connection's TLS feature —
ITlsConnectionFeature.TryGetChannelBindingBytes(ChannelBindingKind.Endpoint, out …)— and wraps it for the Kerberos/NTLM exchange. It is automatic and unconditional for HTTPS connections that expose an endpoint CBT; there is no option to configure.Breaking change: No — additive hardening with a documented fallback to prior behavior.
📁 Affected files
security/authentication/windowsauth.mdTarget article uids:
security/authentication/windowsauth📝 Proposed changes
✏️ 1. Update —
security/authentication/windowsauth.md, add a channel-binding note to the Kestrel section (State D split at line 175)Applies to:
>= aspnetcore-11.0Location: Lines 173–177, between the Kestrel WARNING block (ends L174) and the "native Windows Authentication detection" NOTE (starts L176).
Before (lines 173–177):
After:
Rationale: The behavior is Kestrel-specific (on HTTP.sys, Windows Authentication is handled in kernel mode, not by the Negotiate handler), so the Kestrel section is the correct home. The note is scoped
>= aspnetcore-11.0because the automatic binding is new in .NET 11, and the surrounding content must remain>= aspnetcore-6.0— hence the four-directive split. The wording deliberately parallels, but does not merge with, the HTTP.sys CBT-hardening note at L265–L266 so readers don't confuse the automatic Kestrel behavior with the opt-in HTTP.sys AppContext switch.✅ 2. Update — TOC
No TOC change required. The edit adds a note to an article already in the TOC.
✅ Action plan
:::moniker range=openers and 4:::moniker-endclosers (up from 2 and 2), with the reopened>= aspnetcore-6.0range copied character-for-character./dotnet/api/system.security.authentication.extendedprotection.channelbindinglink resolves; if a more specific conceptual target is preferred, substitute it.ITlsConnectionFeature.TryGetChannelBindingBytes. The enabling server-side API (RFC 5929 endpoint CBT exposure) is documented for HTTP.sys inbreaking-changes/11/httpsys-channel-binding-token-enabled.md. Whether the Kestrel note should cross-link that breaking-change article (different server, but the same underlyingITlsConnectionFeatureAPI) is an editorial call; the proposed note keeps it simple and omits the link to avoid implying the HTTP.sys opt-out applies to Kestrel.ITlsConnectionFeature.TryGetChannelBindingBytesto application code — not yet analyzed at the time of filing; this issue covers only the Negotiate-on-Kestrel consumer behavior. If that feature is filed later, cross-link the two.🔗 References
security/authentication/windowsauth.mdL265–L266src/Security/Authentication/Negotiate/src/NegotiateHandler.csL413–L419 —GetChannelBindingToken()callsITlsConnectionFeature.TryGetChannelBindingBytes(ChannelBindingKind.Endpoint, …); consumed at L134.src/Security/Authentication/Negotiate/src/Internal/NegotiateChannelBinding.csL9 —internal sealed class NegotiateChannelBinding : ChannelBinding(no new public symbol).breaking-changes/11/httpsys-channel-binding-token-enabled.md