Autentificare și Autorizare
În această secțiune, vom discuta despre autentificare și autorizare. Pentru autentificarea utilizatorilor, vom folosi o schemă simplă de autentificare cu adresa de email și parola, care va returna un jeton (token) folosind standardul JWT (JSON Web Token). JWT-ul este un JSON semnat în format Base64. Generați din swagger-ul proiectul laboratorului JWT-ul pe ruta de login cu user "admin@default.com" și parola "default" pentru a vedea cum arată.
Puteți intra pe jwt.io să-l decodați și veți vedea că JWT-ul are 3 părți în format Base64 despărțite prin ".":
- Header - aici se descrie ce tip este, aici o să fie mereu "JWT" și algoritmul de semnare folosit.
- Payload - aici se pun informațiile utile din JWT numite claim-uri, acestea o să fie folosite pentru identificarea și autorizarea utilizatorului.
- Semnatura - JWT-ul este semnat cu o cheie știută doar de server, din header și payload se generează mai întâi un hash, iar apoi se criptează hash-ul respectiv. Semnatura are ca scop ca JWT-ul să nu poată fi alterat sau să fie falsificat de cineva fără cheia de semnare.
Un exemplu de JWT ar fi următorul:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiI2MTczNjJlMC1iZTlhLTQzOWItOGJiMy02OTlhYzBjNjA3NzMiLCJuYW1lIjoiQWRtaW4iLCJlbWFpbCI6ImFkbWluQGRlZmF1bHQuY29tIiwibmJmIjoxNzA0NjQ5OTI5LCJleHAiOjE3MDUyNTQ3MjksImlhdCI6MTcwNDY0OTkyOSwiaXNzIjoiaHR0cHM6Ly9teS5hcHAiLCJhdWQiOiJodHRwczovL215LmFwcCJ9.TLcWuBxVLIVCta9J0x1Sx8Zi9R26c0OPQdLuKzbuqvE
Cu header:
{
"alg": "HS256",
"typ": "JWT"
}
Și payload:
{
"nameid": "617362e0-be9a-439b-8bb3-699ac0c60773",
"name": "Admin",
"email": "admin@default.com",
"nbf": 1704649929,
"exp": 1705254729,
"iat": 1704649929,
"iss": "https://my.app",
"aud": "https://my.app"
}
Pentru a folosi JWT-ul, acesta trebuie pus în cereri HTTP în header-ul Authorization cu schema de bearer token, adică în formatul "Bearer <jwt>". Din swagger puteți seta token-ul ca "Bearer <jwt>" prin butonul de "Authorize". Ca să protejați diferitele rute din controllere, puteți pune atributul [Authorize] pe rută sau pe întregul controller. Codul din laborator e deja configurat să funcționeze cu această autorizare, doar trebuie să folosiți acel atribut unde aveți nevoie.
Trebuie să știți că JWT nu trebuie să fie legea pentru autorizare; acesta doar trebuie să fie valid și să identifice utilizatorul. Din payload-ul JWT-ului se pot extrage claim-urile, cele standard sunt:
- sub/nameid (subject/name identifier) - de obicei identifică deținătorul JWT-ului pentru care s-a emis, poate fi un ID ca număr sau GUID sau un username.
- iat (issued at) - e amprenta de timp de când a fost emis JWT-ul.
- exp (expires at) - e amprenta de timp când va expira JWT-ul, se poate omite dar un JWT care nu expira este inutil și o breșă de securitate.
- iss (issuer) - autoritatea care a emis JWT-ul, de obicei este numele de domeniu al furnizorului de identitate.
- aud (audience) - audiența țintă pentru care se emite JWT-ul, de obicei este numele de domeniu al aplicației client.
Pe lângă claim-urile standard, se pot adăuga orice alte câmpuri în payload, dar sub/nameid vă sunt suficiente ca să identificați utilizatorul în baza de date cu ce drepturi are acesta. În codul laboratorului, aveți codul cu comentarii ca să vă ajute pentru extragerea claim-urilor și implementarea drepturilor de acces a utilizatorilor personalizate. Folosiți JWT-ul ca să identificați utilizatorul și să vă faceți propria logică de autorizare personalizată acolo unde este nevoie.
Nu vă bazați doar pe informațiile din JWT, acesta nu trebuie să ghideze autorizarea. Dacă includeți prea multe informații în JWT și vă bazați prea mult pe acestea, puteți avea situația când aveți informații neactualizate în JWT față de baza de date, acesta încă fiind valid. Aceste situații pot constitui probleme grave pentru integritatea și securitatea sistemului.