Den kompletta guiden till att integrera en OIDC-server i ditt projekt
Lär dig bästa praxis för att integrera en OIDC (OpenID Connect) server i ditt projekt och förstå hur komponenter interagerar med varandra på scenen.
Du kan hamna i en situation där du behöver ett centraliserat autentiserings- och auktorisationssystem, dvs. identitetsåtkomsthantering (IAM) eller identitetsleverantör (IdP). Ibland lägger folk till ett ord för att ange affärsområdet, såsom Kund-IAM och Arbetskrafts-IAM.
Låt oss lägga dessa fina namn åt sidan för ett ögonblick. Behovet av IAM kan uppstå eftersom din applikation växer, eller att du planerar att delegera det hårda arbetet till en leverantör från början. I vilket fall som helst når du en punkt där ett identitetssystem behöver introduceras i ditt projekt.
Med tanke på populariteten för OAuth 2.0 är OpenID Connect (OIDC) ett naturligt val för många utvecklare. Eftersom OIDC är ett autentiseringslager som byggs ovanpå OAuth 2.0 kan du känna dig bekant när du börjar arbeta med OIDC. Låt oss sätta igång!
Vad är en OIDC-server och varför ska jag integrera OIDC-server?
En OIDC-server, eller identitetsleverantör, är ett centraliserat system som hanterar användarautentisering och auktorisering. Som vi diskuterade i Varför du behöver ett centraliserat identitetssystem för en multi-app-verksamhet, har ett centraliserat identitetssystem många fördelar.
Låt oss säga att ditt projekt börjar med en enkel webbapplikation, och det har inbyggd autentisering:
När ditt projekt växer, behöver du introducera en mobilversion:
Det blir en dålig upplevelse för användare om de behöver skapa ett konto för varje applikation. Eftersom du började med en webbapplikation, låter du mobilapplikationen kommunicera med webbapplikationen för autentisering:
Nu introduceras en ny API-tjänst. Eftersom det är en tjänst för betalande användare, behöver du försäkra dig om att användaren är autentiserad och auktoriserad att få tillgång till tjänsten. För att uppnå detta kan du proxyera tjänsten genom webbapplikationen:
Eller, använd någon tokenteknik för att autentisera användaren, och validera token genom att prata med webbapplikationen i tjänsten. Så att mobilapplikationen kan använda tjänsten direkt:
Saker och ting börjar bli rörigt. Så du bestämmer dig för att bryta ut autentiserings- och auktoriseringslogiken i en separat tjänst:
Refaktoringsprocessen kan vara smärtsam. Du kanske märker att komplexiteten ökar exponentiellt när du lägger till fler applikationer och tjänster till projektet. Ännu värre kan vara att du behöver upprätthålla flera autentiseringsmetoder såsom lösenordsfri inloggning, social inloggning, SAML, etc.
Detta är anledningen till att vi helst skulle introducera en identitetsleverantör i början när du planerar att skala ditt projekt.
Bästa praxis för att integrera en OIDC-server
Hitta en OIDC-leverantör
Det finns många OIDC-leverantörer tillgängliga på marknaden. Du kan välja en baserat på dina krav och preferenser. Så länge leverantören följer OIDC-standarder, kommer den att spela samma roll i ditt projekt.
Vad betyder ”subject”, ”client” och ”audience” i OIDC?
För att förenkla konceptet kan vi tänka oss att subject är den enhet som begär tillgång till en audience via en client.
Låt oss se några typiska scenarier:
1. En användare klickar på inloggningsknappen på en webbapplikation
I en traditionell webbapplikation med serverrendering är frontend och backend sammanflätade. Låt oss säga att webbapplikationen serverar både frontend och backend:
- Subject: Användaren
- Audience: OIDC-servern
- Client: Webbapplikationen
Det kan verka motsägelsefullt att audience är OIDC-servern. Faktum är att det är nyckeln till att realisera SSO (Single Sign-On) upplevelsen f ör slutanvändare. Låt oss se ett förenklat sekvensdiagram för auktoriseringskodflöde:
code
är en engångskod som kan bytas mot olika tokens, såsom access token, ID-token och refresh token. Det är okej om du inte förstår alla dessa tokens just nu. När vi fortsätter kommer du att få en bättre förståelse för dem.
I ovanstående fall behöver användaren inte logga in igen när de byter till en annan applikation eftersom användaren (subject) redan har autentiserats med OIDC-servern (audience).
2. En användare använder en enkel-sidesapplikation
I en enkel-sidesapplikation (eller en mobilapplikation) är frontend och backend separerade. Låt oss säga att backend är en API-tjänst:
- Subject: Användaren
- Audience: API-tjänsten
- Client: Den enkel-sidesapplikationen (SPA)
Ett förenklat sekvensdiagram med auktoriseringskodflöde:
Eftersom API-tjänsten är icke-interaktiv, måste SPA använda access token med API-tjänsten som audience (den aud
i token).
Varför är OIDC-servern fortfarande en audience?
Tekniskt kan du ta bort OIDC-servern från audience-listan. Eftersom du i de flesta fall behöver användarinformation från OIDC-servern (som kräver att OIDC-servern är en audience), är det bättre att alltid inkludera OIDC-servern i audience-listan när det innebär användarinteraktion.
Vänta, säger du att vi kan ha flera audience i en auktoriseringsbegäran?
Exakt! Kom ihåg att OIDC är byggt ovanpå OAuth 2.0, det är möjligt att använda RFC 8707: Resource Indicators for OAuth 2.0 i auktorisationsbegäran för att specificera flera audience. Det kräver stöd både från grant och OIDC-servern. Logto stödjer denna funktionalitet naturligt.
3. En maskin-till-maskin kommunikation
Låt oss säga att du har en tjänst A som behöver kalla tjänst B:
- Subject: Tjänst A
- Audience: Tjänst B
- Client: Tjänst A
Ett förenklat sekvensdiagram med klientuppgifter grant:
När tjänst B behöver kalla tjänst A byts rollerna helt enkelt.
Sammanfattning
- Subject: Det kan vara en användare, en tjänst, eller vilken enhet som helst som behöver få tillgång till audience.
- Client: Det kan vara en webbapplikation, en mobilapplikation, eller vilken enhet som helst som initierar begäran eller agerar på subjektets vägnar.
- Audience: Det kan vara en tjänst, ett API, eller vilken enhet som helst som tillhandahåller tillgång till subjektet.
Vad är access tokens, ID tokens och refresh tokens?
Det finns tre typer av tokens du kan stöta på när du arbetar med OIDC:
- Access token: Den används för att få tillgång till audience. Den kan vara en JWT (JSON Web Token) eller en ogenomskinlig token (vanligtvis en slumpmässig sträng).
- ID token: En OIDC-specifik token som innehåller användarinformation. Den är alltid en JWT. Klienten kan avkoda token för att få användarinformation.
- Refresh token: Den används för att få en ny uppsättning tokens när access token eller ID-token går ut.
För en detaljerad förklaring av dessa tokens kan du referera till Förståelse av refresh tokens, access tokens och ID tokens i OIDC-protokollet.
I ovanstående scenario 1 och 2 syftar termen auktoriseringsbegäran på en begäran om att få en uppsättning tokens via ett specifikt grant.
När allt går bra, kommer en uppsättning tokens att returneras i steget "Byt tokens med code
". De tillgängliga tokens i uppsättningen beror på flera faktorer, särskilt scope
-parametern i auktoriseringsbegäran. För enkelhetens skull antar vi att alla tokens returneras i uppsättningen. När access token går ut, kan klienten använda refresh token för att få en ny uppsättning tokens utan användarinteraktion.
För scenario 3 är det enklare eftersom klientuppgifter grant endast returnerar en access token.
Hur hantera flera audience i OIDC?
Du kanske märker att bara en access token returneras åt gången. Hur skulle vi hantera fallet där klienten behöver få tillgång till flera audience?
Det finns två vanliga lösningar:
Specificera resource
i kodbytarbegäran
När klienten byter kod mot tokens kan den specificera en resource
-parameter i begäran. OIDC-servern returnerar en access token för den specificerade audience om det är tillämpligt.
Här är ett icke-normativt exempel:
Då kommer OIDC-servern returnera en access token för API_SERVICE
audience, om det är tillämpligt.
Använd en refresh token för att få en ny access token
Med RFC 8707 kan klienten till och med specificera flera audience genom att använda resource
-parametern flera gånger. Nu, om refresh tokens är tillgängliga i klienten, kan klienten specificera audience i resource
-parametern när den uppdaterar token.
Här är ett icke-normativt exempel:
Det har samma effekt som den tidigare lösningen. Samtidigt är andra tilldelade audience fortfarande tillgängliga i framtida tokenbegäranden.
Klientuppgifter grant
Du kan också använda resource
-parametern i klientuppgifter grant för att specificera audience. Det finns inget problem med flera audience i denna grant eftersom du alltid kan begära en ny access token för en annan audience genom helt enkelt att skicka en annan tokenbegäran.
Skydda din API-tjänst
"API-tjänsten" i scenario 2 och "Tjänst B" i scenario 3 har en sak gemensamt: de behöver validera access token för att avgöra om begäran är auktoriserad. Beroende på formatet på access token kan valideringsprocessen variera.
- Ogenomskinlig token: API-tjänsten behöver anropa OIDC-servern för att validera token. Ett introspektionsendpoint tillhandahålls vanligtvis av OIDC-servern för detta ändamål.
- JWT: API-tjänsten kan validera token lokalt genom att kontrollera signaturen och anspråken i token. OIDC-servern tillhandahåller vanligtvis en JSON Web Key Set (JWKS) endpoint (
jwks_uri
) för API-tjänsten att få den offentliga nyckeln för att verifiera signaturen.
Om du är ny på JWT kan du referera till Vad är JSON Web Token (JWT)?. I själva verket är det vanligtvis inte nödvändigt att validera signaturen och kontrollera anspråken manuellt eftersom det finns många bibliotek som kan göra det åt dig, såsom jose för Node.js och webbläsare.
Kontrollera anspråk
Förutom att validera JWT-signaturen bör API-tjänsten alltid kontrollera anspråken i token:
iss
: Utgivaren av token. Den ska matcha OIDC-serverns utgivar-URL.aud
: Audience för token. Den ska matcha API-tjänstens audience värde (vanligtvis en giltig URI).exp
: Utgångstiden för token. API-tjänsten bör avvisa token om det har gått ut.scope
: Omfånget (tillåtelse) för token. API-tjänsten ska kontrollera om det erforderliga omfånget är närvarande i token.
Andra anspråk, såsom sub
(subject) och iat
(utfärdad vid), är också viktiga i vissa fall. Om du har ytterligare säkerhetsåtgärder, kontrollera anspråken i enlighet därmed.
Auktorisering
En obesvarad fråga kvarstår där ute: Hur avgör vi om ett scope (dvs. tillåtelse) kan beviljas till ett subject?
Den enskilda frågan leder till en helt ny värld av auktorisering, som ligger utanför artikelns räckvidd. Kort sagt finns det några vanliga tillvägagångssätt som RBAC (Role-Based Access Control) och ABAC (Attribute-Based Access Control). Här är några resurser för att komma igång:
- RBAC och ABAC: De åtkomstkontrollmodeller du bör känna till
- Behärska RBAC i Logto: Ett omfattande verklighetsbaserat exempel
Avslutande anteckningar
Att införa en OIDC-server i ditt projekt är ett stort steg. Det kan avsevärt förbättra säkerheten och skalbarheten i ditt projekt. Samtidigt kan det ta lite tid att förstå koncepten och interaktionerna mellan komponenterna.
Att välja en bra OIDC-leverantör som passar dina krav och preferenser kan märkbart minska komplexiteten i integrationsprocessen, eftersom leverantören vanligtvis erbjuder hela paketet, inklusive OIDC-servern, auktoriseringsmekanismer, SDKs och de företagsfunktioner du kan behöva i framtiden.
Jag hoppas att denna guide hjälper dig att förstå grunderna för att integrera en OIDC-server. Om du letar efter en att börja med, skulle jag själviskt rekommendera Logto, vår identitetsinfrastruktur för utvecklare.