Auth0 ble for dyrt, .NET 8 mente å ha løsningen, men så begynte problemene

– .NET 8s Identity Endpoints virka å løse alle våre problemer, skriver CTO Lars Espen Nordhus, men det var for godt til å være sant.

– Spesielt kravet om skalering til 50.000 brukere kom til å koste utrolig mye med 0Auth, og summen av krav gjorde at vi måtte tenke nytt, skriver Lars Espen Nordhus i Alv. 📸: Alv
– Spesielt kravet om skalering til 50.000 brukere kom til å koste utrolig mye med 0Auth, og summen av krav gjorde at vi måtte tenke nytt, skriver Lars Espen Nordhus i Alv. 📸: Alv Vis mer

Når vi skulle velge autentiseringsløsning for vårt nye prosjekt, tok vi en runde, før vi bestemte oss for å gå for Auth0.

Vi hadde alle jobbet med produktet tidligere og syntes det er lett å bruke og veldig godt dokumentert. Det er en anerkjent teknologi som også kan ha en hyggelig startpris for prosjekter i startfasen, slik som oss.

Utfordringen vår var at vi fort, etter å ha satt opp løsningen og begynt testing, så at dette ikke kom til å bli billig, gitt våre behov. Våre krav til løsningen var:

  • Sosial innlogging med Facebook, Google og andreSoMe
  • Rask skalering til minimum 50.000 brukere
  • Lavedriftskostnader,siden inntjening pr bruker er lav
  • Maskin til maskin autentisering
  • Mikrotjeneste-arkitektur uten «back-end for front-end»
  • Rolleadminsitrasjon
  • En standard løsning basert på OpenIdConnect

Spesielt kravet om skalering til 50.000 brukere kom til å koste utrolig mye med denne løsningen, og summen av krav gjorde at vi måtte tenke nytt.

Vi var imidlertid heldige! .NET 8 hadde akkurat kommet ut, og med det slapp de den nye Identity Endpoints-oppsettet, som virket å løse alle våre problemer.

Enkelt å sette opp

Det eneste man trenger å gjøre, er å legge til disse seksjonene i program.cs-fila, og koble den opp mot databasen du vil bruke for lagring av brukerne dine.

Jeg har brukt sqlite her:

Program.cs
Program.cs Vis mer

For å få satt opp sosial innlogging med Facebook og Google trengs ikke mye kode. Microsoft har laget nuget-pakker for flere SoMe-plattformer og disse gjør ting lett å sette opp. I eksempelet under trenger du bare å bytte ut secret og id med det du får fra dev-sidene deres per app:

image: Auth0 ble for dyrt, .NET 8 mente å ha løsningen, men så begynte problemene

Dette gikk lett og var fort gjort! Men løste det problemet?

Mangler maskin til maskin

La oss ta en nærmere titt på hva .NET 8 gir oss opp mot kravene vi hadde:

  • Sosial innlogging
    Ja, dette er lett og støttet.
  • Rask skalering til 50 000 brukere
    Dette bør være støttet, uten at vi har testet det enda....
  • Lave driftskostnader siden inntjening er lav
    Dette bør være støttet. Løsningen skalerer dynamisk ettersom vi får flere brukere, uten at vi har ytelsestester på dette foreløpig.
  • Rolleadministrasjon
    Løsningen støtterbåde roller og attributter som kan sjekkes i dekoratøren til endepunktet og virker veldig lovende.
  • Maskin til maskin autentisering
    Her begynner problemene. Det finnes ikke noe konsept i løsningen for andre ting enn brukere. Dette fører til at du ikke kan skille på maskiner og brukere, med tanke på levetid på token for eksempel. En annen premium løsning en del støtter, er at maskiner som skal knytte seg til api-ene, kan generere sine egne jwt-access-token ved hjelp av RSA key. Dette gjør at du reduserer lasten på auth-serveren og 3.part system kan bestemme levetiden på token når du lager integrasjoner. Dette er dessverre heller ikke mulig med .NET 8 løsningen slik den er i dag. Dette er upraktisk men ikke en blocker.

Mikrotjeneste-arkitektur uten «back-end for front-end» og en standard løsning basert på OpenId Connect

Løsningen følger ikke OIDC spekk og dette gir også problemer. Det finnes ikke noe konsept om whitelisting av redirect url for innlogging. Det er også problematikk dersom du vil støtte flere domener uten å senke sikkerheten.

SSO kan ikke støttes, siden du ikke har noe måte å verifisere token eller cookie selv på samme domenet uten at alle API får lesetilgang til brukerdatabasen (noe man ikke har lyst til).

Access tokenet som ustedes er ikke på JWT-format som gjør det umulig å verifiseresav andre api-er.

Det finnes ikke noe introspect endepunkt som gir info om tokenet. Dette kunne man laget selv men vil føre til ekstra forsinkelse på alle apikall.

Dersom vi hadde gått for en back-end for front-end, kunne vi kanskje klart oss, og heller hindre all tilgang til mikrotjenestene våre. Dette skaper imidlertid unødvendige avhengigheter i arkitekturen, og det vil vi helst ikke ha.

Prøver heller Keycloak

Jeg er fullt klar over at det er mulig å løse utfordringene ved å gjøre grep som back-end for front-end, lage et endepunkt for introspect på auth server eller utstede egne JWT tokens manuelt, men poenget her var å finne en hyllevare som dekket behovet.

Det er lett å gjøre feil med autentisering og risikofylt å skrive for mye selv, spesielt å gjøre dette i mange språk på tvers.

Alt dette har en betydelig risiko, som vi ikke var villig til å ta. Så dessverre løste ikke .NET 8 mitt behov for denne gang.

Vi har valgt å prøve videre med Keycloak, som hittil virker lovende. Hvem vet, kanskje det kommer en ny blogg om ikke lenge om «hvorfor vi feilet med Keycloak». Stay tuned.