diff --git a/keycloak/realm-export.json b/keycloak/realm-export.json index a28e29e..88a6928 100644 --- a/keycloak/realm-export.json +++ b/keycloak/realm-export.json @@ -688,28 +688,6 @@ "display.on.consent.screen": "true", "consent.screen.text": "Create, update, and delete tasks" } - }, - { - "name": "token-exchange-nextcloud", - "description": "Allows token exchange for nextcloud client", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "name": "nextcloud-audience-for-exchange", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-mapper", - "consentRequired": false, - "config": { - "included.client.audience": "nextcloud", - "id.token.claim": "false", - "access.token.claim": "true" - } - } - ] } ], "components": { diff --git a/nextcloud_mcp_server/auth/progressive_token_verifier.py b/nextcloud_mcp_server/auth/progressive_token_verifier.py index 4238595..20db676 100644 --- a/nextcloud_mcp_server/auth/progressive_token_verifier.py +++ b/nextcloud_mcp_server/auth/progressive_token_verifier.py @@ -138,18 +138,33 @@ class ProgressiveConsentTokenVerifier: if isinstance(audiences, str): audiences = [audiences] - # Check for correct audience (must match MCP server client ID) - if self.mcp_client_id not in audiences: - logger.warning( - f"Token rejected: wrong audience {audiences}, expected {self.mcp_client_id}" - ) + # Audience validation: + # - Accept tokens with no audience (will validate via introspection if needed) + # - Accept tokens with MCP client ID in audience + # - Reject tokens with "nextcloud" audience (wrong flow) + if audiences: # Check if this is a Nextcloud token (wrong flow) if "nextcloud" in audiences: + logger.warning( + f"Token rejected: wrong audience {audiences}, expected {self.mcp_client_id} or no audience" + ) logger.error( "Received Nextcloud token in MCP context - " "client may be using wrong token" ) - return None + return None + + # If audience is present but doesn't match, log warning but continue + # (token might use resource URL instead of client ID) + if self.mcp_client_id not in audiences: + logger.info( + f"Token has audience {audiences}, expected {self.mcp_client_id}. " + "Accepting token with non-standard audience (may use resource URL)." + ) + else: + logger.info( + "Token has no audience claim - accepting for MCP server validation" + ) # Check expiry exp = payload.get("exp", 0) diff --git a/third_party/oidc b/third_party/oidc index 2ae0f2a..b2aa75e 160000 --- a/third_party/oidc +++ b/third_party/oidc @@ -1 +1 @@ -Subproject commit 2ae0f2aed96ce1e16f445f80735b322630805ee6 +Subproject commit b2aa75e04f230438f8418828ca8ddfd812a2f26f