3.5 KiB
Fix Bearer Token Authentication Causing Session Logout
Problem
Bearer token authentication with OIDC fails for app-specific APIs (like Notes, Calendar, etc.) with 401 Unauthorized errors, even though the same Bearer token works fine for OCS APIs (like /ocs/v2.php/cloud/capabilities).
Root Cause
When using Bearer token authentication:
- ✅ Bearer token validation successfully authenticates the user
- ✅ A session is created for the authenticated user
- ❌ Nextcloud's
CORSMiddlewaredetects the logged-in session but no CSRF token - ❌
CORSMiddlewarecalls$this->session->logout()to prevent CSRF attacks - ❌ The logout invalidates the session, breaking the API request with 401 Unauthorized
This occurs because app-specific APIs (Notes, Calendar, etc.) use the @CORS annotation, which triggers the CORSMiddleware security checks. The OCS APIs don't have this annotation, which is why they work correctly.
Error Logs
[TokenInvalidatedListener] Could not find the OIDC session related with an invalidated token
Session token invalidated before logout
Logging out
Solution
Set the app_api session flag during Bearer token authentication. This instructs CORSMiddleware to skip the CSRF check and logout logic, as the authentication is API-based rather than session-based.
This is the same mechanism used by Nextcloud's AppAPI framework for external application authentication.
Changes
The fix adds $this->session->set('app_api', true); before all successful Bearer token authentication return statements in lib/User/Backend.php:
- Line 243: After OIDC Identity Provider validation
- Line 310: After auto-provisioning with bearer provisioning
- Line 315: After existing user authentication
- Line 337: After LDAP user sync
Testing
Tested with the nextcloud-mcp-server project's integration tests:
Before Fix
✅ Capabilities endpoint (OCS API) - 200 OK
❌ Notes API listing - 401 Unauthorized
❌ Notes API create - 401 Unauthorized
After Fix
✅ Capabilities endpoint (OCS API) - 200 OK
✅ Notes API listing - 200 OK
✅ Notes API create - 200 OK
✅ Notes API delete - 200 OK
All OAuth Bearer token operations now work correctly across all Nextcloud APIs without session invalidation.
Configuration
This fix works with the standard Bearer token validation configuration:
// config.php
'user_oidc' => [
'oidc_provider_bearer_validation' => true,
],
And in the OIDC Identity Provider app:
php occ config:app:set oidc dynamic_client_registration --value='true'
Impact
This fix enables proper Bearer token authentication for:
- All Nextcloud app APIs (Notes, Calendar, Contacts, etc.)
- External applications using OAuth 2.0 / OpenID Connect
- MCP servers and other API integrations
- Any application using the
Authorization: Bearerheader
Related Files
lib/User/Backend.php- Modified to setapp_apiflag/server/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php- Contains the CSRF/logout logic that this bypasses