6.5 KiB
Checkliste: Microsoft Entra ID — PORTA (OAuth)
Operative Liste: was in der App-Registrierung im Ziel-Tenant (z. B. poweron.swiss) konfiguriert werden muss und welche Gateway-Variablen/Code-Stellen dazu passen.
Hintergrund Konzept Auth- vs. Data-App: z-archive/concepts/OAuth-Auth-vs-Data-Connection-Konzept.md.
Hinweis: App-Registrierungen lassen sich nicht „in einen anderen Tenant verschieben“. Neu im Ziel-Tenant anlegen (oder bewusst Multi-Tenant), Secrets neu erzeugen, Nutzer müssen sich ggf. neu anmelden / Microsoft-Verbindungen neu verbinden.
1) Entra Admin Center — App registration
Azure Portal → Microsoft Entra ID → App registrations → New registration.
- Name: z. B. PowerOn PORTA.
- Supported account types:
- Nur eigener Tenant (Single tenant), oder
- Multitenant — dann passt typisch
Service_MSFT_TENANT_ID = commonzum Authoritylogin.microsoftonline.com/common.
- Redirects werden unter Authentication ergänzt (nächster Abschnitt).
2) Authentication — Redirect URIs (Web)
App registration → Authentication → Platform „Web“ → Redirect URIs.
Pro öffentlich erreichbare Gateway-URL drei URIs (exakt, inkl. Schema):
| URI | Env-Variable / Zweck |
|---|---|
{origin}/api/msft/auth/login/callback |
Service_MSFT_AUTH_REDIRECT_URI (Login) |
{origin}/api/msft/auth/connect/callback |
Service_MSFT_DATA_REDIRECT_URI (User-Daten-Connection) |
{origin}/api/msft/adminconsent/callback |
Admin-Consent-Flow (abgeleitet aus Service_MSFT_DATA_REDIRECT_URI, siehe _admin_consent_redirect_uri() in routeSecurityMsft.py) |
Fehlt die Admin-Consent-URI, scheitert der Flow mit
AADSTS50011: The redirect URI ... does not match— der User sieht "Leider können wir Sie nicht anmelden".
In diesem Repo typische Origins (jeweils alle drei URIs):
- Lokal:
http://localhost:8000 - INT:
https://gateway-int.poweron.swiss - PROD:
https://gateway-prod.poweron.swiss - Forgejo/ALT-Prod (falls genutzt):
https://api.poweron.swiss
Implizite Flow / SPA: für dieses Gateway-Backend-Redirect-Muster nicht nötig (Confidential Client mit Secret).
Backend-Routing: platform-core/modules/routes/routeSecurityMsft.py (Prefix /api/msft).
3) Certificates & secrets
Certificates & secrets → New client secret.
Wert in Service_MSFT_AUTH_CLIENT_SECRET und Service_MSFT_DATA_CLIENT_SECRET eintragen (bei einer App-Registrierung für beide Flows: dieselben Secrets — in den Envs oft identisch).
Verschlüsselung siehe encrypt-env-secrets.md.
4) API permissions (Microsoft Graph — Delegated)
API permissions → Add a permission → Microsoft Graph → Delegated permissions.
Single Source of Truth für die Scope-Liste: platform-core/modules/auth/oauthProviderConfig.py → msftAuthScopes, msftDataScopes
| Zweck | Graph permissions (delegated) |
|---|---|
Login (msftAuthScopes) |
User.Read |
Datenverbindung (msftDataScopes) |
User.Read, Mail.ReadWrite, Mail.Send, Files.ReadWrite.All, Sites.ReadWrite.All, Team.ReadBasic.All, OnlineMeetings.Read, Chat.ReadWrite, ChatMessage.Send, Calendars.Read, Contacts.Read |
Viele dieser Permissions erfordern Administratoreinwilligung im Tenant: Grant admin consent for {tenant}.
Zusätzlicher Flow im Gateway: Admin-Consent-URL unter /api/msft/adminconsent mit Callback …/api/msft/adminconsent/callback (Redirect wird aus Service_MSFT_DATA_REDIRECT_URI abgeleitet — siehe routeSecurityMsft.py). Die Callback-URI muss zwingend unter den Redirect URIs in Abschnitt 2 eingetragen sein.
Multi-Tenant-Apps (TENANT_ID=common): Admin Consent gilt pro Tenant. Ein Admin-Consent durch einen valueon.ch-Admin hat keine Wirkung für pamocreate.com-User. Jeder neue Tenant, der die App nutzt, braucht eine eigene Admin-Zustimmung — entweder durch den Tenant-Admin via /api/msft/adminconsent (im PowerOn-Wizard: "Admin-Zustimmung erteilen") oder durch direkten Aufruf von https://login.microsoftonline.com/{tenant}/v2.0/adminconsent?client_id=.... Solange das fehlt, bekommen User aus diesem Tenant beim Login den "Anforderung gesendet"-Screen.
5) Gateway — Env-Dateien anpassen
| Variable | Bedeutung |
|---|---|
Service_MSFT_AUTH_CLIENT_ID |
Application (client) ID für Login-Flow |
Service_MSFT_AUTH_CLIENT_SECRET |
Client secret (verschlüsselt) |
Service_MSFT_AUTH_REDIRECT_URI |
Muss 1:1 mit Entra Login-Redirect übereinstimmen |
Service_MSFT_DATA_CLIENT_ID |
Application (client) ID für Connect; darf = Auth sein |
Service_MSFT_DATA_CLIENT_SECRET |
Client secret (verschlüsselt) |
Service_MSFT_DATA_REDIRECT_URI |
Muss 1:1 mit Entra Connect-Redirect übereinstimmen |
Service_MSFT_TENANT_ID |
common (Multi-Tenant-Anmeldung) oder Verzeichnis-ID (GUID) des Tenants poweron.swiss für Single-Tenant-Authority |
Dateien (Stand Repo): platform-core/env-gateway-dev.env, env-gateway-int.env, env-gateway-prod.env, env-gateway-prod-forgejo.env, ggf. platform-core/.env.
Wenn neues Frontend oder neuer API-Host:
APP_API_URL— öffentliche Basis des Gateways.APP_ALLOWED_ORIGINS— CORS für das UI.
6) Gateway — Python / Sicherheit (Referenz)
| Datei | Inhalt |
|---|---|
platform-core/modules/auth/oauthProviderConfig.py |
msftAuthScopes, msftDataScopes, msftDataScopesForRefresh |
platform-core/modules/routes/routeSecurityMsft.py |
Login, Connect, Admin-Consent; liest alle Service_MSFT_* |
platform-core/modules/auth/tokenManager.py |
Refresh für Microsoft Data (Service_MSFT_DATA_*, Service_MSFT_TENANT_ID) |
platform-core/modules/auth/csrf.py |
CSRF-Ausnahmen für /api/msft/auth/* und /api/msft/adminconsent* — bei neuen OAuth-Pfaden ggf. erweitern (selten) |
Keine Code-Änderung nötig, solange gleiche Routen und gleiche Scope-Menge wie in oauthProviderConfig.py verwendet werden.
7) Smoke-Tests
- Login mit Microsoft: Rückkehr ohne AADSTS50011 (Redirect mismatch)
- Verbindungen → Microsoft connect/reconnect
- Nach Tenant-Wechsel: Admin Consent im neuen Tenant ausgeführt
- Je nach Feature: Mail, OneDrive/SharePoint, Teams/Chat, Kalender, Kontakte kurz testen