.NET Api ajutor intelegere OAuth

Salutare, ma chinui de ceva vreme sa inteleg OAuth, iar resursele de pe net nu par a fi de ajutor.

Am inteles ideea cu OAuth, este folosit cand ai nevoie sa accesezi un serviciu in numele utilizatorului, in loc sa dai credentialele tale (username & pwd) serviciului x (api-ul meu), se foloseste acest flow.

Apesi pe login, esti redirectionat la IdP page, esti redirectionat inapoi cu un access token pe care dupa il vei putea da API-ului tau. (aici mai intra si implementarile cu authorization code / PKCE, dar irelevant).

Problema este ca nu inteleg cum poate API-ul tau sa verifice tokenul generat de Azure, Google (Y)… Din ce am gasit pana acum, va trebuie ca API-ului tau sa faca un request cu tokenul la serviciul Y. Pt azure ar fi asta: .AddMicrosoftIdentityWebApi(configuration); ca sa il valideze.

Totusi, nu vazusem peste tot asta in tutoriale? Dar intrebarea este, asa se procedeaza cu orice token din Oauth?

Iar urmatoare intrebare ar fi, daca eu vreau sa am si Oauth si basic auth-ul implementat de mine. Cum va stii API-ului meu cand primeste un token, ce strategie sa foloseasca sa verifice tokenul? Pot adauga mai multe strategii de validare a tokenului la api, dar cum le diferentiaza? Le incearca pe fiecare?

Multumesc, si daca intrebarile mele sunt prea basic, apreciez si niste link-uri in care sa gasesc raspunsurile :slight_smile:

Ai probleme la înțelegerea sau la implementare flow-ului oAuth?

  1. Când configurezi serviciul 3rd party pentru oauth, vei fi întrebat de un endpoint.
  2. userul intră pe aplicația ta → apasă pe „login with [my-oauth-provider]” [^1](google, github etc)
  3. este redirecționat spre pagina provider-ului, unde se autentifică
  4. după ce se autentifică, este redirecționat înapoi în pagina ta pe endpoint-ul configurat la pasul 1, dar cu un token în BODY.

La intelegere.

Da, asta inteleg. Problema se pune mai departe, cand foloseste acel token generat de Google, Azure,…spre api. Cum il valideaza API-ului tau, avand in vedere ca e generat de altcineva?

Validat in sensul de, a te lasa sa accesezi endpointuri care au nevoie de autentificare*

Pe endpoint-ul de auth primești mai multe informații: un token, un client id etc.

Tu folosești token-ul ăla să faci un request extra spre serverul de auth (în backend) să verifici dacă e valid.

Uită-te la github, mi se pare că este explicat mai bine decât la Google. Procesul este asemănător la toți providerii de oAuth (deși nu sunt sigur că obiectul primit este același peste tot).

Multumesc pt raspunsuri, dar cred ca inteleg eu ceva gresit. Da, am inteles ce zice Github, am incercat mai jos sa las o diagrama.

Acel [Authorize] attribute, din .NET verifica JWT-ul pe care i-l dai sa vada daca userul are autorizatie sau nu. Intrebarea este, daca token-ul acesta vine de la GitHub, de unde stie API-ul meu sa ii verifice signature-ul?

Iti faci propriul serviciu de auth (sunt multe optiuni, Keycloak/Authelia/Authentik…), care elibereaza un token pe baza tokenului de la X.

Iti mai trebuie si un serviciu pentru user management, poti sa te bazezi pe auth sau sa faci ceva mai complex.

1 Like

Daca te intereseaza la nivel de implementare, depinde mult de aplicatia ta. Daca ne trimiti tot codul, putem sa ne uitam sa iti explicam.

Daca te intereseaza la nivel inalt, de obicei e cam asa:

  • se foloseste openId (nu doar oAuth)
  • openId are un endpoint https://id-srv/.well-known/openid-configuration. De exemplu: https://accounts.google.com/.well-known/openid-configuration sau https://token.actions.githubusercontent.com/.well-known/openid-configuration
  • aici gasesti jwks_uri care indica locul unde sunt prezentate cheile/algoritmii cu care poti verifica semnatura token-urilor
  • dupa cum stii, un token JWT este compus din mai multe bucati, header/body/semnatura
  • daca semnatura nu poate fi verificata cu nici una din cheile de mai sus, atunci token-ul nu este valid => 401
  • de obicei cheile sunt tinute in cache timp de o zi dar asta poate varia de la implementare la implementare

.NET are un middleware de openId care poate face toate cele de mai sus. Inclusiv flow-urile de authorization code, refresh token, etc.

1 Like

Deci asta nu? Pt google am gasit ca au si ei .AddGoogleOpenIdConnect

Ok, am inteles asta. Va face API-ul meu un request la GOogle/Azure de fiecare data sa valideze tokenul.

Acum ramane, daca vreau si Azure si Google, API-ul va incerca fiecare endpoint sa vada daca valideaza careva tokenul? (Nu e ineficient?)

Mersi, pare util ca sa nu faci handle tu la fiecare serviciu. Dar eu sunt curios cum functioneaza daca vreau eu sa fac asta.

Pai e o mica smecherie la mijloc, o data un certificat eliberat si validat, tu il accepti ca de facto valid cu JWT, nu il mai validezi. L-ai validat cand l-ai setat pe domeniul tau pe FE.

Pai oricine poate sa creeze un JWT cu orice audience/issuer vrea. Ai un link despre asta?

Oricine poate crea un JWT, dar nu de pe orice domeniu.

Daca ai un link, cu cel mai mare drag ma uit. Dar din ce am inteles eu, poti pune orice payload in JWT. Nu poti crede nimic, pana nu verifici signature-ul. Care, cred ca am inteles mai sus, se va face prin alt api call la serviciu Azure/Google, doar apoi iei de buna ce e in payload.

Am gasit asta:
Authorize with a specific scheme in ASP.NET Core | Microsoft Learn
Jos de tot:
options.ForwardDefaultSelector = context =>

^ acolo decizi cum validezi. Dar nu cred ca am vazut asta prin vreun tutorial.

E vreun “schema” pe JWT sau ceva identifier pe care il foloeseste .NET?

Nu chiar, API-ul tau va face cam un request pe zi sa ia lista de chei/certificate care pot valida o semnatura. Serverele astea rotesc cheile la ceva timp din motive de securitate. Dar pastreaza cheile vechi (pentru o perioada de timp) pentru a valida token-urile “in flight”.

Idea e ca un JWT cand e emis, are:

  • header (ce contine tipul token-ului, ce algoritm e folosit la semnare, etc.)
  • un body (ce contine tot felul de claim-uri, acel json)
  • o semnatura

Tu poti sa verifici un JWT ca e valid, verificand semnatura. Semnatura e calculata aplicand niste algoritmi criptografici + o cheie asimetrica peste header si body.

Pe scurt:

  • tu nu poti genera un token valid decat daca ai cheia privata (si nu o ai, pentru ca serverele expun doar cheia publica)
  • tu nu poti modifica un token si sa ramana valid pentru ca semnatura token-ului este strans legata de continutul tokenului. Daca modifici un singur caracter, tokenul devine invalid. (din nou punctul de mai sus, nu ai cheia privata sa generezi o semnatura valida).

Nu e ineficient, pentru ca se intampla local… E destul de rapid sa verifici o semnatura in memorie.

De obicei lumea foloseste providere de autentificare locale. Practic cand dai login with google, iti creezi un user local pe care il marchezi ca a venit din userul cu {id: x, provider: google}. Dar se face asta de obicei ca sa nu depinzi de 3rd parties. De exemplu daca vrei sa renunti la google din varii motive, poti sa lasi userul sa-si creeze o parola. In cazul asta tu folosesti doar o schema de autentificare. Provider-ul extern e folosit doar pentru auto-provisioning + login cu schema ta.

Am vazut ca tot mai multi scot “Login with Facebook”

Apropo, e opensource codul. Mi-am batut capul de multe ori cu el la lucru. Si noi folosim DuendeIdentityServer si avem ca external login provider AAD.

Gasesti aici toti pasii de care ziceam:

2 Likes

Ok, banuiesc ca prin lista de chei te referi la secretkey (n are cum sa fie secretkey ca ar fi exploited atunci), poate un caching ceva la jwt-urile verificate, sa faci criptarea la JWT header si payload sa verifici semnatura. Daca e asa, intr-adevar nu se pune problema de eficienta.

De acord si cu restul punctelor. Mersi mult, am inteles :slight_smile:

Atentie, cheile/certificatele expuse de OpenId nu sunt aceleasi folosite de TLS. Desi chain of trust este prin SSL/TLS, deoarece le obtii printr-un GET.

Adica accepti cheile de verificare semnaturi JWT, pentru ca le obtii de pe un domeniu cunoscut, printro conexiune securizata de un certificat emis pentru acel domeniu.

@andrei-tatar gata, cu ce ai zis tu am inteles. confuzia era in symmetric vs asymmetric encryption. eu implementasem pana acum doar symmetric encryption, si nu avea sens acum are.

authentication - Is it possible to validate a JWT token without having the secret key? - Stack Overflow

Acolo explica foarte bine daca s-o mai gasi cineva interesat.

1 Like

Exista servicii foarte usor de integrat precum:
Clerk | Authentication and User Management
A new era of authentication - Kinde

.NET SDK - Developer tools - Help center - Kinde