Files
certigo/docs/OAUTH_KONZEPT.md

23 KiB

OAuth 2.0 Integration Konzept für Certigo

1. Übersicht

1.1 Ziel

Integration von OAuth 2.0 als zusätzliche Authentifizierungsmethode neben dem bestehenden Basic Authentication System. Benutzer sollen sich mit externen OAuth-Providern (z.B. Google, Microsoft, GitHub) anmelden können.

1.2 Anforderungen

  • Hybrides System: OAuth und Basic Auth parallel unterstützen
  • User Linking: OAuth-Benutzer mit bestehenden lokalen Accounts verknüpfen können
  • Automatische User-Erstellung: Neue OAuth-Benutzer automatisch anlegen
  • Berechtigungssystem: OAuth-Benutzer in bestehendes Permission-System integrieren
  • Session Management: Sichere Session-Verwaltung für OAuth-Logins
  • Multi-Provider: Unterstützung mehrerer OAuth-Provider gleichzeitig

2. Architektur

2.1 OAuth Flow (Authorization Code Flow)

┌─────────┐         ┌──────────┐         ┌─────────────┐         ┌──────────┐
│ Browser │         │ Frontend │         │   Backend   │         │  OAuth   │
│         │         │          │         │             │         │ Provider │
└────┬────┘         └────┬─────┘         └──────┬──────┘         └────┬─────┘
     │                   │                      │                      │
     │ 1. Login Button   │                      │                      │
     │──────────────────>│                      │                      │
     │                   │                      │                      │
     │                   │ 2. GET /api/oauth/{provider}/auth           │
     │                   │─────────────────────>│                      │
     │                   │                      │                      │
     │                   │                      │ 3. Redirect to OAuth  │
     │                   │                      │    Authorization URL │
     │                   │<─────────────────────│                      │
     │                   │                      │                      │
     │ 4. Redirect to    │                      │                      │
     │    OAuth Provider │                      │                      │
     │<──────────────────│                      │                      │
     │                   │                      │                      │
     │ 5. User Auth      │                      │                      │
     │────────────────────────────────────────────────────────────────>│
     │                   │                      │                      │
     │ 6. Callback with  │                      │                      │
     │    Authorization  │                      │                      │
     │    Code           │                      │                      │
     │<────────────────────────────────────────────────────────────────│
     │                   │                      │                      │
     │ 7. Callback to    │                      │                      │
     │    /api/oauth/    │                      │                      │
     │    {provider}/    │                      │                      │
     │    callback        │                      │                      │
     │──────────────────>│                      │                      │
     │                   │ 8. POST /api/oauth/{provider}/callback       │
     │                   │    (code=xxx)        │                      │
     │                   │─────────────────────>│                      │
     │                   │                      │                      │
     │                   │                      │ 9. Exchange Code for  │
     │                   │                      │    Access Token       │
     │                   │                      │──────────────────────>│
     │                   │                      │                      │
     │                   │                      │ 10. Get User Info    │
     │                   │                      │──────────────────────>│
     │                   │                      │                      │
     │                   │                      │ 11. User Info        │
     │                   │                      │<──────────────────────│
     │                   │                      │                      │
     │                   │                      │ 12. Create/Update    │
     │                   │                      │    User in DB         │
     │                   │                      │                      │
     │                   │                      │ 13. Create Session   │
     │                   │                      │                      │
     │                   │ 14. Return Session   │                      │
     │                   │     Token            │                      │
     │                   │<─────────────────────│                      │
     │                   │                      │                      │
     │ 15. Store Session │                      │                      │
     │     & Redirect    │                      │                      │
     │<──────────────────│                      │                      │
     │                   │                      │                      │

2.2 Komponenten

Backend

  • OAuth Handler: /api/oauth/{provider}/auth - Initiierung des OAuth Flows
  • OAuth Callback Handler: /api/oauth/{provider}/callback - Verarbeitung des Authorization Codes
  • OAuth Provider Manager: Verwaltung mehrerer OAuth-Provider
  • Session Manager: Verwaltung von OAuth-Sessions (JWT oder Session-Tokens)
  • User Linking Service: Verknüpfung von OAuth-Accounts mit lokalen Accounts

Frontend

  • OAuth Login Component: Buttons für verschiedene OAuth-Provider
  • OAuth Callback Handler: Verarbeitung des Redirects nach OAuth-Authentifizierung
  • Session Storage: Speicherung von Session-Tokens (HttpOnly Cookies bevorzugt)

3. Datenbank-Schema

3.1 Erweiterte Users-Tabelle

-- Migration: Erweitere users-Tabelle um OAuth-Felder
ALTER TABLE users ADD COLUMN auth_method TEXT DEFAULT 'basic'; -- 'basic' | 'oauth' | 'hybrid'
ALTER TABLE users ADD COLUMN oauth_provider TEXT; -- 'google' | 'microsoft' | 'github' | NULL
ALTER TABLE users ADD COLUMN oauth_provider_id TEXT; -- Externe User-ID vom OAuth-Provider
ALTER TABLE users ADD COLUMN oauth_email TEXT; -- Email vom OAuth-Provider (kann von lokaler Email abweichen)
ALTER TABLE users ADD COLUMN password_hash TEXT; -- NULL für reine OAuth-User

3.2 Neue Tabelle: oauth_sessions

CREATE TABLE IF NOT EXISTS oauth_sessions (
    id TEXT PRIMARY KEY,
    user_id TEXT NOT NULL,
    provider TEXT NOT NULL,
    access_token TEXT, -- Verschlüsselt gespeichert
    refresh_token TEXT, -- Verschlüsselt gespeichert
    expires_at DATETIME NOT NULL,
    created_at DATETIME NOT NULL,
    last_used_at DATETIME,
    ip_address TEXT,
    user_agent TEXT,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

CREATE INDEX idx_oauth_sessions_user_id ON oauth_sessions(user_id);
CREATE INDEX idx_oauth_sessions_expires_at ON oauth_sessions(expires_at);

3.3 Neue Tabelle: oauth_providers

CREATE TABLE IF NOT EXISTS oauth_providers (
    id TEXT PRIMARY KEY, -- 'google', 'microsoft', 'github'
    name TEXT NOT NULL,
    enabled BOOLEAN DEFAULT 1,
    client_id TEXT NOT NULL,
    client_secret TEXT NOT NULL, -- Verschlüsselt gespeichert
    authorization_url TEXT NOT NULL,
    token_url TEXT NOT NULL,
    user_info_url TEXT NOT NULL,
    scopes TEXT, -- JSON Array: ["openid", "email", "profile"]
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL
);
-- Für Benutzer, die mehrere OAuth-Provider verknüpfen wollen
CREATE TABLE IF NOT EXISTS user_oauth_links (
    id TEXT PRIMARY KEY,
    user_id TEXT NOT NULL,
    provider TEXT NOT NULL,
    provider_user_id TEXT NOT NULL,
    provider_email TEXT,
    linked_at DATETIME NOT NULL,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    UNIQUE(provider, provider_user_id)
);

CREATE INDEX idx_user_oauth_links_user_id ON user_oauth_links(user_id);
CREATE INDEX idx_user_oauth_links_provider ON user_oauth_links(provider, provider_user_id);

4. OAuth Provider Konfiguration

4.1 Unterstützte Provider

Google OAuth 2.0

  • Authorization URL: https://accounts.google.com/o/oauth2/v2/auth
  • Token URL: https://oauth2.googleapis.com/token
  • User Info URL: https://www.googleapis.com/oauth2/v2/userinfo
  • Scopes: ["openid", "email", "profile"]

Microsoft Azure AD

  • Authorization URL: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
  • Token URL: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
  • User Info URL: https://graph.microsoft.com/v1.0/me
  • Scopes: ["openid", "email", "profile"]

GitHub

  • Authorization URL: https://github.com/login/oauth/authorize
  • Token URL: https://github.com/login/oauth/access_token
  • User Info URL: https://api.github.com/user
  • Scopes: ["user:email"]

4.2 Provider-Konfiguration (Environment Variables / Config File)

oauth:
  providers:
    google:
      enabled: true
      client_id: "${GOOGLE_CLIENT_ID}"
      client_secret: "${GOOGLE_CLIENT_SECRET}"
      redirect_uri: "http://localhost:5173/api/oauth/google/callback"
      scopes: ["openid", "email", "profile"]
    microsoft:
      enabled: true
      tenant: "${MICROSOFT_TENANT_ID}"
      client_id: "${MICROSOFT_CLIENT_ID}"
      client_secret: "${MICROSOFT_CLIENT_SECRET}"
      redirect_uri: "http://localhost:5173/api/oauth/microsoft/callback"
      scopes: ["openid", "email", "profile"]
    github:
      enabled: false
      client_id: "${GITHUB_CLIENT_ID}"
      client_secret: "${GITHUB_CLIENT_SECRET}"
      redirect_uri: "http://localhost:5173/api/oauth/github/callback"
      scopes: ["user:email"]

5. API-Endpunkte

5.1 OAuth Initiation

GET /api/oauth/{provider}/auth

Initiert den OAuth Flow für einen bestimmten Provider.

Query Parameters:

  • redirect_uri (optional): Custom Redirect URI nach erfolgreichem Login

Response:

  • 302 Redirect zur OAuth Provider Authorization URL

Beispiel:

GET /api/oauth/google/auth
→ Redirect zu: https://accounts.google.com/o/oauth2/v2/auth?client_id=...&redirect_uri=...&scope=...&response_type=code&state=...

5.2 OAuth Callback

GET /api/oauth/{provider}/callback

Verarbeitet den Authorization Code vom OAuth-Provider.

Query Parameters:

  • code: Authorization Code vom Provider
  • state: CSRF Protection Token (optional, aber empfohlen)

Response:

{
  "success": true,
  "user": {
    "id": "uuid",
    "username": "user@example.com",
    "email": "user@example.com",
    "isAdmin": false,
    "enabled": true,
    "authMethod": "oauth",
    "oauthProvider": "google"
  },
  "sessionToken": "jwt-token-here",
  "redirectTo": "/"
}

Fehler-Response:

{
  "success": false,
  "error": "Invalid authorization code",
  "errorCode": "OAUTH_INVALID_CODE"
}

5.3 OAuth Logout

POST /api/oauth/logout

Beendet die OAuth-Session.

Headers:

  • Authorization: Bearer {sessionToken}

Response:

{
  "success": true,
  "message": "Logged out successfully"
}

5.4 OAuth Provider Status

GET /api/oauth/providers

Gibt eine Liste aller konfigurierten OAuth-Provider zurück.

Response:

{
  "providers": [
    {
      "id": "google",
      "name": "Google",
      "enabled": true,
      "authUrl": "/api/oauth/google/auth"
    },
    {
      "id": "microsoft",
      "name": "Microsoft",
      "enabled": true,
      "authUrl": "/api/oauth/microsoft/auth"
    }
  ]
}

POST /api/oauth/link

Verknüpft einen OAuth-Account mit einem bestehenden lokalen Account (für Hybrid-Auth).

Headers:

  • Authorization: Basic {credentials} (lokaler Account)

Body:

{
  "provider": "google",
  "code": "authorization-code-from-oauth"
}

Response:

{
  "success": true,
  "message": "OAuth account linked successfully"
}

6. Session Management

6.1 Session-Token (JWT)

Token-Struktur:

{
  "sub": "user-uuid",
  "auth_method": "oauth",
  "provider": "google",
  "exp": 1234567890,
  "iat": 1234567890,
  "session_id": "session-uuid"
}

Token-Speicherung:

  • Backend: In oauth_sessions Tabelle
  • Frontend: HttpOnly Cookie (bevorzugt) oder localStorage (Fallback)
  • Lifetime: 24 Stunden (konfigurierbar)
  • Refresh: Automatisches Refresh bei Ablauf (falls Refresh Token vorhanden)

6.2 Session-Validierung

Middleware: oauthSessionMiddleware

Prüft OAuth-Session-Token in folgenden Headers:

  1. Authorization: Bearer {token}
  2. Cookie: oauth_session

Flow:

Request → oauthSessionMiddleware → Check Token → Validate Session → Continue
                                      ↓ Invalid
                                  401 Unauthorized

7. User Management

7.1 Automatische User-Erstellung

Flow:

  1. OAuth-Callback empfängt User-Info vom Provider
  2. Prüfe ob User mit oauth_provider_id existiert
  3. Falls nicht:
    • Erstelle neuen User
    • Setze auth_method = 'oauth'
    • Setze oauth_provider und oauth_provider_id
    • Setze password_hash = NULL
    • Setze enabled = true (oder konfigurierbar)
    • Setze isAdmin = false
    • Weise Standard-Berechtigungsgruppe zu (optional)
  4. Falls ja:
    • Update last_login_at (falls Feld existiert)
    • Update Session

7.2 User Linking (Hybrid Auth)

Szenario: Benutzer hat bereits lokalen Account, möchte OAuth hinzufügen

Flow:

  1. User loggt sich mit Basic Auth ein
  2. User klickt "Link Google Account"
  3. OAuth Flow wird initiiert
  4. Nach erfolgreicher OAuth-Auth:
    • Verknüpfe OAuth-Account mit lokalem Account
    • Setze auth_method = 'hybrid'
    • Erstelle Eintrag in user_oauth_links
  5. User kann sich nun mit beiden Methoden anmelden

7.3 User Mapping

Email-basierte Verknüpfung:

  • Falls OAuth-Email mit lokalem Account übereinstimmt → Auto-Link (optional, konfigurierbar)
  • Falls nicht → Neue User-Erstellung oder manuelle Verknüpfung erforderlich

8. Sicherheit

8.1 CSRF Protection

State Parameter:

  • Generiere zufälligen state Token bei OAuth-Initiation
  • Speichere in Session/Cookie
  • Validiere bei Callback

Implementierung:

state := generateRandomToken(32)
storeStateInSession(state)
redirectURL := fmt.Sprintf("%s?state=%s&...", oauthURL, state)

8.2 Token-Verschlüsselung

Access/Refresh Tokens:

  • Verschlüsselt in Datenbank speichern (AES-256)
  • Nie im Klartext loggen
  • Automatische Löschung bei Ablauf

8.3 Rate Limiting

OAuth-Endpunkte:

  • /api/oauth/{provider}/auth: 10 Requests/Minute pro IP
  • /api/oauth/{provider}/callback: 5 Requests/Minute pro IP

8.4 Secure Cookies

Session Cookies:

  • HttpOnly: true
  • Secure: true (HTTPS only)
  • SameSite: Lax oder Strict
  • Path: /api

9. Frontend-Integration

9.1 Login-Seite Erweiterung

Aktuelle Login-Seite (frontend/src/pages/Login.jsx) erweitern:

// OAuth Login Buttons hinzufügen
<div className="oauth-providers">
  <button onClick={() => initiateOAuth('google')}>
    <img src="/icons/google.svg" /> Mit Google anmelden
  </button>
  <button onClick={() => initiateOAuth('microsoft')}>
    <img src="/icons/microsoft.svg" /> Mit Microsoft anmelden
  </button>
</div>

// Oder: Separater OAuth-Login-Bereich
<div className="divider">oder</div>

9.2 OAuth Callback Handler

Neue Route: frontend/src/pages/OAuthCallback.jsx

useEffect(() => {
  const params = new URLSearchParams(window.location.search)
  const code = params.get('code')
  const state = params.get('state')
  const provider = extractProviderFromURL() // z.B. '/oauth/google/callback'
  
  if (code) {
    handleOAuthCallback(provider, code, state)
  }
}, [])

9.3 AuthContext Erweiterung

Erweitere frontend/src/contexts/AuthContext.jsx:

const loginWithOAuth = async (provider) => {
  // Redirect zu Backend OAuth Initiation
  window.location.href = `/api/oauth/${provider}/auth`
}

const handleOAuthCallback = async (provider, code, state) => {
  const response = await fetch(`/api/oauth/${provider}/callback?code=${code}&state=${state}`)
  const data = await response.json()
  
  if (data.success) {
    // Store session token
    localStorage.setItem('oauth_session', data.sessionToken)
    setUser(data.user)
    setIsAuthenticated(true)
    navigate('/')
  }
}

10. Migration & Backward Compatibility

10.1 Bestehende User

Migration:

  • Alle bestehenden User haben auth_method = 'basic'
  • oauth_provider und oauth_provider_id sind NULL
  • password_hash bleibt bestehen

10.2 API-Kompatibilität

Bestehende Endpunkte:

  • Funktionieren weiterhin mit Basic Auth
  • Neue Middleware prüft zuerst OAuth-Session, dann Basic Auth

Middleware-Order:

Request → oauthSessionMiddleware → basicAuthMiddleware → Handler
              ↓ Invalid                    ↓ Invalid
           Try Basic Auth             401 Unauthorized

10.3 User-Erstellung

Admin-Erstellung:

  • Admins können weiterhin lokale User erstellen
  • OAuth-User können manuell zu Admins gemacht werden

11. Konfiguration & Deployment

11.1 Environment Variables

# OAuth Provider Credentials
GOOGLE_CLIENT_ID=xxx
GOOGLE_CLIENT_SECRET=xxx
MICROSOFT_CLIENT_ID=xxx
MICROSOFT_CLIENT_SECRET=xxx
MICROSOFT_TENANT_ID=xxx
GITHUB_CLIENT_ID=xxx
GITHUB_CLIENT_SECRET=xxx

# OAuth Settings
OAUTH_SESSION_SECRET=xxx # Für Session-Token Signing
OAUTH_SESSION_LIFETIME=24h
OAUTH_REDIRECT_BASE_URL=http://localhost:5173
OAUTH_AUTO_CREATE_USERS=true
OAUTH_AUTO_LINK_BY_EMAIL=false

11.2 Provider-Registrierung

Google:

  1. Google Cloud Console → APIs & Services → Credentials
  2. OAuth 2.0 Client ID erstellen
  3. Authorized redirect URIs: http://localhost:5173/api/oauth/google/callback

Microsoft:

  1. Azure Portal → App Registrations
  2. Neue App registrieren
  3. Redirect URIs: http://localhost:5173/api/oauth/microsoft/callback

GitHub:

  1. GitHub Settings → Developer settings → OAuth Apps
  2. Neue OAuth App erstellen
  3. Authorization callback URL: http://localhost:5173/api/oauth/github/callback

12. Testing & Rollout

12.1 Test-Plan

Phase 1: Backend-Integration

  • OAuth Provider Manager implementieren
  • OAuth Handler Endpunkte
  • Session Management
  • Datenbank-Migrationen

Phase 2: Frontend-Integration

  • OAuth Login Buttons
  • Callback Handler
  • Session Storage
  • AuthContext Erweiterung

Phase 3: Testing

  • Unit Tests für OAuth Flow
  • Integration Tests
  • Security Tests (CSRF, Token Validation)
  • User Acceptance Testing

Phase 4: Rollout

  • Staging Deployment
  • Production Deployment
  • Monitoring & Logging

12.2 Rollback-Plan

Falls Probleme auftreten:

  1. OAuth-Endpunkte deaktivieren (Feature Flag)
  2. Bestehende Basic Auth bleibt funktionsfähig
  3. Datenbank-Migrationen sind rückwärtskompatibel

13. Monitoring & Logging

13.1 Logging

OAuth-Events:

  • OAuth Flow Initiation
  • OAuth Callback (Erfolg/Fehler)
  • User-Erstellung via OAuth
  • Session-Erstellung/Löschung
  • Token-Refresh

Structured Logging:

logOAuthEvent("oauth_login_initiated", map[string]interface{}{
    "provider": "google",
    "user_id": userID,
    "ip_address": ip,
    "trace_id": traceID,
})

13.2 Metrics

Zu tracken:

  • Anzahl OAuth-Logins pro Provider
  • Erfolgsrate OAuth Flows
  • Session-Dauer
  • Fehlerrate (Invalid Code, Token Expiry, etc.)

14. Zukünftige Erweiterungen

14.1 Multi-Factor Authentication

  • OAuth als Second Factor für Basic Auth User

14.2 SSO (Single Sign-On)

  • SAML 2.0 Support
  • OpenID Connect

14.3 Social Login

  • Weitere Provider: Facebook, Twitter, LinkedIn

14.4 Account Management

  • UI für Verknüpfung mehrerer OAuth-Accounts
  • Entkopplung von OAuth-Accounts

15. Abhängigkeiten

15.1 Backend (Go)

// OAuth Libraries
github.com/golang/oauth2
github.com/coreos/go-oidc/v3/oidc  // Für OpenID Connect

// JWT
github.com/golang-jwt/jwt/v5

// Encryption
golang.org/x/crypto

15.2 Frontend

Keine zusätzlichen Dependencies nötig (native Fetch API für OAuth Flow)


16. Risiken & Mitigation

16.1 Risiken

Risiko Wahrscheinlichkeit Impact Mitigation
OAuth Provider Downtime Mittel Hoch Fallback auf Basic Auth
Token-Leak Niedrig Sehr Hoch HttpOnly Cookies, Token Rotation
CSRF-Angriffe Mittel Hoch State Parameter Validation
Account Takeover Niedrig Sehr Hoch Email-Verification, Rate Limiting

16.2 Security Best Practices

  • HTTPS nur (in Production)
  • State Parameter für CSRF Protection
  • Token-Verschlüsselung in DB
  • Session Timeout
  • Rate Limiting
  • Audit Logging

17. Zusammenfassung

17.1 Vorteile

  • Benutzerfreundlichkeit: Ein-Klick-Login mit bekannten Accounts
  • Sicherheit: Keine Passwort-Verwaltung für OAuth-User
  • Skalierbarkeit: Externe Provider übernehmen Authentifizierung
  • Flexibilität: Hybrid-System unterstützt beide Methoden

17.2 Herausforderungen

  • Komplexität: Zusätzliche Infrastruktur und Code
  • Abhängigkeit: Abhängig von externen Providern
  • Migration: Bestehende User müssen unterstützt werden
  • Testing: Mehr Test-Szenarien durch Multi-Provider

Erstellt am: 2025-01-XX
Version: 1.0
Status: Konzept - Noch nicht implementiert