fix: serve RFC 9728 path-suffixed metadata, document connector redirect URIs
Two separate discovery footguns, both found while debugging an Authentik "Redirect URI Error" on a claude.ai custom connector. RFC 9728 §3.1 puts the metadata for a resource identified by `https://host/api/mcp` at `/.well-known/oauth-protected-resource/api/mcp`. Only the root form was served, so clients that derive the metadata URL from the MCP endpoint URL — rather than reading `resource_metadata` off our 401 — got Next.js's HTML 404 and failed discovery with a JSON parse error. Add a `[...path]` route serving the same document with `resource` naming the suffixed identifier (§3.3 has the client compare it as an exact string, so echoing the bare origin would be rejected). The document body moves to `lib/auth/resource-metadata.ts` so the two routes cannot drift apart on `scopes_supported` — a divergence there costs you the `aud` claim or the refresh token. Paths are allowlisted rather than wildcarded so this cannot advertise resources the app does not serve. `buildWwwAuthenticate()` still points at the root URL; this change is purely additive. Separately, the redirect URIs an MCP provider needs depend on how clients reach it: a loopback URI for the CLI, `https://claude.ai/api/mcp/auth_callback` for a claude.ai custom connector. Registering only the former is what produces the "Redirect URI Error" page, and a portless `http://localhost/callback` entry matches nothing the CLI sends. Document both, keyed on the literal error text, and note that DCR is enterprise-gated on Authentik so these are hand-registered on a FOSS instance. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -231,13 +231,17 @@ https://memory.example.com/auth/cli-callback
|
||||
The first covers the loopback listener from README → *B. OAuth flow*; the
|
||||
second is the manual-paste fallback from *C*. "Mobile and desktop
|
||||
applications" permits arbitrary `https://` URIs alongside the loopback one, so
|
||||
both live on the same platform.
|
||||
both live on the same platform. If the server will also be added as a claude.ai
|
||||
custom connector, that flow is brokered by claude.ai and comes back to
|
||||
`https://claude.ai/api/mcp/auth_callback` — register it here too, or the
|
||||
connector stops at the IdP's redirect-URI mismatch error before any login
|
||||
prompt. See README → *Which redirect URIs to register*.
|
||||
|
||||
**Note the missing port.** Entra ignores the port component when matching
|
||||
`http://localhost` redirect URIs, so the single registration
|
||||
`http://localhost/callback` matches `http://localhost:33418/callback`,
|
||||
`http://localhost:9999/callback`, and any other port. This is Entra's
|
||||
equivalent of the Authentik regex (`^http://(127\.0\.0\.1|localhost):\d+/.*$`)
|
||||
equivalent of the Authentik regex (`http://(localhost|127\.0\.0\.1):[0-9]+/.*`)
|
||||
the README mentions — users can pick any `--callback-port` without
|
||||
re-registering.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user