v11 update: SignalR .NET client supports authentication refresh after redirects
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
- Issue type
- Documentation
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- csharp
- Domain
- documentation
Research direction
Start in aspnetcore/signalr/authn-and-authz.md at the .NET 11 Authentication refresh section around lines 275–279, then review the linked HttpConnection.cs and release note for redirect behavior. Done means the article explains app and transport tokens, refresh scheduling after redirects, and the current Azure SignalR Service limitation within the existing .NET 11 moniker zone.
Written by the indexing model from the issue text.
Description
[!NOTE]
This is an AI-assisted coverage analysis of the What's new in ASP.NET Core in .NET 11 release note, reviewed by a human before filing. Every line number and permalink refers to the pinned commits below. Companion issue: the core authentication refresh feature is covered in https://github.com/dotnet/AspNetCore.Docs/issues/37691, which edits the same article.
Target repository: dotnet/AspNetCore.Docs
Analyzed at commit: 4986136881f2bbf1879f10106467769df5a49932
Product source verified at: dotnet/aspnetcore @ 1fcd7ef305697a1888f3ede076010350ae9f4f8d
Source release note: SignalR .NET client supports authentication refresh after redirects
🎯 Goal
The authentication refresh feature itself is well documented — see dotnet/AspNetCore.Docs#37691 for the verification record. What's missing is everything specific to this sub-area: not one article in the docset mentions negotiate redirects in connection with authentication refresh, and no article mentions Azure SignalR Service in that context either. A docset-wide search for "redirect" scoped to aspnetcore/signalr/ returns only reconnection and HTTPS-redirection content.
This matters more than a typical discoverability gap because the release note itself flags a deployment trap: the client-side support exists, but the redirecting server most readers will use — Azure SignalR Service — hasn't enabled the server half yet. A reader who enables WithAuthenticationRefresh behind Azure SignalR today gets a connection that never schedules a refresh, with nothing in the docs explaining why.
This report proposes one change: a short subsection in the existing .NET 11 Authentication refresh section of xref:signalr/authn-and-authz covering redirect behavior and the current Azure SignalR status.
✅ Coverage status summary
Legend: ✅ already documented · ✏️ update needed · 🟣 could not determine
| # | Feature element from What's New | Status | Where |
|---|---|---|---|
| 1 | Authentication refresh works when negotiate redirects to another server | ✏️ | 1. Update — aspnetcore/signalr/authn-and-authz.md L275–L279 |
| 2 | The client preserves the app-token provider across the redirect and uses it to authenticate the refresh request | ✏️ | 1. Update |
| 3 | The client adopts a refreshed transport token returned by the /refresh response |
✏️ | 1. Update |
| 4 | The reported token lifetime is retained across the redirect so automatic refresh stays scheduled | ✏️ | 1. Update |
| 5 | Redirecting servers such as Azure SignalR Service are the scenario this enables | ✏️ | 1. Update |
| 6 | The .NET client article has no path to authentication refresh at all | ✏️ | Tracked in dotnet/AspNetCore.Docs#37691, change 4 — not re-proposed here |
| 7 | The .NET client refreshes using the connection's AccessTokenProvider |
✅ | authn-and-authz.md L168 |
| 8 | RefreshAuthenticationAsync returns the new token lifetime reported by the server |
✅ | authn-and-authz.md L170–L183 |
| 9 | Automatic refresh is scheduled only when the server reports a token lifetime | ✅ | authn-and-authz.md L202, L277 |
| 10 | Refresh requires a connection that negotiated protocol version 1 or later | ✅ | authn-and-authz.md L277 |
| 11 | The client feature matrix lists Authentication Refresh at 11.0.0 for the .NET client | ✅ | aspnetcore/signalr/client-features.md L43 |
| 12 | Whether Azure SignalR Service has enabled the server half | 🟣 | See Review considerations |
🔢 Version applicability
Applies to: CURRENT-ONLY
Target moniker: >= aspnetcore-11.0
Earlier versions affected: None. Authentication refresh doesn't exist before .NET 11, so redirect support for it can't either. Evidence: 326d566 — Support SignalR authentication refresh after negotiate redirects (#67612), merged 2026-07-21, contributed by @MoChilia. git show --stat on that commit shows it touched exactly three files: HttpConnection.cs, AccessTokenHttpMessageHandler.cs, and a test file. It adds no public API, so nothing changes in PublicAPI.Unshipped.txt.
| Article | monikerRange |
Moniker state |
|---|---|---|
aspnetcore/signalr/authn-and-authz.md |
'>= aspnetcore-3.1' |
State C — the insertion point at line 277 is inside the existing :::moniker range=">= aspnetcore-11.0" zone spanning L121–L279. Insert directly; no split, no new directives, zone counts unchanged. |
📋 Coverage gap summary
Both scenarios that lead a reader here end badly today.
A developer running SignalR behind Azure SignalR Service enables WithAuthenticationRefresh, deploys, and observes that the refresh never fires. xref:signalr/authn-and-authz tells them automatic refresh is scheduled only when the server reports a token lifetime, but nothing tells them their redirecting service doesn't report one yet. There's no way to distinguish "I configured it wrong" from "the service doesn't support this".
A developer writing their own redirecting negotiate endpoint needs to know which token authenticates the /refresh request. This is genuinely subtle: the client keeps two tokens after a redirect. The token from AccessTokenProvider authenticates against the app's own negotiate endpoint, and the token returned in the redirect response authenticates the transport against the redirect target. Refresh uses the first one, and a /refresh response can supply a new value for the second. Nothing in the docset says so, and the distinction isn't guessable.
Feature announced in What's New:
The SignalR .NET client extends SignalR authentication refresh so it works when negotiate redirects to another server, contributed by @MoChilia. This client change enables support for redirecting servers such as Azure SignalR Service, which hasn't enabled the feature yet.
The client preserves the app-token provider across the redirect, adopts a refreshed transport token from the response, and retains
tokenLifetimeSecondsso automatic refresh remains scheduled after the original token expires.
Breaking change: No. This is a fix within a feature that's new in the same release.
📁 Affected files
| Item | Path | Lines | Section |
|---|---|---|---|
| 1. | aspnetcore/signalr/authn-and-authz.md |
275–279 | "Authentication refresh" (end of the .NET 11 zone) |
Target article uid: signalr/authn-and-authz
📝 Proposed changes
✏️ 1. Update — aspnetcore/signalr/authn-and-authz.md, insert after line 277
Applies to: >= aspnetcore-11.0 (already the enclosing zone — State C, insert directly)
Location: Line 277, after the closing caveat paragraph and immediately before the :::moniker-end that closes the .NET 11 zone.
Before (lines 275–279):
A hub method that's already running keeps the `Context.User` it started with. Later invocations observe the refreshed `Context.User`. For more information about how SignalR caches the authenticated user, see [User and role changes during the connection lifetime](#user-and-role-changes-during-the-connection-lifetime).
Authentication refresh requires a connection that negotiated protocol version 1 or later. Automatic refresh is scheduled only when the server reports a token lifetime, which typically comes from an authentication scheme that sets an expiration, such as bearer tokens. Windows authentication doesn't report an expiration and isn't tracked or refreshed by this feature.
:::moniker-end
After:
A hub method that's already running keeps the `Context.User` it started with. Later invocations observe the refreshed `Context.User`. For more information about how SignalR caches the authenticated user, see [User and role changes during the connection lifetime](#user-and-role-changes-during-the-connection-lifetime).
Authentication refresh requires a connection that negotiated protocol version 1 or later. Automatic refresh is scheduled only when the server reports a token lifetime, which typically comes from an authentication scheme that sets an expiration, such as bearer tokens. Windows authentication doesn't report an expiration and isn't tracked or refreshed by this feature.
#### Refresh through a redirecting negotiate endpoint
A negotiate endpoint can redirect a client to a different server, which is how Azure SignalR Service and similar services take over the connection. After a redirect, the .NET client holds two tokens:
* The **app token** from the `AccessTokenProvider` configured on the connection. It authenticates requests to the app's own negotiate endpoint.
* The **transport token** returned in the redirect response. It authenticates the transport connection to the redirect target.
The .NET client uses the app token to authenticate refresh requests, so `AccessTokenProvider` continues to be called for each refresh after a redirect. The token lifetime reported by any negotiate response in the redirect chain is retained, so automatic refresh stays scheduled. If the refresh response returns a new transport token, the client adopts it for subsequent transport requests. A self-hosted SignalR server doesn't return one, because the transport token and the app token are the same.
> [!IMPORTANT]
> The redirect target must implement the refresh endpoint for any of this to take effect. As of .NET 11, Azure SignalR Service doesn't support authentication refresh. A connection through a service that doesn't report a token lifetime never schedules an automatic refresh, and `RefreshAuthenticationAsync` fails. Check the service's documentation before enabling authentication refresh in an app that runs behind it.
:::moniker-end
Rationale: This is the article that already documents the whole feature, and the redirect behavior is a property of the feature rather than of the .NET client's transport internals — so it belongs here, inside the existing Authentication refresh section, rather than in a new section of xref:signalr/dotnet-client. dotnet/AspNetCore.Docs#37691 change 4 adds the pointer from the .NET client article that makes this reachable.
Verified against HttpConnection.cs: the redirect loop preserves _appAccessTokenProvider while replacing _accessTokenProvider with the transport token from the redirect response; GetRefreshRequestTokenAsync uses the app-token provider for the refresh request; _initialTokenLifetime is captured from any negotiate in the chain; and RefreshAuthenticationAsync adopts an accessToken from the refresh response by calling UpdateCachedToken when one is present.
✅ 2. Update — TOC
No TOC change required. xref:signalr/authn-and-authz already has a TOC entry, and no new article is proposed.
✅ Action plan
- Confirm the Azure SignalR Service statement with the SignalR or Azure SignalR team before publishing. The release note says the service "hasn't enabled the feature yet", which is a point-in-time claim — see Review considerations.
- Apply change 1. It's a State C insertion inside an existing
>= aspnetcore-11.0zone, so no moniker directives are added or removed.authn-and-authz.mdhas 10:::moniker range=openers and 10:::moniker-endclosers before and after. - Verify the
[User and role changes during the connection lifetime](#user-and-role-changes-during-the-connection-lifetime)anchor in the surrounding text still resolves after the insertion, and that the new#### Refresh through a redirecting negotiate endpointheading produces a unique anchor. - Coordinate with dotnet/AspNetCore.Docs#37691, which edits the same article. Apply that issue's changes 1 and 2 first (they're earlier in the file) or this change first (it's later in the file) — either order works as long as the line numbers used are re-read after the first edit lands.
- Build and confirm the new content renders under the .NET 11 selector only.
- Resolve any OpenPublishing.Build warnings.
⚠️ Review considerations
- 🟣 Has Azure SignalR Service enabled authentication refresh since the release note was written? This audit can verify the ASP.NET Core client and server halves from
dotnet/aspnetcoresource, but Azure SignalR Service is a separate, closed-source service. TheIMPORTANTnote in change 1 is worded as a point-in-time statement about .NET 11 for that reason. If the service has shipped support, drop the note and replace it with a link to the Azure SignalR documentation. If support is planned, consider wording it as "not yet supported" with a tracking link instead. - 🟣 Should the Azure SignalR documentation carry the same warning? The natural place for a reader already on Azure SignalR is the service's own docs (
/azure/azure-signalr/), which are outside this docset. Worth raising with that content team separately. - Finding worth noting in review: the TypeScript client, added later in #67964, already contains equivalent redirect handling —
_setTransportAccessToken, the initial token lifetime captured inside_getNegotiationResponse, and adoption of anaccessTokenfrom the refresh response. So this sub-area is a .NET client catching up within the same release, not a lasting capability difference between clients. The proposed text is therefore written to describe the shipped behavior rather than as a .NET-client-only caveat, which avoids implying the TypeScript client behaves differently. - Deliberately not proposed: a change to xref:signalr/scale, the Azure SignalR Service article in this docset. It's the article a reader scaling out would open, but documenting a feature the service doesn't support yet would create content that's wrong the moment support ships, and stale if it doesn't. Revisit once the 🟣 above is answered.
- Out of scope for this issue: the core authentication refresh feature (dotnet/AspNetCore.Docs#37691) and the TypeScript client APIs (tracked in a companion issue for SignalR TypeScript client supports authentication refresh).
🔗 References
- What's New section: SignalR .NET client supports authentication refresh after redirects
- Implementing PR: #67612 (commit
326d566), contributed by @MoChilia - Product source — redirect loop, app-token preservation, refresh-request token, and transport-token adoption:
HttpConnection.cs - Product source — server-side
/refreshresponse shape:HttpConnectionDispatcher.csL124–L262 - Related issue: dotnet/AspNetCore.Docs#37691 — v11 update: SignalR authentication refresh (adds the .NET client article cross-reference this content depends on for discoverability)
- Dominant language
- C#
- Stars
- 13.1k
- Forks
- 24.6k
- Avg merge
- 21h 10m
- Merged PRs (30d)
- 113
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/AspNetCore.Docs
-
:watch: Not Triaged 11.0 security/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
dotnet/AspNetCore.Docs#37710 ·
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
dotnet/AspNetCore.Docs#37698 ·
-
:watch: Not Triaged aspnet-core/svc fundamentals/subsvc Source - Docs.ms
Difficulty 2/5 1-2 days Newbie friendliness 78/100
dotnet/AspNetCore.Docs#37677 ·
-
:watch: Not Triaged aspnet-core/svc security/subsvc Source - Docs.ms
Difficulty 1/5 1-3 hours Newbie friendliness 78/100
dotnet/AspNetCore.Docs#37667 ·
All issues in dotnet/AspNetCore.Docs
Similar issues
-
type/automation type/tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
t/bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
ci-failure-cause test-failure
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
area:auth FE mvp P3
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
klasolsson81/jobbliggaren#1788 ·