Fix browser token auth over HTTP - #16818
Conversation
Use a distinct dashboard auth cookie name for browser-token auth on HTTP endpoints so stale HTTPS cookie state cannot shadow an HTTP sign-in. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16818Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16818" |
Run forwarded header normalization before browser-token validation so sign-in cookie naming uses the same scheme as later authorization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes browser-token dashboard authentication when the dashboard is reachable over both HTTPS and HTTP (notably Safari’s localhost cookie behavior) by separating cookie names per scheme and adding integration coverage for mixed-scheme scenarios.
Changes:
- Introduces an
ICookieManagerimplementation that uses a distinct cookie name for HTTP requests while keeping the existing cookie name for HTTPS. - Ensures
UseForwardedHeaders()runs before browser-token validation so the normalized scheme influences cookie issuance correctly. - Adds integration tests covering mixed HTTPS/HTTP login flows and cookie emission semantics.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/Aspire.Dashboard.Tests/Integration/FrontendBrowserTokenAuthTests.cs | Adds mixed-scheme integration tests for browser-token redirects and cookie name/Secure behavior. |
| src/Aspire.Dashboard/DashboardWebApplication.cs | Wires the new cookie manager and moves forwarded-headers middleware earlier in the pipeline. |
| src/Aspire.Dashboard/Authentication/BrowserTokenCookieManager.cs | Adds scheme-dependent cookie naming logic to avoid HTTP/HTTPS cookie collisions. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| return Task.CompletedTask; | ||
| }; | ||
| options.Cookie.Name = DashboardAuthCookieName; | ||
| options.CookieManager = new BrowserTokenCookieManager(DashboardHttpAuthCookieName); |
There was a problem hiding this comment.
What about OAuth? Should it set this? If so, rename to AspireDashboardCookieManager
There was a problem hiding this comment.
Applied to OpenID Connect as well in #17368: the manager is now AspireDashboardCookieManager, and both OIDC and browser-token auth use it.
| Assert.Contains(deletedCookies, c => c.StartsWith(".Aspire.Dashboard.Auth=", StringComparison.Ordinal) && c.Contains("expires=Thu, 01 Jan 1970", StringComparison.OrdinalIgnoreCase)); | ||
| Assert.Contains(deletedCookies, c => c.StartsWith(".Aspire.Dashboard.Auth.Http=", StringComparison.Ordinal) && c.Contains("expires=Thu, 01 Jan 1970", StringComparison.OrdinalIgnoreCase)); |
There was a problem hiding this comment.
Assert.Collection here to be explicit?
There was a problem hiding this comment.
Changed to Assert.Collection in #17368 so the two expected deleted cookies are asserted explicitly.
|
This change is too risky for 13.3. Soonest it should go in is 13.4. |
|
This isn't a regression right? |
|
I don't think so. Nothing has changed here. |
|
Marking as draft, since the issue was pushed back to 13.4 |
Description
Fixes #16067
This fixes browser-token dashboard authentication when the dashboard is available over both HTTPS and HTTP. Safari can retain HTTPS localhost cookie state that shadows a later HTTP browser-token sign-in, causing the dashboard to prompt for the token repeatedly even after a successful sign-in.
Changes:
.Aspire.Dashboard.Auth.Httpcookie name for HTTP requests while keeping.Aspire.Dashboard.Authfor HTTPS requests.Validation:
dotnet test --project tests/Aspire.Dashboard.Tests/Aspire.Dashboard.Tests.csproj --no-launch-profile -- --filter-class "*.FrontendBrowserTokenAuthTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"dotnet test --project tests/Aspire.Dashboard.Tests/Aspire.Dashboard.Tests.csproj --no-launch-profile -- --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"Checklist
<remarks />and<code />elements on your triple slash comments?aspire.devissue: