Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Identity & Access Management Glossar

OAuth 2.0 / OpenID Connect

OAuth 2.0 ist ein Autorisierungsframework das Anwendungen limitierten Zugriff auf Ressourcen im Namen eines Nutzers erlaubt. OpenID Connect (OIDC) baut auf OAuth 2.0 auf und fügt Authentifizierung hinzu - die Basis für modernes Single Sign-On und Social Login.

OAuth 2.0 ermöglicht eine fundamentale Sicherheitsverbesserung: Anstatt Third-Party-Apps das Passwort zu geben (was historisch tatsächlich gemacht wurde!), erteilt der Nutzer der App nur die spezifischen Berechtigungen die sie benötigt - für eine begrenzte Zeit, jederzeit widerruflich. OpenID Connect erweitert OAuth um standardisierte Identitätsinformationen.

OAuth 2.0 in einem Satz erklärt

Analogie: Im Hotelbetrieb geben Sie dem Parkservice nicht Ihren Haustürschlüssel, sondern einen Valet-Key der nur das Auto starten kann. Bei OAuth geben Sie der App nicht Ihr Passwort, sondern ein Token das nur bestimmte Aktionen erlaubt.

Ohne OAuth (historisch):

“Bitte geben Sie Ihr Google-Passwort ein, damit wir Ihre Kontakte importieren können” - Die App hatte Vollzugriff auf alles; Widerruf nur durch Passwort ändern möglich.

Mit OAuth 2.0:

“Erlauben Sie XY-App Zugriff auf: Ihre Kontaktliste (nur lesen)” - Token mit eingeschränktem Scope; Widerruf jederzeit in Google-Einstellungen, ohne Passwort zu ändern.

Die OAuth 2.0 Komponenten

Die 4 Rollen

Resource Owner (Nutzer):

  • Besitzt die Ressourcen (E-Mails, Kontakte, etc.)
  • Erteilt Zugriffserlaubnis

Client (Anwendung):

  • App die auf Ressourcen zugreifen möchte
  • Registriert beim Authorization Server (erhält Client ID + Secret)

Authorization Server (IdP):

  • Stellt Access Tokens aus nach Zustimmung
  • Beispiele: Google, Microsoft Entra ID, Auth0, Keycloak

Resource Server (API):

  • Hält die Ressourcen (Gmail API, Calendar API)
  • Akzeptiert Access Tokens und liefert Daten

Zentrale Konzepte

BegriffBedeutung
Access TokenKurzlebig (15min-1h), für API-Zugriff
Refresh TokenLanglebig (7-30 Tage), holt neue Access Tokens
ScopeWelche Permissions? (read:contacts, write:calendar)
StateCSRF-Schutz beim Authorization Request
PKCEProof Key for Code Exchange (für Public Clients)

OAuth 2.0 Flows

1. Authorization Code Flow + PKCE (empfohlen für alle)

Wann: Web-Apps, Mobile Apps, Single Page Apps Sicherheit: Höchste (Code wird gegen Token eingetauscht)

Ablauf:
a) App generiert code_verifier (zufällig) + code_challenge (SHA256 davon)
b) App sendet User zu IdP:
   GET /authorize?
     client_id=abc
     &response_type=code
     &scope=openid email
     &redirect_uri=https://app.firma.de/callback
     &state=zufälligerWert
     &code_challenge=<hash>
     &code_challenge_method=S256

c) User loggt sich beim IdP ein
d) IdP redirectet zu Callback mit Authorization Code:
   GET /callback?code=auth_code_123&state=zufälligerWert

e) App tauscht Code gegen Token:
   POST /token
     grant_type=authorization_code
     &code=auth_code_123
     &redirect_uri=https://app.firma.de/callback
     &client_id=abc
     &code_verifier=<original_verifier>  ← PKCE!

f) IdP liefert:
   { "access_token": "...", "refresh_token": "...", "id_token": "..." }

2. Client Credentials Flow

Wann: Server-zu-Server (kein User beteiligt) Beispiel: Microservice ruft andere API auf

POST /token
  grant_type=client_credentials
  &client_id=service-a
  &client_secret=secret
  &scope=api:read

Veraltete Flows - nicht verwenden

  • Implicit Flow (veraltet): Token in URL → History, Logs, Referer-Header; ersetzt durch Authorization Code + PKCE
  • Password Grant Flow (veraltet): App erhält Passwort direkt → OAuth-Sicherheit ausgehebelt; nur für Legacy-Migration

OpenID Connect (OIDC)

OIDC = OAuth 2.0 + Identitätsschicht

Was OIDC hinzufügt:

  • ID Token (JWT): wer ist der User?
  • /userinfo Endpoint: Nutzerinformationen abrufen
  • Standard-Scopes: openid, profile, email, phone, address
  • Discovery Endpoint: /.well-known/openid-configuration
// ID Token Inhalt (JWT Payload):
{
  "iss": "https://accounts.google.com",     // Issuer
  "sub": "10769150350006150715113082367",    // Subject (User-ID)
  "aud": "client_id_123",                   // Audience (deine App)
  "exp": 1311281970,                        // Expiry
  "iat": 1311280970,                        // Issued At
  "nonce": "0394852-3190485-2490358",        // CSRF-Schutz
  "email": "user@example.com",
  "email_verified": true,
  "name": "Max Muster"
}

Wichtige Validierungen des ID Tokens:

  1. iss == bekannter Issuer (nicht “Evil IdP”!)
  2. aud == deine Client ID (kein Token-Substitution-Angriff!)
  3. exp > jetzt (Token nicht abgelaufen)
  4. nonce == gesendeter Nonce (CSRF-Schutz)
  5. Signatur mit IdP-Public-Key gültig
  6. Algorithmus: RS256 oder ES256 (nicht none oder HS256!)

OAuth-Sicherheitslücken

1. Redirect URI Validation (häufigste Schwachstelle)

FALSCH: Redirect-URI-Whitelist: "https://app.firma.de/*"
Angriff: redirect_uri=https://app.firma.de/callback?next=https://attacker.com
→ OAuth Code wird an attacker.com weitergeleitet!

RICHTIG: Exakte URI (kein Wildcard!):
Whitelist: ["https://app.firma.de/callback"]

2. State Parameter fehlt (CSRF)

Angriff: Angreifer lässt Opfer OAuth-Flow starten mit Angreifer-Code → Opfer loggt sich mit Angreifer-Account in App ein. Schutz: State-Parameter setzen und validieren!

3. Open Redirect über Redirect URI

Wenn App nach OAuth auf user-bestimmte URL redirectet:

Angriff: ?redirect=/nach-login?url=https://phishing.com
Schutz: Nur erlaubte relative URLs als Redirect

4. Authorization Code Interception (ohne PKCE)

Code in URL sichtbar → Referer-Header, Proxy-Logs. Schutz: PKCE erzwingen (code_challenge)

5. Token Leakage in Logs

Access Tokens in URL-Parametern → Server-Logs enthalten Token. Schutz: Token NUR in Authorization-Header, nie in URL

Angreifer registriert App bei Google/Microsoft mit glaubwürdigem Namen (“IT-Support Tool”) und weitem Scope (offline_access, Mail.ReadWrite). User erteilt Consent → Angreifer hat Vollzugriff auf Mailbox. Schutz: Conditional Access Policy → Admin-Approval für neue Apps

Implementierung: Node.js mit Passport.js

// Express + Passport.js + OIDC

import passport from 'passport';
import { Strategy as OIDCStrategy } from 'passport-openidconnect';

passport.use(new OIDCStrategy({
  issuer: 'https://accounts.google.com',
  authorizationURL: 'https://accounts.google.com/o/oauth2/v2/auth',
  tokenURL: 'https://oauth2.googleapis.com/token',
  userInfoURL: 'https://openidconnect.googleapis.com/v1/userinfo',
  clientID: process.env.GOOGLE_CLIENT_ID,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  callbackURL: 'https://app.firma.de/auth/callback',
  scope: ['openid', 'email', 'profile'],

  // Sicherheit:
  pkce: true,       // PKCE aktivieren!
  state: true,      // State-Parameter für CSRF-Schutz
}, async (issuer, profile, done) => {
  // User in Datenbank finden oder erstellen
  const user = await User.findOrCreate({ googleId: profile.id });
  return done(null, user);
}));

// Routes:
app.get('/auth/google', passport.authenticate('openidconnect'));

app.get('/auth/callback',
  passport.authenticate('openidconnect', { failureRedirect: '/login' }),
  (req, res) => res.redirect('/dashboard')
);

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung