|
3 | 3 | OIDC-Fundament der „-bar“-Tools (auf Basis von mozilla-django-oidc): |
4 | 4 |
|
5 | 5 | - `oidc.OIDCBackend` — Claim-Mapping aufs Tool-User-Model, Just-in-time- |
6 | | - Provisionierung, IdP-Gruppen → Django-Admin (autoritativ), optionale |
7 | | - Account-Obergrenze und Subject-Drift-Fallback (beides aus per Default). |
| 6 | + Provisionierung, IdP-Gruppe → Django-Admin, optionale Account-Obergrenze |
| 7 | + und Subject-Drift-Fallback (beides aus per Default). |
8 | 8 | - `oidc.SilentLoginView` — Silent SSO (`prompt=none`, kein Redirect-Loop). |
| 9 | +- `oidc.SafeOIDCCallbackView` — mozillas Callback, der einen wiederholten |
| 10 | + Callback (Browser-„Zurück“ direkt nach dem Login) auf die SPA umleitet |
| 11 | + statt eine 400-Seite zu zeigen; loggt niemanden ein. |
9 | 12 | - `oidc.backchannel_logout` — OIDC Back-Channel Logout 1.0 (Token-Prüfung, |
10 | | - löscht alle Sessions des Subjects). |
| 13 | + löscht alle Sessions des Subjects über den Session-Index). |
11 | 14 | - `oidc.provider_logout_url`, `oidc.is_oidc_admin`, `oidc.claims_in_admin_group` |
| 15 | +- `views.whoami_payload` / `views.whoami`, `views.logout_view`, |
| 16 | + `views.set_language` — die Session-Endpunkte der SPA; `urls.urlpatterns` |
| 17 | + verdrahtet OIDC-Routen und `api/whoami/language/`. |
12 | 18 | - `discovery.discover_endpoints` — Endpunkte aus `OIDC_OP_ISSUER` ableiten. |
13 | 19 | - `models.AbstractBasicUser` — Basis fürs konkrete `accounts.User` des Tools |
14 | | - (`subject` + `claims`; ADR-0003: Model und Migrationen bleiben im Tool). |
| 20 | + (`subject`, `claims`, `language`; ADR-0003: Model und Migrationen bleiben |
| 21 | + im Tool). `models.UserSession` — Index Nutzer → Session (eigene |
| 22 | + Migration im Paket). |
15 | 23 |
|
16 | 24 | ## Einbinden |
17 | 25 |
|
18 | 26 | ```python |
19 | | -INSTALLED_APPS = [..., "basicbar_auth"] |
| 27 | +INSTALLED_APPS = [..., "basicbar_auth"] # hat seit 0.2 eine eigene Migration |
20 | 28 | AUTHENTICATION_BACKENDS = [ |
21 | 29 | "basicbar_auth.oidc.OIDCBackend", |
22 | 30 | "django.contrib.auth.backends.ModelBackend", |
23 | 31 | ] |
24 | 32 | OIDC_OP_LOGOUT_URL_METHOD = "basicbar_auth.oidc.provider_logout_url" |
25 | 33 |
|
26 | | -# urls.py |
27 | | -from basicbar_auth.oidc import SilentLoginView, backchannel_logout |
28 | | -path("oidc/silent/", SilentLoginView.as_view(), name="oidc-silent"), |
29 | | -path("oidc/backchannel-logout/", backchannel_logout, name="oidc-backchannel-logout"), |
30 | | -path("oidc/", include("mozilla_django_oidc.urls")), |
| 34 | +# urls.py — logout-redirect, silent, backchannel-logout, callback, mozilla, |
| 35 | +# api/whoami/language/ in einem Rutsch; api/whoami/ bleibt Sache des Tools: |
| 36 | +path("", include("basicbar_auth.urls")), |
| 37 | +path("api/whoami/", whoami), |
| 38 | + |
| 39 | +# accounts/models.py |
| 40 | +class User(AbstractBasicUser): # subject, claims, language kommen mit |
| 41 | + ... # (ein eigenes, gleiches `language` darf bleiben) |
| 42 | + |
| 43 | +# accounts/views.py — whoami mit Tool-Feldern: |
| 44 | +from basicbar_auth.views import whoami_payload |
| 45 | +def whoami(request): |
| 46 | + return JsonResponse({**whoami_payload(request), "ai_enabled": ai.is_enabled()}) |
31 | 47 | ``` |
32 | 48 |
|
| 49 | +`whoami_payload` liefert `authenticated`, `csrf_token` und — angemeldet — |
| 50 | +`username`, `first_name`, `last_name`, `email`, `subject`, `is_staff`, |
| 51 | +`language`. Ohne eigene Felder reicht `basicbar_auth.views.whoami` direkt. |
| 52 | + |
33 | 53 | Claim-Namen (`OIDC_CLAIM_USERNAME`, …), `OIDC_GROUPS_CLAIM`/`OIDC_ADMIN_GROUP` |
34 | 54 | und die optionalen Verhalten kommen aus Settings mit Paket-Defaults |
35 | | -(`conf.py`). Bestehende Tools adoptieren ohne Umbau ihres User-Models. |
| 55 | +(`conf.py`). Bestehende Tools adoptieren ohne Umbau ihres User-Models |
| 56 | +(`AbstractUser` + identische Felder funktioniert weiter). |
| 57 | + |
| 58 | +**Admin-Gruppe:** Mit `OIDC_ADMIN_GROUP` verleiht die Gruppenmitgliedschaft |
| 59 | +`is_staff`/`is_superuser` und ihr Verlust entzieht sie — aber nur Rechte, |
| 60 | +die aus der Gruppe kamen (erkennbar am Claims-Snapshot des letzten Logins). |
| 61 | +Eine Beförderung im Tool (Nutzerverwaltung, Django-Admin) überlebt den |
| 62 | +nächsten Login; `is_oidc_admin(user)` sagt dem Tool, welche Admins der IdP |
| 63 | +verwaltet (die darf das Tool lokal nicht entziehen). |
| 64 | + |
| 65 | +**Session-Index:** `user_logged_in`/`user_logged_out` pflegen `UserSession`; |
| 66 | +der Back-Channel-Logout löscht darüber gezielt, statt jede unabgelaufene |
| 67 | +Session zu dekodieren (relevant bei vielen anonymen Besucher-Sessions). |
| 68 | +Sessions aus der Zeit vor 0.2 kennt der Index nicht — für sie bleibt der |
| 69 | +Scan als Fallback, bis sie ablaufen. Voraussetzung ist der DB-Session-Store. |
| 70 | + |
| 71 | +**Discovery:** `discover_endpoints` loggt Fehler (WARNING) und liefert `{}`, |
| 72 | +damit der Settings-Import nicht abstürzt. Produktiv sollten die Settings bei |
| 73 | +leeren Endpunkten mit `ImproperlyConfigured` abbrechen (so das Template), |
| 74 | +sonst scheitert jeder Login später mit einem unklaren Fehler. |
36 | 75 |
|
37 | 76 | ## Betreiber-Hinweise (Fristen, Kennungs-Wiedervergabe) |
38 | 77 |
|
|
0 commit comments