Commit 9371dc6
Swap admin auth to standard Blazor OIDC code + PKCE flow
Phase D-1 step 2c. Replaces the HTTP Basic admin auth scheme with
the standard Blazor OIDC workflow: cookie session, OpenIdConnect
challenge, interactive login page served by the same Duende
IdentityServer instance that authenticates worker machines.
Coordinator packages:
- Adds Microsoft.AspNetCore.Authentication.OpenIdConnect 10.0.4
(version pinned up from 10.0.0 to satisfy Duende 7.4.7's
transitive floor and avoid NU1605 downgrade).
IdentityServerResources:
- Adds IdentityResources (OpenId, Profile) for the interactive UI
client's ID token claims.
- Adds BuildAdminUiClient builder that emits a Duende Client with
authorization_code + PKCE, openid+profile scopes, and redirect
URIs pointing at {baseUrl}/signin-oidc and /signout-callback-oidc.
- Exposes AdminUiClientId constant so Program.cs can reference it.
CoordinatorOptions:
- New BaseUrl setting (default https://localhost:5001). Doubles as
the OpenID Connect authority URL so the coordinator's OIDC client
discovers its own IS's /.well-known/openid-configuration. In
production this should match the public ngrok reserved domain.
Program.cs (significant rewrite):
- Seeds Duende TestUserStore with a single admin user built from
CoordinatorOptions.Admin.{Username,Password}. AddTestUsers wires
the default resource-owner password validator so Duende's login
endpoint can authenticate the operator.
- Configures IdentityServer UserInteraction.LoginUrl = /Account/Login
so /connect/authorize redirects unauthenticated users into the
Blazor login page instead of the built-in Duende quickstart UI.
- Stacks four authentication schemes:
Cookies — admin session cookie (default scheme)
oidc — OpenIdConnect challenge (default challenge scheme)
Bearer — JWT validation for worker endpoints
idsrv — Duende's own default cookie (for the IS login flow)
- AdminPolicy now requires the Cookies scheme + admin role claim.
WorkerPolicy unchanged (Bearer + bitnet-worker scope).
- Adds /Account/Login/submit minimal API endpoint that validates
posted credentials against TestUserStore, signs in on
IdentityServerConstants.DefaultCookieAuthenticationScheme
("idsrv"), and redirects to the caller's returnUrl (the IS
/connect/authorize continuation URL). DisableAntiforgery() for
now; CSRF hardening lands when the login page gets a Blazor
@editform.
Components/Pages/LoginPage.razor (new):
- Static-SSR Blazor page at /Account/Login with a plain HTML form
POSTing to /Account/Login/submit.
- SupplyParameterFromQuery populates returnUrl (from Duende's
/connect/authorize redirect) and error (from the submit
endpoint's bounce-back on bad credentials).
- Uses MainLayout so the page picks up the shared dark-theme
header / styles.
Components/Pages/ApiKeysPage.razor:
- Drops the AuthenticationSchemes = "AdminBasic" override on
@Attribute [Authorize]; the page now defers to AdminPolicy which
in turn uses the default cookie scheme that OIDC populates.
AdminBasicAuthenticationHandler.cs removed. Programmatic admin
access still possible via the JSON endpoints after obtaining an
admin cookie through the OIDC flow, or by adding a client-credentials
grant for scripted callers in a follow-up step.
Fast-lane regression: 223/223 tests pass in 1m24s on net10 slice.
No existing tests exercise the new OIDC handshake end-to-end —
that integration suite lands after /work and /heartbeat are
implemented so one run covers the full worker lifecycle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>1 parent 3e2b7a6 commit 9371dc6
7 files changed
Lines changed: 263 additions & 196 deletions
File tree
- src/BitNetSharp.Distributed.Coordinator
- Auth
- Components/Pages
- Configuration
- Identity
Lines changed: 0 additions & 140 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
| 2 | + | |
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| |||
Lines changed: 59 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
Lines changed: 10 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
70 | 80 | | |
71 | 81 | | |
72 | 82 | | |
| |||
Lines changed: 48 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| |||
46 | 47 | | |
47 | 48 | | |
48 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
49 | 97 | | |
0 commit comments