Files
qrcode-generator/docs/authentik.md
T
Florian Wilde c8d60d8006 Anmeldung ueber Authentik und andere OIDC-Anbieter
Anmeldefluss mit PKCE (S256), State und Nonce. Das ID-Token wird gegen den
JWKS des Anbieters geprueft — Signatur, Aussteller, Empfaenger, Ablauf und
Nonce; alles Noetige kommt aus dem Discovery-Dokument, damit die Anbindung
nicht auf Authentik festgelegt ist.

Wiedererkannt wird jemand an der Kennung des Anbieters (sub), nicht an der
E-Mail-Adresse — Adressen aendern sich. Ein bestehendes Konto mit derselben
Adresse wird verknuepft statt verdoppelt, aber nur bei bestaetigter Adresse:
sonst koennte sich beim Anbieter jemand eine fremde Adresse eintragen und
damit ein hiesiges Konto uebernehmen.

Uebernommen wird bewusst nur, wer jemand ist — plus die Instanz-Administration,
wenn OIDC_ADMIN_GROUP gesetzt ist. Gruppen und Rollen bleiben Sache dieser
Anwendung: die Gruppen im Verzeichnis bedeuten etwas anderes als die hier.

Konten aus dem Verzeichnis haben kein Passwort mehr (passwordHash ist jetzt
optional); Konto-Bereich und Passwort-Anmeldung sagen das statt an einer
leeren Pruefung zu scheitern.

Anleitung mit allen Feldern in Authentik: docs/authentik.md
2026-08-15 00:12:21 +02:00

10 KiB

Anmeldung über Authentik (OIDC)

Diese Anleitung richtet die Anmeldung am QR-Code-Generator über Authentik ein. Sie funktioniert genauso mit anderen OpenID-Connect-Anbietern — Keycloak, Zitadel, Entra ID —, weil die Anwendung alles Nötige aus dem Discovery-Dokument des Anbieters liest. Die Beispiele nennen Authentik, weil die Feldnamen dort so heißen.

Zeitbedarf: etwa 15 Minuten.


Vorher klären

Frage Antwort für diese Anleitung
Adresse der Anwendung https://qr.example.com
Adresse von Authentik https://auth.example.com
Läuft die Anwendung über HTTPS? Ja — siehe Hinweis unten

HTTPS ist Pflicht, sobald es über den eigenen Rechner hinausgeht. Beim Anmelden gehen Token über die Leitung, und der Sitzungs-Cookie wird nur bei https:// in der BASE_URL als Secure gesetzt. Für einen Versuch im LAN geht auch HTTP; produktiv gehört ein Reverse Proxy davor (siehe README, Abschnitt „Hinter einem Reverse Proxy“).

Die Anwendung muss Authentik erreichen können und umgekehrt der Browser beide. Laufen beide in Docker auf demselben Host, genügt es meist, sie ins selbe Netz zu hängen — der Browser braucht aber in jedem Fall öffentlich auflösbare Adressen.


Schritt 1 — In Authentik einen Provider anlegen

Applications → Providers → Create → OAuth2/OpenID Provider

Feld Wert
Name QR-Code-Generator
Authorization flow default-provider-authorization-explicit-consent (oder implicit, wenn niemand zustimmen soll)
Client type Confidential
Client ID notieren — kommt gleich in die .env
Client Secret notieren — ebenfalls
Redirect URIs https://qr.example.com/api/auth/oidc/callback
Signing Key ein vorhandenes Zertifikat auswählen
Subject mode Based on the User's hashed ID (Voreinstellung)

Zu den Scopes: openid, email und profile müssen ausgewählt sein. Ohne email liefert Authentik keine Adresse, und die Anwendung lehnt die Anmeldung mit einer entsprechenden Meldung ab.

Redirect URI genau so eintragen. Ein fehlendes https://, ein Schrägstrich zu viel oder ein anderer Hostname führt zu redirect_uri mismatch — Authentik bricht dann ab, bevor die Anwendung überhaupt etwas mitbekommt.


Schritt 2 — Eine Application anlegen

Applications → Applications → Create

Feld Wert
Name QR-Code-Generator
Slug qrcode-generator
Provider der eben angelegte Provider
Launch URL https://qr.example.com

Der Slug steckt gleich in der Issuer-Adresse — merken.

Wer den Zugang einschränken will, hängt hier unter Policy / Group / User Bindings eine Gruppe ein. Das ist der empfohlene Weg: Wer sich bei Authentik anmelden darf, kommt sonst auch in den QR-Code-Generator.


Schritt 3 — Die Issuer-Adresse herausfinden

Authentik zeigt sie beim Provider unter Provider Info als OpenID Configuration Issuer. Sie sieht so aus:

https://auth.example.com/application/o/qrcode-generator/

Prüfen lässt sich das direkt:

curl https://auth.example.com/application/o/qrcode-generator/.well-known/openid-configuration

Kommt ein JSON-Dokument mit authorization_endpoint, token_endpoint und jwks_uri zurück, stimmt die Adresse.


Schritt 4 — Die .env ergänzen

AUTH_ENABLED=true

OIDC_ENABLED=true
OIDC_ISSUER=https://auth.example.com/application/o/qrcode-generator/
OIDC_CLIENT_ID=<Client ID aus Schritt 1>
OIDC_CLIENT_SECRET=<Client Secret aus Schritt 1>
OIDC_BUTTON_LABEL=Mit Authentik anmelden
OIDC_SCOPES=openid email profile
OIDC_DEFAULT_ROLE=EDITOR
OIDC_ADMIN_GROUP=qr-admins
OIDC_GROUPS_CLAIM=groups
OIDC_ONLY=false

Danach neu starten:

docker compose up -d

OIDC_ENABLED allein genügt nicht — AUTH_ENABLED muss ebenfalls true sein. Ohne Anmeldung gibt es keine Benutzer, denen eine Anmeldung zugeordnet werden könnte.


Schritt 5 — Ausprobieren

https://qr.example.com/anmelden aufrufen. Über dem Passwortfeld steht jetzt „Mit Authentik anmelden“. Ein Klick führt zu Authentik, nach der Anmeldung geht es zurück in die Anwendung.

Alle Anmeldenden bekommen die Rolle aus OIDC_DEFAULT_ROLE in der Standardgruppe. Wer die Verwaltung öffnen darf, hängt davon ab, ob OIDC_ADMIN_GROUP gesetzt ist:

  • Leer: Der erste Mensch, der sich anmeldet, wird Administrator dieser Installation — genau wie bei der Ersteinrichtung mit Passwort. Danach vergibt man das Recht unter Verwaltung → Benutzer.
  • Gesetzt: Dann entscheidet allein die Gruppe, und zwar bei jeder Anmeldung neu — auch beim allerersten Benutzer.

Achtung beim ersten Mal: Wenn du OIDC_ADMIN_GROUP setzt, vergewissere dich, dass dein eigenes Konto in dieser Gruppe ist. Sonst hat niemand Zugang zur Verwaltung. Der Weg zurück ist einfach: die Variable leeren, docker compose up -d, neu anmelden — dann greift wieder die Regel „der erste wird Administrator“, sofern es noch gar keinen gibt.


Was die Anwendung aus Authentik übernimmt — und was nicht

Übernommen Bleibt in der Anwendung
Wer jemand ist (sub) Mitgliedschaft in Gruppen
E-Mail-Adresse Rolle je Gruppe (Admin/Bearbeiter/Betrachter)
Anzeigename Zuteilung von Domains
Instanz-Administration, falls OIDC_ADMIN_GROUP gesetzt ist alles Übrige

Das ist eine bewusste Entscheidung. Die Gruppen in Authentik und die Gruppen hier bedeuten nicht dasselbe: dort geht es um Organisation und Zugang, hier um die Frage, wer welche QR-Codes sehen und ändern darf. Eine automatische Übersetzung wäre eine Quelle stiller Überraschungen — deshalb pflegt man Gruppen und Rollen weiterhin unter Verwaltung → Gruppen.

Wiedererkannt wird jemand an der Kennung von Authentik (sub), nicht an der E-Mail-Adresse. Ändert sich die Adresse, bleibt es dasselbe Konto.

Die Admin-Gruppe

Steht in OIDC_ADMIN_GROUP ein Gruppenname, entscheidet Authentik bei jeder Anmeldung neu, wer die Verwaltung öffnen darf: Mitglieder der Gruppe bekommen das Recht, alle anderen verlieren es. Bleibt die Variable leer, rührt die Anmeldung das Recht nicht an — dann pflegt man es hier.


Bestehende Konten übernehmen

Gibt es hier schon Konten mit Passwort, werden sie beim ersten Anmelden über Authentik anhand der E-Mail-Adresse verknüpft. Aus dem lokalen Administrator wird also kein zweites Konto; Gruppen, Rollen und die angelegten Codes bleiben.

Verknüpft wird nur, wenn Authentik die Adresse als bestätigt meldet. Sonst könnte sich beim Anbieter jemand eine fremde Adresse eintragen und damit ein hiesiges Konto übernehmen. Meldet Authentik sie als unbestätigt, bricht die Anmeldung mit einer Erklärung ab.

Ist ein Konto einmal verknüpft, gibt es dafür kein Passwort mehr: Der Bereich Konto zeigt dann statt der Passwortänderung einen Hinweis auf den Anbieter.


Nur noch über Authentik anmelden

OIDC_ONLY=true

Danach verschwindet das Passwortfeld von der Anmeldeseite.

Vorher an den Notausgang denken. Fällt Authentik aus oder ist der Provider falsch konfiguriert, kommt niemand mehr hinein. Der Weg zurück: OIDC_ONLY=false in der .env, docker compose up -d — dann geht die Anmeldung mit Passwort wieder. Lege dir dafür ein lokales Administratorkonto an, bevor du umstellst.


Wenn etwas nicht klappt

Symptom Ursache und Abhilfe
Der Knopf erscheint nicht AUTH_ENABLED oder OIDC_ENABLED steht nicht auf true. Prüfen mit docker compose exec app env | grep OIDC. Steht dort nichts, fehlt die Variable im environment:-Block der docker-compose.yml — die .env allein reicht nicht.
„Die Anmeldung über den externen Anbieter ist unvollständig eingerichtet“ Es fehlt OIDC_ISSUER, OIDC_CLIENT_ID oder OIDC_CLIENT_SECRET. Die Meldung nennt, welche.
„Der Anmelde-Anbieter ist nicht erreichbar“ Der Container kommt nicht an Authentik. Testen mit docker compose exec app wget -qO- <issuer>/.well-known/openid-configuration. Häufig: interner DNS-Name statt öffentlicher Adresse.
Authentik meldet redirect_uri mismatch Die Redirect URI im Provider stimmt nicht exakt mit {BASE_URL}/api/auth/oidc/callback überein. Auf Schema, Hostname und Schrägstriche achten.
„Der Anbieter hat keine E-Mail-Adresse geliefert“ Der Scope email fehlt im Provider, oder der Benutzer hat in Authentik keine Adresse hinterlegt.
„Der Anbieter hat die Anmeldung abgelehnt“ Der Benutzer ist der Application in Authentik nicht zugeordnet — Policy/Group Binding prüfen.
„Der Anmeldevorgang ist abgelaufen“ Zwischen Klick und Rückkehr sind mehr als 10 Minuten vergangen, oder der Cookie ging verloren. Häufigste echte Ursache: BASE_URL zeigt auf eine andere Adresse als die, über die der Browser kommt.
„Das Anmelde-Token des Anbieters ist ungültig“ Uhrzeit-Abweichung zwischen den Servern oder ein gewechselter Signaturschlüssel. Beides zeigt docker compose logs app genauer.
Nach der Anmeldung fehlt die Verwaltung OIDC_ADMIN_GROUP ist gesetzt, der Benutzer aber nicht in dieser Gruppe. Entweder die Gruppe in Authentik ergänzen oder die Variable leeren und das Recht hier vergeben.

Ausführlichere Meldungen stehen im Protokoll:

docker compose logs -f app

Was technisch passiert

  1. Klick auf den Knopf → /api/auth/oidc/start. Die Anwendung holt das Discovery-Dokument, würfelt state, nonce und ein PKCE-Geheimnis und legt sie in einen kurzlebigen, httpOnly-Cookie.
  2. Weiterleitung zu Authentik mit code_challenge (S256).
  3. Nach der Anmeldung kommt Authentik mit code und state zurück auf /api/auth/oidc/callback. Stimmt der state nicht, endet es hier.
  4. Die Anwendung tauscht den Code gegen Token — mit Client-Geheimnis und PKCE-Verifier. Ein abgefangener Code allein nützt also niemandem.
  5. Das ID-Token wird gegen den JWKS von Authentik geprüft: Signatur, Aussteller, Empfänger, Ablauf und nonce.
  6. Konto suchen (über sub, ersatzweise über die bestätigte Adresse), anlegen oder verknüpfen — und die Sitzung wie bei der Passwort-Anmeldung setzen.

Die Sitzung selbst ist danach dieselbe wie sonst: ein Zufallstoken im Cookie, in der Datenbank nur dessen SHA-256. Abmelden beendet sie hier; bei Authentik bleibt man angemeldet.