4.7 KiB
name, description, metadata
| name | description | metadata | ||||||
|---|---|---|---|---|---|---|---|---|
| project-idp-witglobal | PingFederate (WITGLOBAL) als IdP für plato-customer-be — DEV-Konfiguration, BFF-Architektur, Token-Eigenschaften, Test-Rig. |
|
PingFederate (WITGLOBAL) ist der Identity Provider für die Plato-Customer-Applikation.
Architektur (seit Umbau 2026-05-22): Backend-for-Frontend (BFF) — passt zum ursprünglichen IAM-Ticket-Inhalt.
- BE ist OIDC-Client (
openid-clientv6, confidential client mitclient_secret) - BE macht Code-Tausch, behält die Tokens
- FE bekommt nur HTTP-only Session-Cookie via
express-session - FE redirected bei 401 (axios-Interceptor) auf
/auth/login - Auth-Routen:
/auth/login,/oauth/callback,/auth/me,/auth/logout - Lokal: zusätzliche Middleware in
apps/plato-customer-be/src/main.tsfängtGET /mit?code=ab (weil IAM für localhost nur Root-Redirect-URI registriert hat) - Server: saubere
/oauth/callback-Route, keine Root-Middleware nötig - Lokales Cmd: siehe project-run-commands
DEV-Endpoints und Client:
- Issuer:
https://login-dev.witglobal.net - Discovery:
https://login-dev.witglobal.net/.well-known/openid-configuration - Client-ID:
KONZ-PlaTo-Customer-DEV - Client-Secret: aus ENV
OIDC_CLIENT_SECRET(server-side, nie im Browser-Bundle!) - Registrierte Redirect-URIs:
- Lokal:
http://localhost:3000(Root, ohne Pfad — Exact-Match!) - DEV-Server:
https://fahrzeugeinrichtung.apps.ocp-dev01.wgn.wuerth.com/oauth/callback - PROD-Server:
https://fahrzeugeinrichtung.apps.ocp-01.wgn.wuerth.com/oauth/callback
- Lokal:
Token-Eigenschaften (verifiziert 2026-05-22):
access_tokenist ein JWT (RS512), Audience = client_id =KONZ-PlaTo-Customer-DEV- Claims im Access-Token:
scope,client_id,iat,jti,aud,sub,uid,iss,pi.sri,exp - Laufzeit: 3600s
- JWKS-URI:
https://login-dev.witglobal.net/pf/JWKS(wird seit BFF vonopenid-clientintern gehandhabt; nicht mehr direkt nötig)
User-Mapping: Nach erfolgreichem Code-Tausch wird sub (z.B. ex08802409) in libs/command/command-be/src/lib/users/user.json über UserRegistry.getUser() nachgeschlagen. Existiert kein Eintrag → 401. Marcus' Eintrag ex08802409 wurde am 2026-05-22 ergänzt (provisorisch mit marcus.hinz@adesso.de). Eine richtige User-DB ist als nächstes Thema dran (siehe project-cleanup-timeline).
Test-Rig: scripts/oidc-test.mjs — Self-contained Node-Skript (keine Deps), startet HTTP-Server auf :3000, druckt Authorize-URL, fängt Callback, tauscht Code → Token, gibt alles dekodiert aus. Vor Test: Backend stoppen (Port-Konflikt). Aufruf: CLIENT_SECRET='…' node scripts/oidc-test.mjs. ENV überschreibbar: CLIENT_ID, ISSUER, REDIRECT_URI, SCOPES, PORT. Nutzt Self-Issuing-Pattern (war zum Validieren der IdP-Anbindung gedacht, vor BFF-Umbau).
Netz-Exposure / Hardening (verifiziert 2026-05-22): Vorgelagerter Proxy/WAF antwortet ausschließlich auf die definierten OIDC-Pfade (/.well-known/... → 200, /pf/JWKS, /as/authorization.oauth2, /as/token.oauth2). Alles andere — inkl. GET / und HEAD / — wird stillschweigend geblackholed (Connection-Timeout, kein RST, kein 403). Das ist by-design und in Ordnung. Debugging-Falle: Wenn die FE-PWA "trotz nicht erreichbarem IdP läuft", ist das fast immer der Service Worker + gecachte Tokens — nicht eine offene Test-Instanz. Verifikation: DevTools → Application → Clear site data → Hard-Reload. Curl aus kalter Shell ist die ehrliche Antwort auf "ist der Server wirklich offen?".
Gotcha — redirect_uri Trailing-Slash bei lokalem BFF-Flow (gefixt 2026-05-22):
PingFederate validiert redirect_uri beim Token-Tausch byte-exakt gegen den Authorize-Wert; bei DEV ist http://localhost:3000 (ohne Slash) registriert und der IdP normalisiert den Authorize-Wert mit Slash intern wieder auf den registrierten String zurück. openid-client v6 macht beim Token-Tausch aber zwangsweise stripParams(new URL(currentUrl)) → produziert http://localhost:3000/ (WHATWG-URL erzwingt pathname='/') → invalid_grant: redirect_uri value must be identical to the value included in the authorization request. Fix: customFetch-Hook in OidcService.onModuleInit patcht den outgoing URLSearchParams.redirect_uri (Body ist URLSearchParams, NICHT String/Uint8Array) und schneidet den Trailing-Slash ab. Server-Pfad (/oauth/callback) ist davon nicht betroffen.
Offene Punkte:
- Session-Store ist
MemoryStore(express-session default). Für Multi-Pod-Deployment muss Redis o.ä. rein. OIDC_CLIENT_SECRETmuss im Gitops-Repo als Kubernetes-Secret an den Pod gereicht werden.