Compare commits

...

2 Commits

Author SHA1 Message Date
kawa e3926804a9 Clarify the two OAuth redirect URIs in README
The Configuration table listed ClientConnect__RedirectUri (/connect/callback)
alongside the Oidc__* settings, implying it was an OIDC sign-in redirect URI on
the toolbox's own Entra app. It isn't: /connect/callback is the per-profile
SharePoint connect flow (PKCE public client using each profile's own ClientId),
registered on the client-tenant apps — not the sign-in app.

Split the two flows out explicitly: /signin-oidc on the sign-in (Web) app,
/connect/callback on each profile's (public client) app. Also document that the
confidential sign-in app needs an HTTPS redirect URI (http only for localhost),
so a plain-HTTP LAN deployment needs an HTTPS-terminating proxy or must fall
back to local login.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 17:51:55 +02:00
kawa 80f660053d Strip quotes/whitespace from Oidc config values
docker-compose's `environment` list form embeds literal quotes in the value
(`- Oidc__TenantId="<guid>"` → the value is "<guid>" with quotes), producing a
malformed Authority URL (…/"<tenant>"/v2.0). Metadata discovery then fails with
IDX20803 and the Microsoft sign-in challenge 500s. The same trap on ClientSecret
would silently break the token exchange.

Trim surrounding quotes and whitespace from TenantId, ClientId and ClientSecret
so a quoted env var no longer breaks OIDC.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 17:32:58 +02:00
2 changed files with 20 additions and 5 deletions
+8 -3
View File
@@ -110,9 +110,14 @@ else
.AddOpenIdConnect(options =>
{
var oidc = builder.Configuration.GetSection("Oidc");
options.Authority = $"https://login.microsoftonline.com/{oidc["TenantId"]}/v2.0";
options.ClientId = oidc["ClientId"];
options.ClientSecret = oidc["ClientSecret"];
// Strip accidental surrounding quotes/whitespace. docker-compose's `environment` list form
// (`- Oidc__TenantId="<guid>"`) embeds the literal quotes in the value, producing a malformed
// Authority (…/"<tenant>"/v2.0) that fails metadata discovery with IDX20803. Same trap on the
// secret would silently break the token exchange. Trim defensively.
static string Clean(string? v) => v?.Trim().Trim('"', '\'') ?? string.Empty;
options.Authority = $"https://login.microsoftonline.com/{Clean(oidc["TenantId"])}/v2.0";
options.ClientId = Clean(oidc["ClientId"]);
options.ClientSecret = Clean(oidc["ClientSecret"]);
options.ResponseType = OpenIdConnectResponseType.Code;
// Do NOT persist the OIDC access/id/refresh tokens in the auth cookie. They are
// never read (SharePoint/Graph auth runs through the separate connect flow +
+12 -2
View File
@@ -28,13 +28,23 @@ Set these as environment variables (or in `appsettings.json` under the `Oidc` se
| `Oidc__TenantId` | Entra tenant GUID |
| `Oidc__ClientId` | App registration client ID |
| `Oidc__ClientSecret` | App registration client secret |
| `ClientConnect__RedirectUri` | Public callback URL, e.g. `https://your-host/connect/callback` |
| `ClientConnect__RedirectUri` | Callback for the per-profile SharePoint connect flow, e.g. `https://your-host/connect/callback` (see below — **not** an OIDC setting) |
| `DataFolder` | Persistent data path (default `/data`) |
| `ASPNETCORE_ENVIRONMENT` | Must be `Production` to enable OIDC |
> In `Development`, OIDC is disabled — the app uses a cookie-only auto-login (hardcoded Admin) for local work.
**Entra app registration** must include redirect URI `https://your-host/signin-oidc` and the Graph permissions required by the audit/reporting features (`GroupMember.Read.All`, `Group.Read.All`, `User.Read.All`).
### Two distinct OAuth flows — two redirect URIs
These are separate and registered on **different** Entra apps. Don't conflate them.
1. **App sign-in (OIDC).** Logging into the toolbox itself via "Sign in with Microsoft". Uses the `Oidc__*` app above. Callback path is the framework default `/signin-oidc` (not configurable here).
→ On **this** app registration, add redirect URI `https://your-host/signin-oidc` under the **Web** platform. This app also needs the Graph permissions the audit/reporting features require: `GroupMember.Read.All`, `Group.Read.All`, `User.Read.All`.
2. **SharePoint connect (per-profile).** Getting a delegated SharePoint/Graph token for a client tenant. A PKCE public-client flow that uses **each connection profile's own `ClientId`/`TenantId`** — not the `Oidc__*` app. `ClientConnect__RedirectUri` is the callback for this flow.
→ On **each client-tenant profile's** app registration, add the `ClientConnect__RedirectUri` value (e.g. `https://your-host/connect/callback`) under the **Mobile and desktop / public client** platform.
> **HTTPS note.** The sign-in app is a confidential (Web) client, so Entra requires its `/signin-oidc` redirect URI to be **HTTPS** — plain HTTP is allowed only for `http://localhost`, not a LAN host/IP. To run OIDC on a plain-HTTP LAN deployment, put the app behind an HTTPS-terminating reverse proxy: register `https://your-host/signin-oidc`, and the app honours `X-Forwarded-Proto` (see `UseForwardedHeaders`) to build the correct `https` redirect. Without a proxy, OIDC sign-in won't work over a non-localhost HTTP host — use the local email/password login instead.
Persistent state (profiles, settings, templates, logs, exports, certs) lives in `DataFolder`.