Skip to content

Repository files navigation

Cookie Auth for Nextcloud

License: AGPL v3 Nextcloud PHP

A Nextcloud app that enables automatic Single-Sign-On (SSO) when Nextcloud is embedded in an iframe. It reads a JWT token from a configurable cookie, validates it against a public key (e.g., from Keycloak), and automatically logs in the matching Nextcloud user.

Features

  • JWT Authentication: Validates JWT tokens from cookies using RS256/RS384/RS512 algorithms
  • Keycloak Integration: Auto-fetches public keys from Keycloak realms
  • Flexible User Matching: Match users by username claim or email fallback
  • Session Caching: Prevents redundant token validation
  • External Password API: Optional integration for SMB/external storage authentication
  • Debug Endpoints: Built-in diagnostics for troubleshooting

Use Case

This app is designed for scenarios where:

  • Nextcloud is embedded in an iframe within a portal application
  • The portal uses Keycloak or another OIDC provider for authentication
  • The JWT token is already present as a cookie from the parent application
  • You want seamless SSO without redirecting users through another login flow

Requirements

Requirement Version
Nextcloud 25 or higher
PHP 8.1 or higher

Additional requirements:

  • A JWT token in a cookie (e.g., from Keycloak)
  • Users must already exist in Nextcloud (matching by username or email)
  • HTTPS for both portal and Nextcloud

Installation

From Git

cd /var/www/nextcloud/apps
git clone https://github.com/netzint/nextcloud-app-cookieauth

Enable the App

sudo -u www-data php occ app:enable nextcloud-app-cookieauth

Configuration

Add the following to your config/config.php:

Required: Session Cookie Configuration

For iframe SSO to work, you must configure Nextcloud's session cookie:

// Required for iframe SSO - allows session cookie to be sent cross-origin
'session_cookie_samesite' => 'None',

Option 1: Auto-fetch Public Key from Keycloak (Recommended)

'nextcloud-app-cookieauth' => [
    // Keycloak Realm URL - public key is fetched automatically
    'realm_url' => 'https://your-edulution-domain.com/auth/realms/edulution',

    // Name of the cookie containing the JWT token
    'cookie_name' => 'authToken',

    // JWT claim to use for matching users
    'user_claim' => 'preferred_username',

    // Optional: If user not found by username, try matching by email
    'fallback_to_email' => true,

    // Optional: API to fetch user's password for SMB/external storage
    'password_api_url' => 'https://api.example.com',
],

The public key is cached for 1 hour to minimize HTTP requests.

Option 2: Manual Public Key Configuration

'nextcloud-app-cookieauth' => [
    // Name of the cookie containing the JWT token
    'cookie_name' => 'authToken',

    // Path to the public key file (PEM format)
    // OR the key itself as a string starting with "-----BEGIN"
    'public_key' => '/etc/nextcloud/keycloak-public-key.pem',

    // JWT signing algorithm (RS256, RS384, RS512)
    'algorithm' => 'RS256',

    // JWT claim to use for matching users
    'user_claim' => 'preferred_username',

    // Optional: Expected issuer (for additional validation)
    'issuer' => 'https://your-edulution-domain.com/auth/realms/edulution',

    // Optional: If user not found by username, try matching by email
    'fallback_to_email' => true,
],

Configuration Reference

Option Required Default Description
realm_url Yes* - Keycloak realm URL (auto-fetches public key)
public_key Yes* - Path to PEM file or PEM string
cookie_name Yes - Name of the cookie containing the JWT
user_claim Yes - JWT claim for username (e.g., preferred_username)
algorithm No RS256 JWT algorithm (RS256, RS384, RS512)
issuer No realm_url Expected JWT issuer for validation
fallback_to_email No false Try email lookup if username not found
password_api_url No - API URL to fetch user passwords for external storage

*Either realm_url OR public_key must be provided.

How It Works

Portal (with Keycloak)              Nextcloud (iframe)
       │                                   │
       │  1. User logs in to portal        │
       │  2. Keycloak issues JWT token     │
       │     and sets cookie               │
       │                                   │
       │  3. Portal loads Nextcloud        │
       │     in iframe                     │
       │ ─────────────────────────────────>│
       │     (cookie is sent)              │
       │                                   │  4. App reads JWT from cookie
       │                                   │  5. Validates JWT signature
       │                                   │  6. Extracts username from claims
       │                                   │  7. Logs in Nextcloud user
       │                                   │
       │<───────────────────────────────── │  8. Returns authenticated page

Cookie Requirements

For the cookie to be sent with iframe requests:

  1. SameSite: Must be SameSite=None; Secure for cross-origin iframes
  2. Domain: Cookie domain must include the Nextcloud domain
  3. HTTPS: Both portal and Nextcloud must use HTTPS

Example cookie header:

Set-Cookie: authToken=eyJhbGci...; Path=/; Domain=.example.com; Secure; HttpOnly; SameSite=None

User Provisioning

Users must exist in Nextcloud before auto-login can work. The app matches users by:

  1. Primary: The claim specified in user_claim (e.g., preferred_username)
  2. Fallback (if enabled): The email claim

Provision users via:

  • LDAP synchronization
  • Nextcloud User Provisioning API
  • Manual creation
  • External user backends

Debug Endpoints

Status Check

GET /apps/nextcloud-app-cookieauth/status

Returns basic authentication status:

{
  "authenticated": true,
  "user": {
    "uid": "john.doe",
    "displayName": "John Doe",
    "email": "john.doe@example.com"
  }
}

Detailed Debug Info

GET /apps/nextcloud-app-cookieauth/debug

Returns detailed session diagnostics including recommendations.

Token Check

GET /apps/nextcloud-app-cookieauth/tokenCheck

Checks if a valid session token exists in the database.

Troubleshooting

Problem Solution
"User not found" Verify user exists in Nextcloud; check user_claim config
"Signature verification failed" Check public key; verify algorithm matches
"Token expired" User needs a fresh token from the portal
"Issuer mismatch" Check issuer config matches JWT issuer claim
Cookie not sent Verify SameSite=None; Secure; check cookie domain
"Failed to fetch realm info" Verify realm_url is accessible from server
Login works but CSRF errors Add 'session_cookie_samesite' => 'None' to config.php
Login appears to work but fails Session cookie not persisting; check session_cookie_samesite
User shown but operations fail Use /debug endpoint to diagnose session state

Checking Logs

tail -f /var/www/nextcloud/data/nextcloud.log | grep cookieauth

Security Considerations

  • HTTPS Required: Always use HTTPS for both the portal and Nextcloud
  • Issuer Validation: Configure the issuer option to validate token source
  • Token Expiration: The app enforces exp and nbf claims
  • Key Caching: Public keys are cached securely in Nextcloud's database
  • Session Security: Session data is cleared on token validation failure
  • Algorithm Validation: Only configured algorithms are accepted (prevents algorithm confusion attacks)

Development

Running Tests

composer install
composer test

Test Coverage

composer test:coverage

License

This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later).

See LICENSE for the full license text.

Credits

Developed by Netzint GmbH

Support

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages