Multitenant cu autentificare centralizată

Nu e întrebare neaparat de cod exact, ci mai exact de concept, m-am gândit să întreb, poate sunt oameni care au mai multă experienţă ca mine.

Am o aplicaţie multitenant care funcţionează în felul următor:

Este un framework laravel, un singur codebase, un singur server, dar fiecare client are subdomeniul şi baza lui de date independentă.

Până acum era simplu, fiecare user merge la subdomeniul lui, şi se loghează, baza de date e ok, totul banal.

Apoi am avut altă aplicaţie, pe care am mers cu aceeaşi strategie, dar aici am avut nevoie de o pagină de login centralizată, pentru că un client poate avea mai multe instanţe ale aplicaţiei, ceva de genul cum are Infusionsoft dacă ştiţi aplicaţia.

Aici pentru User, din laravel am putut da enforce să folosească mereu baza de date centrală, deci toţi userii sunt în prima instanţă de fapt, se autentifică, şi acolo am un tabel de unde ştiu la care tenants are acces.

Aici am făcut un mini-sistem de autologin, bazat pe hash-uri care se pot folosi o singură dată. După ce te-ai logat, pagina îţi arată la ce instanţe ai acces şi dai click pe ele.

Când dai click, acele linkuri au un hash care de fapt face autologin la instanţa respectivă, după care goleşte hashul. Acesta este regenerat doar atunci când userul trece în altă instanţă şi vrea să revină.

Întrebarea mea este dacă e bună strategia asta, dacă ştiţi altele, în acest context, cu baze de date şi subdomenii separate? Din motive de securitate trebuie să am bazele de date separate, just in case, dar şi pentru că le mai pot muta, distribui pe alte servere, am o mică flexibilitate care o plătesc însă altundeva, ştiu.

Dacă aveţi idei sau alte strategii, mi-ar ajuta pentru că acum trebuie să încep un nou proiect similar.

Nu pot sa ma pronunt cu o solutie concreta, dar poate te ajuta link-ul : https://docs.microsoft.com/en-us/azure/architecture/patterns/

2 Likes

Pare interesant, ceva de genul căutam, patternuri conceptuale să văd ca idee încotro să merg, apoi implementarea nu e problemă, se face.

Care este comportamentul pe care in vrei? Cumva dacă un Iser se logheaza pe ‘a.domain.com’, sa fie considerat logat și pe ‘b.domain.com’? Dar nu pe ‘c.domsin.com’, unde a și b sunt domeniile lui iar c nu?

Exact, vreau să poată sări dintr-un subdomeniu în altul complet transparent.

Mă gândeam să fac o soluție să fie logarea pe domain.com și să setez un cookie pe care îl pot accesa toate subdomeniile. Pe baza acelui cookie pot da acces sau nu.

Dar as prefera să fac asta din session managerul lui laravel, adică laravel să îl vadă logat, fără da hackuiesc inutil, îmi place să fiu cât mai standardizat posibil.

Yup, setarea unui cookie pentru domain.com și toate subdomeniile este o soluție standard. Să te asiguri că e un cookie http-only totuși, și secure de asemenea, că best practice.

Depinde și de ce anume face produsul asta al tau, și care e profilul de atac. De exemplu, dacă lași utilizatorul sa urce un script sau o pagina html care e servit de pe c.domain.com, ai niste cerințe mult mai dure decât dacă e vorba doar de niște interfețe de admin, configurări etc.

Se poate sa fie posibil ceva și cu CORS, dar nu-mi vine în cap configurația corecta ce o poți folosi. Depinde iarăși de cum ai structurat totul și ce poate că e un utilizator.

Trebuie să ai multa grija pe partea de authorization. Deoarece ai aceiași sesiune ptr toate siteurile astea, trebuie sa schimbi conceptualul test isAdmin cu isAdminForThisDomain.


Să pui info de auth in URL sau Hash nu-i asa grozav, că idee de asemenea. URL urile sunt logate pe server in principiu, iar ambele sunt accesibile de către un script malicios. Trebuie pus intr-un side-channel precum cookieuri http only .

1 Like