fix: Correct OAuth token audience validation for multi-audience mode

Fix two issues preventing OAuth tests from passing:

1. Set oidc_client_id and oidc_client_secret on Settings object
   - These were being read from environment but not propagated to the
     UnifiedTokenVerifier settings instance

2. Use client_issuer instead of issuer for JWT validation
   - client_issuer accounts for NEXTCLOUD_PUBLIC_ISSUER_URL override
   - Fixes "Invalid issuer" errors when public URL differs from internal

3. Accept resource URL with /mcp path in audience validation
   - During DCR, resource_url is registered as "{mcp_server_url}/mcp"
   - Tokens correctly include this full path as audience
   - Verifier now accepts both "http://localhost:8001" and
     "http://localhost:8001/mcp" as valid MCP audiences

These changes restore OAuth functionality while maintaining ADR-005
security requirements for proper audience validation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2025-11-05 19:03:35 +01:00
parent 9fab6cb550
commit 5deb3132c3
2 changed files with 15 additions and 4 deletions
+6 -1
View File
@@ -573,6 +573,10 @@ async def setup_oauth_config():
settings = get_settings()
# Override with discovered values if not set in environment
if not settings.oidc_client_id:
settings.oidc_client_id = client_id
if not settings.oidc_client_secret:
settings.oidc_client_secret = client_secret
if not settings.jwks_uri:
settings.jwks_uri = jwks_uri
if not settings.introspection_uri:
@@ -580,7 +584,8 @@ async def setup_oauth_config():
if not settings.userinfo_uri:
settings.userinfo_uri = userinfo_uri
if not settings.oidc_issuer:
settings.oidc_issuer = issuer
# Use client_issuer which handles public URL override
settings.oidc_issuer = client_issuer
if not settings.nextcloud_mcp_server_url:
settings.nextcloud_mcp_server_url = mcp_server_url
if not settings.nextcloud_resource_uri:
@@ -218,10 +218,13 @@ class UnifiedTokenVerifier(TokenVerifier):
audiences_set = set(audiences)
# MCP must have at least one: client_id OR server_url
# MCP must have at least one: client_id OR server_url OR server_url/mcp
mcp_valid = self.settings.oidc_client_id in audiences_set or (
self.settings.nextcloud_mcp_server_url
and self.settings.nextcloud_mcp_server_url in audiences_set
and (
self.settings.nextcloud_mcp_server_url in audiences_set
or f"{self.settings.nextcloud_mcp_server_url}/mcp" in audiences_set
)
)
# Nextcloud must have its resource URI
@@ -251,7 +254,10 @@ class UnifiedTokenVerifier(TokenVerifier):
self.settings.oidc_client_id in audiences_set
or (
self.settings.nextcloud_mcp_server_url
and self.settings.nextcloud_mcp_server_url in audiences_set
and (
self.settings.nextcloud_mcp_server_url in audiences_set
or f"{self.settings.nextcloud_mcp_server_url}/mcp" in audiences_set
)
)
)