Auth-flow
Dyb gennemgang af hvordan Ressourcify autentificerer og autoriserer brugere via Microsoft Entra ID.
Ressourcify bruger NextAuth v5 med Microsoft Entra ID som eneste identitets-provider. Sessioner er stateless via JWT — der er ingen session-tabel i databasen.
De fire deltagere
| Komponent | Rolle |
|---|---|
| Browser | Sender request, opbevarer JWT-cookie |
| Next.js | Validerer, kalder Entra, læser DB |
| Microsoft Entra ID | Identitets-provider, udsteder ID-tokens |
| Postgres | Kilde til brugere og roller |
Komplet flow ved første login
De tre callbacks
signIn — kører ved hvert login
Ansvarlig for at oprette/opdatere brugeren og synkronisere roller fra Entra-grupper.
Vi bruger profile.oid som stabil identifier — ikke email. Email kan
ændres i Entra, men oid er forevigt fastsat ved oprettelse af kontoen.
jwt — kører ved hvert request der har en JWT
Holder JWT-payload'en minimal — kun oid så vi kan slå brugeren op senere.
JWT'en lever i cookien, ikke i databasen. Den er signeret med
AUTH_SECRET (HMAC). Hvis cookien manipuleres, fejler signaturen og
NextAuth afviser den.
session — kører hver gang auth() kaldes i en handler
Beriger session-objektet med fersk data fra databasen.
Rolle-ændringer træder i kraft ved næste session-callback — det er ofte
få sekunder, ikke ved næste login. Gruppe-ændringer i Entra kræver
derimod nyt login, fordi signIn kun læser grupperne én gang.
Session-konfiguration
| Indstilling | Værdi | Hvorfor |
|---|---|---|
strategy | "jwt" | Stateless — ingen session-tabel |
maxAge | 60 * 60 * 12 (12t) | Én arbejdsdag |
| Cookie-navn | __Secure-next-auth.session-token | Secure-flag i produktion |
| Cookie-attr | HttpOnly, SameSite=Lax | XSS- og CSRF-modstand |
Re-login efter de 12 timer går silent via Entra hvis brugeren stadig er logget ind på Microsoft — typisk usynligt for brugeren.
Adgangskontrol efter login
Den autentificerede session er kun det første lag. Hver route-handler
laver yderligere et can()-tjek:
Se RBAC-matrix for hvem der må hvad.
Konfiguration
Entra-config læses ved hver kald via getEntraConfig(orgId). Først tjekkes
DB (EntraConfig-tabel) — ellers falder den tilbage til miljøvariable:
| Env-variabel | DB-felt | Beskrivelse |
|---|---|---|
AUTH_MICROSOFT_ENTRA_ID_TENANT_ID | tenantId | |
AUTH_MICROSOFT_ENTRA_ID_ID | clientId | App-registreringens client-ID |
AUTH_MICROSOFT_ENTRA_ID_SECRET | clientSecretEncrypted | Krypteret med ENCRYPTION_KEY |
ENTRA_GROUP_USERS | groupUsersId | Adgangs-gate |
ENTRA_GROUP_ORG_ADMIN | groupOrgAdminId | |
ENTRA_GROUP_DEPT_ADMIN | groupDeptAdminId | |
ENTRA_GROUP_COORDINATOR | groupCoordinatorId |
DB-versionen er den foretrukne for produktion — clientSecret ligger
aldrig i klartekst, og admins kan rotere den via UI.
Sikkerhedsegenskaber
| Egenskab | Hvordan |
|---|---|
| Single sign-on | Entra håndterer credentials — Ressourcify ser dem aldrig |
| Lockout, MFA | Konfigureret i Entra |
| Replay-modstand | OIDC-nonce valideres af NextAuth |
| Token-manipulation | JWT signeres med AUTH_SECRET; modificerede tokens afvises |
| Brute-force | Login-endpoint findes ikke i Ressourcify — al login går via Entra |
| Privilegium-eskalering | signIn skriver kun ORG-scope-roller; DEPT/TEAM kræver manuel admin-handling |
Hvad sker når brugeren logger ud
Klik på navn → Log ud:
- Browser sender
POST /api/auth/signout - NextAuth sletter session-cookien
- Audit-event
LOGOUTskrives - Browser redirectes til login-siden
Bemærk: brugeren er stadig logget ind på Microsoft. Hvis de besøger
appen igen, går de tilbage via silent SSO. For at logge ud af Microsoft
helt skal de gå til login.microsoftonline.com.