OpenID Connect: autorisation af interne applikationer fra brugerdefineret til standard

For et par måneder siden implementerede jeg en OpenID Connect-server til at administrere adgang til hundredvis af vores interne applikationer. Fra vores egen udvikling, praktisk i mindre skala, er vi gået over til en almindeligt accepteret standard. Adgang gennem den centrale service forenkler i høj grad monotone operationer, reducerer omkostningerne ved at implementere autorisationer, giver dig mulighed for at finde mange færdige løsninger og ikke rack din hjerne, når du udvikler nye. I denne artikel vil jeg tale om denne overgang og de bump, som vi formåede at udfylde.

OpenID Connect: autorisation af interne applikationer fra brugerdefineret til standard

For lang tid siden... Hvordan det hele begyndte

For nogle år siden, da der var for mange interne applikationer til manuel kontrol, skrev vi en applikation til at kontrollere adgangen i virksomheden. Det var en simpel Rails-applikation, der koblede sig til en database med information om medarbejdere, hvor der var konfigureret adgang til forskellige funktioner. Samtidig rejste vi den første SSO, som var baseret på verifikation af tokens fra siden af ​​klienten og autorisationsserveren, tokenet blev transmitteret i krypteret form med flere parametre og verificeret på autorisationsserveren. Dette var ikke den mest bekvemme mulighed, da hver intern applikation skulle beskrive et betydeligt lag af logik, og medarbejderdatabaserne var fuldstændig synkroniseret med autorisationsserveren.

Efter nogen tid besluttede vi at forenkle opgaven med centraliseret autorisation. SSO blev overført til balanceren. Ved hjælp af OpenResty blev der tilføjet en skabelon til Lua, der tjekkede tokens, vidste hvilken applikation anmodningen skulle til og kunne tjekke om der var adgang der. Denne tilgang forenklede i høj grad opgaven med at kontrollere adgangen til interne applikationer - i koden for hver applikation var det ikke længere nødvendigt at beskrive yderligere logik. Det resulterede i, at vi lukkede trafikken eksternt, og selve applikationen vidste ikke noget om autorisation.

Et problem forblev dog uløst. Hvad med applikationer, der har brug for information om medarbejdere? Det var muligt at skrive en API til autorisationstjenesten, men så skulle du tilføje yderligere logik for hver sådan applikation. Derudover ønskede vi at slippe af med afhængigheden af ​​en af ​​vores selvskrevne applikationer, som senere skulle blive oversat til OpenSource, på vores interne autorisationsserver. Vi vil tale om det en anden gang. Løsningen på begge problemer var OAuth.

til fælles standarder

OAuth er en forståelig, generelt accepteret autorisationsstandard, men da kun dens funktionalitet ikke er nok, begyndte de straks at overveje OpenID Connect (OIDC). OIDC i sig selv er den tredje implementering af den åbne godkendelsesstandard, som er strømmet ind i en tilføjelse over OAuth 2.0-protokollen (en åben godkendelsesprotokol). Denne løsning lukker problemet med manglen på data om slutbrugeren, og gør det også muligt at skifte autorisationsudbyder.

Vi valgte dog ikke en specifik udbyder og besluttede at tilføje integration med OIDC til vores eksisterende godkendelsesserver. Til fordel for denne beslutning var det faktum, at OIDC er meget fleksibel med hensyn til slutbrugerautorisation. Det var således muligt at implementere OIDC-understøttelse på din nuværende autorisationsserver.

OpenID Connect: autorisation af interne applikationer fra brugerdefineret til standard

Vores måde at implementere vores egen OIDC-server på

1) Bragte dataene til den ønskede form

For at integrere OIDC er det nødvendigt at bringe de aktuelle brugerdata i en form, der kan forstås af standarden. I OIDC kaldes dette for krav. Påstande er i det væsentlige sidste felter i brugerdatabasen (navn, e-mail, telefon osv.). Eksisterer standardliste over frimærker, og alt, der ikke er inkluderet i denne liste, betragtes som brugerdefineret. Derfor er det første punkt, du skal være opmærksom på, hvis du vil vælge en eksisterende OIDC-udbyder, muligheden for bekvem tilpasning af nye mærker.

Gruppen af ​​kendetegn kombineres i følgende undergruppe - Omfang. Under autorisation anmodes der ikke om adgang til specifikke mærker, men til scopes, selvom nogle af mærkerne fra scopet ikke er nødvendige.

2) Gennemført de nødvendige bevillinger

Den næste del af OIDC integration er udvælgelse og implementering af autorisationstyper, de såkaldte grants. Det yderligere scenarie for interaktion mellem den valgte applikation og autorisationsserveren vil afhænge af den valgte bevilling. En eksemplarisk ordning for valg af det rigtige tilskud er vist i nedenstående figur.

OpenID Connect: autorisation af interne applikationer fra brugerdefineret til standard

Til vores første ansøgning brugte vi den mest almindelige bevilling, autorisationskoden. Dens forskel fra andre er, at det er et tre-trin, dvs. gennemgår yderligere test. Først laver brugeren en anmodning om autorisationstilladelse, modtager et token - Autorisationskode, og derefter med dette token, som med en rejsebillet, anmoder han om et adgangstoken. Al hovedinteraktionen i dette autorisationsscript er baseret på omdirigeringer mellem applikationen og autorisationsserveren. Du kan læse mere om denne bevilling her.

OAuth følger konceptet om, at adgangstokens, der opnås efter godkendelse, skal være midlertidige og bør ændres, helst hvert 10. minut i gennemsnit. Godkendelseskodebevillingen er en tre-trins verifikation gennem omdirigeringer, hvert 10. minut at dreje et sådant trin, ærligt talt, er ikke den mest behagelige opgave for øjnene. For at løse dette problem er der en anden bevilling - Refresh Token, som vi også brugte i vores land. Alt er nemmere her. Under verifikation fra en anden bevilling udstedes der ud over hovedadgangstokenet endnu et - Refresh Token, som kun kan bruges én gang, og dets levetid er normalt meget længere. Med dette Refresh Token, når TTL (Time to Live) for hovedadgangstokenet slutter, vil anmodningen om et nyt adgangstoken komme til endepunktet for en anden bevilling. Det brugte Refresh Token nulstilles øjeblikkeligt. Denne kontrol er to-trins og kan udføres i baggrunden, umærkeligt for brugeren.

3) Konfigurer brugerdefinerede dataoutputformater

Efter at de udvalgte bevillinger er implementeret, virker autorisation, det er værd at nævne at få data om slutbrugeren. OIDC har et separat slutpunkt til dette, hvor du kan anmode om brugerdata med dit nuværende adgangstoken og om det er opdateret. Og hvis brugerens data ikke ændrer sig så ofte, og du skal følge de nuværende mange gange, kan du komme til en løsning som JWT-tokens. Disse tokens understøttes også af standarden. Selve JWT-tokenet består af tre dele: header (information om tokenet), nyttelast (eventuelt nødvendige data) og signatur (signatur, tokenet er underskrevet af serveren, og du kan senere tjekke kilden til dets signatur).

I OIDC-implementeringen kaldes JWT-tokenet id_token. Det kan anmodes om sammen med et almindeligt adgangstoken, og det eneste, der er tilbage, er at bekræfte signaturen. Autorisationsserveren har et separat slutpunkt til dette med en masse offentlige nøgler i formatet J.W.K.. Og når vi taler om dette, er det værd at nævne, at der er et andet endepunkt, som baseret på standarden RFC5785 afspejler den aktuelle konfiguration af OIDC-serveren. Den indeholder alle endepunktsadresser (inklusive adressen på den offentlige nøglering, der bruges til signering), understøttede mærker og scopes, brugte krypteringsalgoritmer, understøttede bevillinger osv.

For eksempel på Google:

{
 "issuer": "https://accounts.google.com",
 "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
 "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
 "token_endpoint": "https://oauth2.googleapis.com/token",
 "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
 "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
 "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
 "response_types_supported": [
  "code",
  "token",
  "id_token",
  "code token",
  "code id_token",
  "token id_token",
  "code token id_token",
  "none"
 ],
 "subject_types_supported": [
  "public"
 ],
 "id_token_signing_alg_values_supported": [
  "RS256"
 ],
 "scopes_supported": [
  "openid",
  "email",
  "profile"
 ],
 "token_endpoint_auth_methods_supported": [
  "client_secret_post",
  "client_secret_basic"
 ],
 "claims_supported": [
  "aud",
  "email",
  "email_verified",
  "exp",
  "family_name",
  "given_name",
  "iat",
  "iss",
  "locale",
  "name",
  "picture",
  "sub"
 ],
 "code_challenge_methods_supported": [
  "plain",
  "S256"
 ],
 "grant_types_supported": [
  "authorization_code",
  "refresh_token",
  "urn:ietf:params:oauth:grant-type:device_code",
  "urn:ietf:params:oauth:grant-type:jwt-bearer"
 ]
}

Ved at bruge id_token kan du således overføre alle de nødvendige kendetegn til tokenets nyttelast og ikke kontakte autorisationsserveren hver gang for at anmode om brugerdata. Ulempen ved denne tilgang er, at ændringen i brugerdata fra serveren ikke kommer med det samme, men sammen med et nyt adgangstoken.

Implementeringsresultater

Så efter at have implementeret vores egen OIDC-server og konfigureret forbindelser til den på applikationssiden, løste vi problemet med at overføre oplysninger om brugere.
Da OIDC er en åben standard, har vi mulighed for at vælge en eksisterende udbyder eller serverimplementering. Vi prøvede Keycloak, som viste sig at være meget praktisk at konfigurere, efter opsætning og ændring af forbindelseskonfigurationer på applikationssiden er den klar til at gå. På applikationssiden er der kun tilbage at ændre forbindelseskonfigurationerne.

Taler om eksisterende løsninger

Inden for vores organisation, som den første OIDC-server, samlede vi vores egen implementering, som blev suppleret efter behov. Efter en detaljeret gennemgang af andre færdige løsninger, kan vi sige, at dette er et problem. Til fordel for beslutningen om at implementere deres egen server var der bekymringer fra udbydernes side i mangel af den nødvendige funktionalitet, samt tilstedeværelsen af ​​et gammelt system, hvor der var forskellige tilpassede autorisationer for nogle tjenester og en hel del af data om medarbejdere allerede var gemt. Men i færdige implementeringer er der bekvemmeligheder for integration. Keycloak har fx sit eget brugerstyringssystem og data gemmes direkte i det, og det vil ikke være svært at overhale dine brugere der. For at gøre dette har Keycloak en API, der giver dig mulighed for fuldt ud at udføre alle de nødvendige overførselshandlinger.

Et andet eksempel på en certificeret, interessant, efter min mening, implementering er Ory Hydra. Det er interessant, fordi det består af forskellige komponenter. For at integrere skal du forbinde din brugeradministrationstjeneste til deres autorisationstjeneste og udvide efter behov.

Keycloak og Ory Hydra er ikke de eneste hyldeløsninger. Det er bedst at vælge en implementering certificeret af OpenID Foundation. Disse løsninger har normalt et OpenID-certificeringsmærke.

OpenID Connect: autorisation af interne applikationer fra brugerdefineret til standard

Glem heller ikke eksisterende betalte udbydere, hvis du ikke ønsker at beholde din OIDC-server. I dag er der mange gode muligheder.

Hvad er næste

I den nærmeste fremtid kommer vi til at lukke trafikken til interne tjenester på en anden måde. Vi planlægger at overføre vores nuværende SSO på balanceren ved hjælp af OpenResty til en proxy baseret på OAuth. Der er allerede mange færdige løsninger her, f.eks.
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Yderligere materialer

jwt.io – god service til validering af JWT-tokens
openid.net/developers/certified - liste over certificerede OIDC implementeringer

Kilde: www.habr.com

Tilføj en kommentar