fix: move audience mapper from scope to nextcloud-mcp-server client
The token-exchange-nextcloud scope was being inherited by DCR clients and requested by external MCP clients (like Gemini CLI), causing all tokens to have aud: "nextcloud" even when targeting the MCP server. ## Problem When external clients registered via DCR, they inherited all optional scopes from the realm defaults, including token-exchange-nextcloud. When these clients requested tokens, they would include this scope, which added aud: "nextcloud" via the scope's protocol mapper. This caused authentication failures for MCP server access: ``` 'aud': 'nextcloud' WARNING - Token rejected: wrong audience ['nextcloud'], expected nextcloud-mcp-server ``` ## Root Cause Client scopes with protocol mappers are applied whenever that scope is requested, regardless of which client requests it. The token-exchange-nextcloud scope was designed for the MCP server's own token requests to Nextcloud APIs, but external clients were also requesting it. ## Solution Move the audience mapper from the token-exchange-nextcloud scope to a direct protocol mapper on the nextcloud-mcp-server client itself. ### Changes 1. **Remove token-exchange-nextcloud from nextcloud-mcp-server optional scopes** - External DCR clients won't inherit this scope - Prevents external clients from requesting it 2. **Add nextcloud-audience protocol mapper directly to nextcloud-mcp-server** - Hardcode aud: "nextcloud" for this client only - Only tokens issued TO nextcloud-mcp-server will have this audience - External MCP clients won't be affected ## Behavior After Fix **Gemini CLI (DCR client) → MCP Server**: - Client doesn't have token-exchange-nextcloud scope - Token audience: Based on RFC 8707 resource parameter (if provided) - Result: No hardcoded audience ✅ **MCP Server (nextcloud-mcp-server) → Nextcloud APIs**: - Client has nextcloud-audience protocol mapper - Token audience: Always "nextcloud" (hardcoded) - Result: aud: "nextcloud" for Nextcloud API access ✅ ## Related - RFC 8707: Resource Indicators for OAuth 2.0 - Keycloak client scopes vs. client protocol mappers - DCR client scope inheritance 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -229,6 +229,18 @@
|
|||||||
"fullScopeAllowed": true,
|
"fullScopeAllowed": true,
|
||||||
"nodeReRegistrationTimeout": -1,
|
"nodeReRegistrationTimeout": -1,
|
||||||
"protocolMappers": [
|
"protocolMappers": [
|
||||||
|
{
|
||||||
|
"name": "nextcloud-audience",
|
||||||
|
"protocol": "openid-connect",
|
||||||
|
"protocolMapper": "oidc-audience-mapper",
|
||||||
|
"consentRequired": false,
|
||||||
|
"config": {
|
||||||
|
"included.client.audience": "nextcloud",
|
||||||
|
"access.token.claim": "true",
|
||||||
|
"id.token.claim": "false",
|
||||||
|
"introspection.token.claim": "true"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "sub",
|
"name": "sub",
|
||||||
"protocol": "openid-connect",
|
"protocol": "openid-connect",
|
||||||
@@ -308,7 +320,6 @@
|
|||||||
"phone",
|
"phone",
|
||||||
"offline_access",
|
"offline_access",
|
||||||
"microprofile-jwt",
|
"microprofile-jwt",
|
||||||
"token-exchange-nextcloud",
|
|
||||||
"notes:read",
|
"notes:read",
|
||||||
"notes:write",
|
"notes:write",
|
||||||
"calendar:read",
|
"calendar:read",
|
||||||
|
|||||||
Reference in New Issue
Block a user