Commit Graph

3 Commits

Author SHA1 Message Date
Chris Coutinho 10dffd0c10 fix: restructure routes to prevent SessionAuthBackend from interfering with FastMCP OAuth
SessionAuthBackend middleware was wrapping the entire app including FastMCP,
which prevented FastMCP's OAuth token verification from running properly.
When SessionAuthBackend returned None for /mcp paths, Starlette marked requests
as "anonymous" and allowed them through, bypassing FastMCP's authentication.

Changes:

1. Route restructuring (app.py):
   - Create separate Starlette app for browser routes (/user, /user/page)
   - Apply SessionAuthBackend only to browser app
   - Mount browser app at /user/* before FastMCP
   - Mount FastMCP at / (catch-all with its own OAuth)
   - Remove global SessionAuthBackend middleware

2. SessionAuthBackend cleanup (session_backend.py):
   - Remove path exclusion logic (no longer needed)
   - Simplify to only handle browser routes
   - Update docstring to reflect mount-based isolation

Benefits:
- FastMCP's OAuth token verification now runs properly
- No middleware interference between authentication mechanisms
- Clear separation: SessionAuth for browser UI, OAuth Bearer for MCP clients
- Tests confirm OAuth authentication works correctly

Testing:
- All OAuth tests pass (test_mcp_oauth_*, test_jwt_*)
- Browser routes still require session auth
- FastMCP routes use OAuth Bearer tokens exclusively

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 03:34:53 +01:00
Chris Coutinho 737d62fe91 fix: allow OAuth Bearer tokens on /mcp endpoint by excluding from session auth
SessionAuthBackend was blocking MCP clients using OAuth Bearer tokens because
it returned None when no session cookie was present, causing 401 responses
before FastMCP's OAuth provider could validate Bearer tokens.

Changes:
- Add path-based exclusion to SessionAuthBackend.authenticate()
- Skip session auth for paths using other authentication methods:
  - /mcp (FastMCP OAuth Bearer tokens)
  - /.well-known/oauth-protected-resource (public PRM endpoint)
  - /health/live, /health/ready (public health checks)
  - /oauth/login, /oauth/login-callback, /oauth/authorize (OAuth flow pages)
- Browser routes (/user, /user/page, /oauth/logout) still require session cookies

This allows MCP clients to connect with OAuth Bearer tokens while maintaining
session-based authentication for browser UI routes.

Testing:
- OAuth tests pass (test_mcp_oauth_server_connection, etc.)
- Browser routes still require session auth (/user returns 303 redirect)
- Public endpoints remain accessible (/health/live works)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 03:26:13 +01:00
Chris Coutinho c2dcb06fe1 feat: add browser-based user info page with separate OAuth flow
Implements /user and /user/page endpoints for displaying authenticated
user information in both BasicAuth and OAuth modes.

Key Features:
- Separate browser OAuth flow (/oauth/login, /oauth/login-callback, /oauth/logout)
- Session-based authentication using signed cookies
- Token refresh for persistent sessions
- HTML and JSON user info endpoints
- IdP profile information retrieval

Architecture:
- BasicAuth mode: Always authenticated as configured user
- OAuth mode: Browser-based authorization code flow with refresh tokens
- Session stored in SQLite with encrypted refresh tokens
- Server-side token refresh using internal Docker hostnames

OAuth Flow:
- /oauth/login: Initiates browser OAuth flow
- /oauth/login-callback: Handles IdP callback and stores refresh token
- /oauth/logout: Clears session cookie
- /user: JSON API endpoint (requires authentication)
- /user/page: HTML page endpoint (requires authentication)

DCR Scopes Fix:
- MCP server DCR now only requests basic OIDC scopes (openid profile email offline_access)
- Nextcloud app scopes (notes:read, etc.) are for MCP clients, not the server itself
- PRM endpoint dynamically advertises supported scopes from tool decorators

Files:
- nextcloud_mcp_server/auth/browser_oauth_routes.py: Browser OAuth flow handlers
- nextcloud_mcp_server/auth/session_backend.py: Starlette session authentication
- nextcloud_mcp_server/auth/userinfo_routes.py: User info endpoints with token refresh
- tests/server/auth/test_userinfo_routes.py: Unit tests
- tests/server/oauth/test_userinfo_integration.py: OAuth integration tests

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 22:16:49 +01:00