Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
de:int:wvdsshell:notes:01-auth-architecture:auth-shell [2026/03/05 14:38] – [1. Auth-Architektur: WvdS.Shell (Benutzeroberfläche)] Wolfgang van der Stillede:int:wvdsshell:notes:01-auth-architecture:auth-shell [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1
Zeile 1: Zeile 1:
-====== 2. Auth-Architektur: WvdS.Shell (Benutzeroberfläche) ====== 
- 
-//Stand: 2026-03-05// 
- 
-Übergeordnet: [[de:int:wvdsshell:notes:01-auth-architecture:start|Auth-Architektur — Gesamtübersicht]] 
-Verwandt: [[de:int:wvdsshell:notes:01-auth-architecture:auth-gateway|3. Gateway.Service]] | [[de:int:wvdsshell:notes:01-auth-architecture:auth-database|4. Datenschicht]] | [[de:int:wvdsshell:notes:01-auth-architecture:auth-migration|5. Migration]] 
- 
-===== Konzept ===== 
- 
-WvdS.Shell verwendet eine **zweischichtige Auth-Architektur**: 
- 
-  - **Schicht 1 — PFX-Zertifikat** (Installations-/Lizenznachweis): Wird von WvdS ausgestellt und trägt Lizenz- und Deployment-Metadaten als Custom-Extensions. Wird lokal validiert — auch offline. 
-  - **Schicht 2 — Identity Provider** (Benutzer-Authentifizierung): Kerberos (SSO, on-net) oder externer MFA-Flow (off-net). Liefert einen JWT Session Token. 
- 
-Beide Schichten müssen erfolgreich sein, bevor eine Extension lädt oder Business-Daten sichtbar sind. 
- 
-===== Schicht 1 — PFX-Zertifikat ===== 
- 
-==== Zweck ==== 
- 
-Das PFX (PKCS#12) dient gleichzeitig als: 
- 
-  * **Lizenznachweis** — Was ist lizenziert? Welche Features? Bis wann? 
-  * **Deployment-Nachweis** — Für welche Domänen/User ist die Installation freigegeben? 
-  * **Offline-Credential** — Wenn Gateway nicht erreichbar, gilt ein valides PFX als Zugangsnachweis für den Offline-Modus. 
- 
-==== Ausstellung ==== 
- 
-WvdS betreibt eine interne CA. Jede Kundeninstallation erhält ein signiertes PFX: 
- 
-  * Signiert mit WvdS-CA (Root-Cert wird im Shell-Binary oder bekanntem Store-Pfad mitgeliefert) 
-  * Laufzeit typisch 1 Jahr (Renewal-Flow ist Aufgabe des Gateway-Service) 
-  * Kein Wildcard — pro Deployment ein eigenes Zertifikat 
- 
-==== Custom Extensions (OID-Struktur) ==== 
- 
-Die Custom-Attributes werden als X.509v3-Extensions mit privatem OID-Arc geschrieben. 
-Vorgeschlagener Arc: ''1.3.6.1.4.1.XXXXX.1.*'' (IANA Private Enterprise Number von WvdS). 
- 
-^ OID-Suffix ^ Attribut-Name           ^ Beispielwert         ^ Beschreibung                           ^ 
-| ''.1''     | ''wvds.license.tier''   | ''professional''     | Lizenz-Stufe                           | 
-| ''.2''     | ''wvds.license.expires'' | ''2027-01-01''      | Ablaufdatum (ISO 8601)                 | 
-| ''.3''     | ''wvds.auth.domains''   | ''ENI,VERSALIS''     | Erlaubte AD-Domänen (Komma-getrennt)   | 
-| ''.4''     | ''wvds.auth.users''     | ''*''                | Erlaubte Usernamen oder ''*'' für alle | 
-| ''.5''     | ''wvds.install.id''     | ''ENIVERS-2026-001'' | Eindeutige Installations-ID            | 
-| ''.6''     | ''wvds.tenant.name''    | ''ENI VERSALIS GmbH'' | Anzeigename der Installation          | 
- 
-> **Nicht im PFX:** ''wvds.license.features'' — Feature-Flags werden nach Auth aus der DB geladen (siehe [[#feature-flags_eniversasys|Feature-Flags / ENIVERSASYS]]). 
- 
-==== Deployment-Varianten ==== 
- 
-^ Variante          ^ Speicherort                                  ^ Schutzmechanismus              ^ 
-| **Corpnet**       | Windows Cert Store (''LocalMachine\My''    | Windows ACL, GPO-Deployment    | 
-| **BYOD / Extern** | Datei ''%APPDATA%\WvdS\license.pfx''         | Passwort in DPAPI SecretStorage | 
- 
-Cert-Store-Variante: Kein Passwort nötig — Windows schützt den Private Key. Shell sucht Zertifikat anhand Issuer-DN automatisch. 
- 
-==== Validierung ==== 
- 
-<code> 
-Shell-Start 
-      │ 
-      ▼ 
-┌─ PFX Validator ──────────────────────────────────────────────┐ 
-│  1. PFX im Cert Store oder Datei vorhanden?                  │ 
-│  2. Signaturkette gültig? (gegen gebündelten WvdS-Root)      │ 
-│  3. Zertifikat nicht abgelaufen?                             │ 
-│  4. wvds.auth.domains enthält aktuelle Domäne oder '*'?      │ 
-│  5. wvds.auth.users enthält aktuellen User oder '*'?         │ 
-│  6. Custom-Attributes laden → License-Objekt befüllen        │ 
-└──────────────────────────────────────────────────────────────┘ 
-         │ OK                        │ FAIL 
-         ▼                           ▼ 
-  Context-Detector           Shell zeigt nativen Fehler-Dialog: 
-  (Schicht 2)                "Kein gültiges Lizenzzertifikat" 
-                             → Shell-Start abgebrochen 
-</code> 
- 
-===== Schicht 2 — Identity Provider ===== 
- 
-==== Context-Aware Auth (Netzwerk-Erkennung) ==== 
- 
-<code> 
-      │ 
-      ▼ 
-┌─ Context-Detector ────────────────────────────────────┐ 
-│  1. Domain-joined?     → SSPI/Kerberos verfügbar?    │ 
-│  2. DC erreichbar?     → LDAP-Ping                   │ 
-│  3. Gateway erreichbar? → HTTP Health-Check          │ 
-└───────────────────────────────────────────────────────┘ 
-         │ 
-   ┌─────┴──────────┬────────────────┐ 
-   ▼                ▼                ▼ 
- Corpnet          Extern          Offline 
-(Kerberos)      (MFA-Flow)      (PFX-Only) 
-</code> 
- 
-==== Szenario A — Corpnet (LAN/WLAN) ==== 
- 
-  * Domain-joined + DC erreichbar + Gateway erreichbar 
-  * SSPI/Kerberos → Service Ticket für Gateway.Service 
-  * **Kein Dialog, kein Klick** — SSO out of the box 
-  * PFX-Domänen-Attribut wird gegen aktuelle AD-Domäne geprüft 
- 
-==== Szenario B — Home-Office mit VPN ==== 
- 
-  * VPN-Tunnel stellt DC-Erreichbarkeit wieder her → identisch wie Szenario A 
-  * Shell führt bei Gateway-Unerreichbarkeit automatische Retries durch (konfigurierbarer Timeout), bevor auf Szenario C/D eskaliert wird 
- 
-==== Szenario C — Extern / BYOD (MFA-Flow) ==== 
- 
-  * DC nicht erreichbar, kein VPN, Gateway aber erreichbar 
-  * **Nativer Auth-Dialog** (pre-WebView, FPC/Lazarus nativ) 
-  * Ablauf: 
-    - Username + Passwort → Gateway 
-    - Gateway sendet TOTP-Challenge 
-    - User öffnet MS Authenticator (OATH TOTP) → 6-stelliger Code 
-    - Gateway validiert → Access Token (JWT, kurzlebig) + Refresh Token (langlebig) 
-    - Refresh Token → ''SecretStorage'' (DPAPI) 
- 
-==== Szenario D — Offline (kein Gateway erreichbar) ==== 
- 
-  * Gateway nicht erreichbar (Server down, kein Netz) 
-  * Gültiges PFX vorhanden + nicht abgelaufen → **Offline-Modus** 
-  * Context Key ''auth.mode = offline'' wird gesetzt 
-  * Extensions können per ''when''-Clause offline-sensitive Features deaktivieren 
-  * Kein Refresh Token nötig — PFX ist der Credential 
-  * Offline-Modus-Dauer: bis PFX-Ablauf oder Gateway wieder erreichbar (Background-Retry) 
- 
-===== Feature-Flags / ENIVERSASYS ===== 
- 
-Feature-Flags steuern, welche Funktionen in der Shell und in Extensions aktiv sind. 
-Sie sind **kein Bestandteil des PFX** — das PFX kennt nur die Lizenz-Stufe (''tier''). 
-Die granularen Feature-Flags werden nach erfolgreicher Auth aus der DB geladen. 
- 
-==== Herkunft und Migration ==== 
- 
-^ Stand     ^ Namespace  ^ System      ^ 
-| Aktuell   | ''auth.*'' | ENIVERSCAFM | 
-| Zukünftig | ''auth.*'' | ENIVERSASYS | 
- 
-Die Shell spricht ausschließlich gegen das Gateway.Service. Das Gateway abstrahiert, 
-ob es ENIVERSCAFM oder ENIVERSASYS als Quelle verwendet — die Shell bekommt immer 
-dasselbe Antwortformat (JSON-Array der aktiven Feature-Keys). 
- 
-==== Ladereihenfolge ==== 
- 
-Feature-Flags werden innerhalb von ''spBlockAuth'' geladen, **nach** dem JWT-Erhalt 
-und **vor** ''AdvancePhase(spBlockRestore)''. Extensions dürfen in ''when''-Clauses 
-auf Feature-Flags zugreifen, also müssen sie vor dem Extension-Scan verfügbar sein. 
- 
-<code> 
-   Auth erfolgreich (JWT vorhanden) 
-         │ 
-         ▼ 
-   GET /api/features  →  Gateway.Service  →  ENIVERSASYS-DB 
-         │ 
-         ▼ 
-   Context Keys befüllen: 
-     license.features = grids,charts,scheduling,... 
-         │ 
-         ▼ 
-   AdvancePhase(spBlockRestore) 
-</code> 
- 
-==== Offline-Verhalten ==== 
- 
-Im Offline-Modus (Szenario D) ist kein Gateway-Aufruf möglich. 
-Zwei Optionen — Entscheidung offen: 
- 
-  * **Letzte bekannte Features** aus ''SecretStorage'' cachen (nach jedem erfolgreichen Online-Login schreiben) 
-  * **Nur Basisfunktionen** im Offline-Modus — Features deaktiviert bis Gateway erreichbar 
- 
-===== TOTP — Aufgabenteilung ===== 
- 
-TOTP (RFC 6238) basiert auf einem **geteilten Geheimnis** zwischen Authenticator-App und Server. 
-Die Kernfrage: Was muss WvdS.Shell selbst implementieren? 
- 
-==== Algorithmus (zur Orientierung) ==== 
- 
-<code> 
-Gemeinsames Geheimnis (base32) → bei Enrollment einmalig zwischen App und Server ausgetauscht 
-Counter = floor(unix_timestamp / 30)   ← 30-Sekunden-Fenster 
-Code = HMAC-SHA1(secret, counter) → auf 6 Dezimalstellen gekürzt 
-</code> 
- 
-MS Authenticator, Google Authenticator und jede andere OATH-TOTP-App erzeugen denselben Code, 
-solange sie dasselbe Geheimnis und eine synchrone Uhrzeit haben. 
- 
-==== Was Gateway.Service implementiert ==== 
- 
-Das ist **ausschließlich Server-Aufgabe**: 
- 
-  * Shared Secret pro User erzeugen und sicher speichern 
-  * Enrollment-URI (otpauth-Schema) und QR-Code für Authenticator-App generieren 
-  * Eingehenden 6-stelligen Code validieren (HMAC-SHA1, ±1 Fenster Toleranz für Uhrzeitabweichung) 
-  * Enrollment-Status pro User verwalten 
-  * Fehlversuche zählen, Lockout-Policy durchsetzen 
- 
-==== Was WvdS.Shell implementiert ==== 
- 
-**Nahezu nichts vom Algorithmus.** Die Shell ist nur ein UI-Träger für den Challenge-Response-Austausch: 
- 
-  - Challenge erkennen: Gateway antwortet mit ''HTTP 401'' + JSON-Body ''{"mfa_required": true, "challenge_id": "..."}'' 
-  - Nativen TOTP-Eingabe-Dialog anzeigen (6 Ziffern, pre-WebView, FPC/Lazarus) 
-  - Optionaler 30-Sekunden-Countdown (UX-Hilfe, kein funktionaler Bedarf) 
-  - Code + ''challenge_id'' an Gateway senden 
-  - Falsche Eingabe: Fehlermeldung anzeigen, Retry erlauben (Gateway definiert Max-Versuche) 
-  - Kein Zugriff auf das Shared Secret — liegt ausschließlich beim Gateway 
- 
-==== Enrollment-Flow ==== 
- 
-Enrollment (erstmalige Einrichtung) ist **kein Shell-Startup-Vorgang**. Zwei Optionen: 
- 
-^ Option ^ Umsetzung ^ Wann sinnvoll ^ 
-| **Admin-seitig** | Gateway-Weboberfläche, Admin verknüpft User mit Authenticator-App | Verwaltete Deployments | 
-| **Self-Service im Shell** | Shell öffnet Gateway-Enrollment-URL in dediziertem WebView-Tab | BYOD, erster Start ohne Enrollment | 
- 
-Beim Self-Service-Flow zeigt die Shell einen WebView, der auf die Gateway-Enrollment-Seite zeigt. 
-Die Shell selbst generiert dabei nichts — der gesamte Enrollment-Prozess läuft im Gateway. 
- 
-==== Zusammenfassung: Was WvdS.Shell selbst codiert ==== 
- 
-  * ''WvdS.Shell.Auth.Provider.TOTP.pas'' — nur Challenge/Response-Protokoll (HTTP-Austausch) 
-  * ''WvdS.Shell.GUI.AuthDialog.pas'' — 6-Ziffern-Eingabefeld + optionaler Countdown-Timer 
-  * Kein HMAC, kein base32, kein Geheimnis-Management — das gehört zum Gateway 
- 
-Gateway-seitige TOTP-Implementierung (Shared Secret, HMAC-SHA1, Lockout): 
-[[de:int:wvdsshell:notes:01-auth-architecture:auth-gateway#totp_service|3. Gateway-Doku: TOTP Service]] 
- 
-===== Token-Flow zwischen Shell und Gateway.Service ===== 
- 
-<code> 
-Shell (Client)              Gateway.Service 
-      │                            │ 
-      │── SSPI Negotiate ─────────►│  (Kerberos — Szenario A/B) 
-      │   + PFX install.id         │  → DC validiert Kerberos 
-      │◄─ Session JWT ─────────────│  → Gateway prüft PFX install.id 
-      │                            │ 
-      │  oder:                     │ 
-      │── username/pw + install.id►│  (Szenario C) 
-      │◄─ TOTP-Challenge ──────────│ 
-      │── TOTP-Code ──────────────►│ 
-      │◄─ {access_token, refresh} ─│ 
-      │                            │ 
-      │── refresh_token ──────────►│  (Silent Refresh, Hintergrund) 
-      │◄─ neues access_token ──────│ 
-</code> 
- 
-Extensions bekommen **nie** den Refresh Token. Via IPC (JSON-RPC) fordern Extensions ein scoped Token an — der Shell-''AuthManager'' tauscht das Shell-Token gegen ein Extension-spezifisches Token beim Gateway. 
- 
-Technische Details der Gateway-Endpoints (Kerberos, TOTP, JWT, Refresh): 
-[[de:int:wvdsshell:notes:01-auth-architecture:auth-gateway#neue_endpoints|3. Gateway-Doku: Neue Endpoints]] 
- 
-===== Startup-Phasen-Integration ===== 
- 
-In ''WvdS.Shell.Types.pas'' wird ''spBlockAuth'' eingefügt: 
- 
-<code pascal> 
-TWvdSShellStartupPhase = ( 
-  spBlockStartup,   // Config, Log init 
-  spBlockAuth,      // [WvdS 2026-03-05] PFX-Validation + Identity Provider 
-  spBlockRestore,   // Extension scan, contribution routing 
-  spAfterRestored,  // Activate startup extensions, show UI 
-  spEventually      // Deferred tasks (auto-update check) 
-); 
-</code> 
- 
-Reihenfolge innerhalb von ''spBlockAuth'': 
-  - PFX laden und validieren (Schicht 1) 
-  - PFX-Attribute in Context Keys schreiben (tier, expires, domains, install.id) 
-  - Context-Detector ausführen (Schicht 2) 
-  - Auth-Provider starten (Kerberos / MFA / Offline) 
-  - Auth-Context Keys setzen (state, method, username, mfa) 
-  - Feature-Flags aus ENIVERSASYS via Gateway laden → ''license.features'' setzen 
-  - ''AdvancePhase(spBlockRestore)'' — erst jetzt startet Extension-Scan 
- 
-===== Context Keys nach Auth ===== 
- 
-^ Key                   ^ Werte / Beispiel                             ^ Beschreibung                       ^ 
-| ''auth.state''        | ''authenticated'' / ''pending'' / ''failed'' | Auth-Status                        | 
-| ''auth.mode''         | ''online'' / ''offline''                     | Gateway erreichbar?                | 
-| ''auth.method''       | ''windows'' / ''external''                   | Verwendetes Verfahren              | 
-| ''auth.username''     | UPN oder Benutzername                        | Aktuell angemeldeter User          | 
-| ''auth.mfa''          | ''true'' / ''false''                         | MFA wurde durchgeführt             | 
-| ''license.tier''      | ''professional'' / ''enterprise''            | Aus PFX (.1)                       | 
-| ''license.expires''   | ''2027-01-01''                               | Aus PFX (.2)                       | 
-| ''license.installId'' | ''ENIVERS-2026-001''                         | Aus PFX (.5)                       | 
-| ''license.features''  | ''grids,charts,scheduling''                  | Aus ENIVERSASYS-DB (nach Auth)     | 
- 
-Beispiel-''when''-Clause in einem Extension-Manifest: 
- 
-<code json> 
-"when": "auth.state == authenticated && license.features contains charts" 
-</code> 
- 
-===== Vorgeschlagene Unit-Struktur ===== 
- 
-<code> 
-Security/ 
-  WvdS.Shell.Security.SecretStorage.pas            ← bereits vorhanden (DPAPI) 
-  Auth/ 
-    WvdS.Shell.Auth.Types.pas                      ← Enums, Records, IAuthProvider 
-    WvdS.Shell.Auth.Certificate.pas                ← PFX laden, Kette validieren 
-    WvdS.Shell.Auth.License.pas                    ← Custom-Attributes lesen, Feature-Flags 
-    WvdS.Shell.Auth.ContextDetector.pas            ← Domain-Join + DC-Ping + Gateway-Check 
-    WvdS.Shell.Auth.SessionManager.pas             ← Token-Lifecycle, Silent Refresh, Offline-Retry 
-    Providers/ 
-      WvdS.Shell.Auth.Provider.Kerberos.pas        ← SSPI/Kerberos (Windows-only) 
-      WvdS.Shell.Auth.Provider.External.pas        ← JWT-basiert (HTTP + Gateway) 
-      WvdS.Shell.Auth.Provider.TOTP.pas            ← Challenge-Response Handling 
-      WvdS.Shell.Auth.Provider.Offline.pas         ← PFX-basierter Offline-Pfad 
- 
-GUI/ 
-  WvdS.Shell.GUI.AuthDialog.pas                    ← Nativer Login-Dialog (pre-WebView) 
-  WvdS.Shell.GUI.OfflineBanner.pas                 ← StatusBar-Hinweis im Offline-Modus 
-</code> 
- 
-''WvdS.Shell.Auth.Types'' importiert nur RTL — null Shell-interne Deps, passend zur Schichten-Regel. 
- 
-===== Design-Entscheidungen (protokolliert) ===== 
- 
-^ Thema         ^ Entscheidung                                                              ^ 
-| Multi-Tenant  | Nicht in Phase 1. Single-Tenant-Deployment. Erweiterbar via ''wvds.tenant.*''-Attributes. | 
-| SSPI-Fallback | Kein NTLM-Fallback. 2026 wird Kerberos vorausgesetzt.                     | 
-| Offline-Modus | PFX als Offline-Credential. Dauer bis PFX-Ablauf oder Gateway-Reconnect.  | 
-| PFX-Speicher  | Cert Store (Corpnet/GPO) oder Datei + DPAPI-Passwort (BYOD).              | 
-| SSO           | Out-of-the-box via Kerberos. Kein Benutzereingriff bei Corpnet.           | 
-| CA            | WvdS-interne CA. Root-Cert im Shell-Binary gebündelt.                     | 
  
Zuletzt geändert: den 05.03.2026 um 14:38