feat(ext-security): add an OAuth 2.1 authorization server
flash-ext-security-oauth-server issues RFC 9068 access tokens (code + PKCE S256, CIMD and DCR clients, RFC 8707 resources, rotating refresh tokens) for resources on the application's own origin. Around it: SecurityExtension resolves a configured origin instead of X-Forwarded-* headers, mechanisms expose schemes() and a route can be restricted to some of them, McpConfig.mechanisms(...) uses that, OIDC bearers must be typed at+jwt, and PublicUrl guards outbound fetches against internal addresses. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7f225e0faf
commit
f28fc43150
@@ -14,9 +14,9 @@ authenticate `/mcp` exactly as they authenticate every other route.
|
||||
When a registered mechanism publishes an OAuth2 issuer — `flash-ext-security-oidc` does — the endpoint
|
||||
behaves as the MCP authorization spec requires, with nothing to configure:
|
||||
|
||||
- `GET /.well-known/oauth-protected-resource/mcp` serves RFC 9728 metadata: the `resource` (derived per
|
||||
request from `X-Forwarded-Proto`/`-Host` or `Host`), every issuer as `authorization_servers`, and
|
||||
`scopes_supported` when `McpConfig.scopesSupported(...)` is set;
|
||||
- `GET /.well-known/oauth-protected-resource/mcp` serves RFC 9728 metadata: the `resource` (the
|
||||
application's `SecurityExtension.origin(...)` plus the path), every issuer as `authorization_servers`,
|
||||
and `scopes_supported` when `McpConfig.scopesSupported(...)` is set;
|
||||
- an anonymous call gets `401` with `WWW-Authenticate: Bearer resource_metadata="…"`;
|
||||
- a token whose `aud` does not include the resource is `403` (RFC 8707) and logged at `WARN`. Credentials
|
||||
that are not audience-bound, such as API keys, are unaffected.
|
||||
@@ -31,6 +31,17 @@ mint a resource audience at all — Keycloak ignores RFC 8707's `resource` param
|
||||
cannot add the mapper has no other way in. Every token a registered issuer signs is then accepted on the
|
||||
endpoint, and the boot logs say so.
|
||||
|
||||
## Which credentials
|
||||
|
||||
By default every mechanism in the chain authenticates `/mcp`, and the session cookie too.
|
||||
`McpConfig.mechanisms(...)` narrows that to the ones named: nothing else is a credential on the endpoint,
|
||||
and only their issuers are published — so a client is sent to exactly the authorization server the
|
||||
endpoint trusts.
|
||||
|
||||
```java
|
||||
McpConfig.builder("app").toolsPackage("com.example.tools").mechanisms(authorizationServer).build();
|
||||
```
|
||||
|
||||
## Tool policies
|
||||
|
||||
The core annotations work on tools as on handlers, checked per `tools/call` against the caller the route
|
||||
|
||||
Reference in New Issue
Block a user