Skip to content

fix(web): Disable OIDC PAR so a Keycloak restart / stale cookie can't dead-end login - #144

Merged
hoangsnowy merged 1 commit into
mainfrom
fix/oidc-disable-par
Aug 10, 2026
Merged

fix(web): Disable OIDC PAR so a Keycloak restart / stale cookie can't dead-end login#144
hoangsnowy merged 1 commit into
mainfrom
fix/oidc-disable-par

Conversation

@hoangsnowy

Copy link
Copy Markdown
Owner

Change description

.NET's OIDC handler auto-enables Pushed Authorization Requests (PAR) whenever the IdP advertises a pushed_authorization_request_endpoint — Keycloak does. The browser is then redirected to /auth?request_uri=urn:ietf:… and Keycloak must resolve that reference from its in-memory PAR store. Restarting Keycloak (dev volume reset, container recreate) or a stale browser session cookie drops that reference → Keycloak can't recover the pushed params → Missing parameter: response_type and login dead-ends.

The agentic realm does not require PAR, so this disables it (PushedAuthorizationBehavior.Disable) and falls back to the classic authorization-code flow — response_type is carried in the URL, there is no server-side reference to lose, so a Keycloak restart or a stale cookie can no longer break login.

Follow-up to #143 (dev header-limit 512K) on the same login-robustness thread.

Type of change

  • Bugfix

Related issues

Follow-up to #143.

Checklist

  • dotnet build passes locally in Release mode (Web built + booted via Aspire AppHost)
  • dotnet test — CI runs the full suite on PR→main; change is OIDC config only (no unit surface)
  • No secrets committed
  • README / docs updated if public behavior changed — n/a (dev-login robustness)
  • Measurable results provided — n/a

Test plan (E2E, full Aspire stack)

Verified on the real stack (dotnet run --project infra/AgentOs.AppHost), clean KC + Postgres volumes:

  1. curl -k -i https://localhost:5180/account/login302 to …/realms/agentic/protocol/openid-connect/auth?client_id=…&response_type=code&code_challenge=…no request_uri=urn:ietf:…, confirming PAR is off and params ride the URL.
  2. Browser login operator / operator on real Keycloak → OIDC callback → Blazor circuit → GNOME desktop loads (screenshot captured).
  3. No HTTP 431; Keycloak AgentOS theme renders from the re-imported realm.

… cookie can't dead-end it

.NET's OIDC handler auto-enables Pushed Authorization Requests whenever the IdP
advertises a pushed_authorization_request_endpoint — Keycloak does — so the browser
was redirected to /auth?request_uri=urn:... and Keycloak had to resolve that
reference from its in-memory PAR store. Restarting Keycloak (or a stale browser
session cookie) drops the reference, Keycloak can't recover the pushed params, and
login dead-ends with "Missing parameter: response_type". A fresh cookie jar worked;
the real browser did not — which read like the 431 was back, but it was this.

The realm does not require PAR, so the classic authorization-code flow (response_type
carried in the URL) is both valid and robust: no server-side reference to lose, so a
Keycloak restart or a stale cookie cannot break the redirect. Sets
options.PushedAuthorizationBehavior = Disable.

Verified: the login redirect now carries response_type=code&scope=openid&
code_challenge=... directly (no request_uri=urn:), the full flow reaches the login
page (200), and the real browser with its pre-existing cookies lands on the AgentOS
sign-in page instead of the Keycloak error page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@hoangsnowy
hoangsnowy merged commit bf5d2ff into main Aug 10, 2026
4 checks passed
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.

1 participant