OpenID Connect: autorisasjon av interne applikasjoner fra tilpasset til standard

For noen måneder siden implementerte jeg en OpenID Connect-server for å administrere tilgang for hundrevis av våre interne applikasjoner. Fra vår egen utvikling, praktisk i mindre skala, har vi gått over til en allment akseptert standard. Tilgang gjennom den sentrale tjenesten forenkler monotone operasjoner i stor grad, reduserer kostnadene ved å implementere autorisasjoner, lar deg finne mange ferdige løsninger og ikke racke hjernen din når du utvikler nye. I denne artikkelen vil jeg snakke om denne overgangen og støtene som vi klarte å fylle.

OpenID Connect: autorisasjon av interne applikasjoner fra tilpasset til standard

For lenge siden... Hvordan det hele begynte

For noen år siden, da det var for mange interne applikasjoner for manuell kontroll, skrev vi en applikasjon for å kontrollere tilgang innad i selskapet. Det var en enkel Rails-applikasjon som koblet til en database med informasjon om ansatte, hvor tilgang til diverse funksjonalitet ble konfigurert. Samtidig hevet vi den første SSO, som var basert på verifisering av tokens fra siden av klienten og autorisasjonsserveren, tokenet ble overført i kryptert form med flere parametere og verifisert på autorisasjonsserveren. Dette var ikke det mest praktiske alternativet, siden hver intern applikasjon måtte beskrive et betydelig lag med logikk, og ansattes databaser var fullstendig synkronisert med autorisasjonsserveren.

Etter en tid bestemte vi oss for å forenkle oppgaven med sentralisert autorisasjon. SSO ble overført til balansereren. Ved hjelp av OpenResty ble det lagt til en mal til Lua som sjekket tokens, visste hvilken applikasjon forespørselen skulle til, og kunne sjekke om det var tilgang der. Denne tilnærmingen forenklet i stor grad oppgaven med å kontrollere tilgang til interne applikasjoner - i koden til hver applikasjon var det ikke lenger nødvendig å beskrive ytterligere logikk. Det førte til at vi stengte trafikken eksternt, og selve applikasjonen visste ikke noe om autorisasjon.

Ett problem forble imidlertid uløst. Hva med applikasjoner som trenger informasjon om ansatte? Det var mulig å skrive en API for autorisasjonstjenesten, men da måtte du legge til ekstra logikk for hver slik applikasjon. I tillegg ønsket vi å bli kvitt avhengigheten av en av våre selvskrevne applikasjoner, som senere skulle bli oversatt til OpenSource, på vår interne autorisasjonsserver. Vi skal snakke om det en annen gang. Løsningen på begge problemene var OAuth.

til felles standarder

OAuth er en forståelig, allment akseptert autorisasjonsstandard, men siden bare funksjonaliteten ikke er nok, begynte de umiddelbart å vurdere OpenID Connect (OIDC). OIDC i seg selv er den tredje implementeringen av den åpne autentiseringsstandarden, som har strømmet inn i et tillegg over OAuth 2.0-protokollen (en åpen autorisasjonsprotokoll). Denne løsningen lukker problemet med mangel på data om sluttbrukeren, og gjør det også mulig å endre autorisasjonsleverandør.

Vi valgte imidlertid ikke en spesifikk leverandør og bestemte oss for å legge til integrasjon med OIDC for vår eksisterende autorisasjonsserver. Til fordel for denne avgjørelsen var det faktum at OIDC er svært fleksibel når det gjelder sluttbrukerautorisasjon. Dermed var det mulig å implementere OIDC-støtte på din nåværende autorisasjonsserver.

OpenID Connect: autorisasjon av interne applikasjoner fra tilpasset til standard

Vår måte å implementere vår egen OIDC-server på

1) Brakt dataene til ønsket form

For å integrere OIDC er det nødvendig å bringe gjeldende brukerdata i en form som er forståelig av standarden. I OIDC kalles dette krav. Krav er i hovedsak endelige felt i brukerdatabasen (navn, e-post, telefon osv.). Finnes standard frimerkeliste, og alt som ikke er inkludert i denne listen regnes som tilpasset. Derfor er det første punktet du må ta hensyn til hvis du vil velge en eksisterende OIDC-leverandør muligheten for praktisk tilpasning av nye merker.

Gruppen av kjennetegn er kombinert i følgende undergruppe - Omfang. Under autorisasjon bes det om tilgang ikke til spesifikke merker, men til scopes, selv om noen av merkene fra scope ikke er nødvendig.

2) Gjennomført nødvendige tilskudd

Den neste delen av OIDC-integrasjonen er valg og implementering av autorisasjonstyper, såkalte grants. Det videre scenariet for interaksjon mellom den valgte applikasjonen og autorisasjonsserveren vil avhenge av den valgte bevilgningen. En eksemplarisk ordning for valg av riktig tilskudd er vist i figuren under.

OpenID Connect: autorisasjon av interne applikasjoner fra tilpasset til standard

For vår første søknad brukte vi det vanligste tilskuddet, autorisasjonskoden. Dens forskjell fra andre er at det er et tre-trinn, dvs. gjennomgår ytterligere testing. Først sender brukeren en forespørsel om autorisasjonstillatelse, mottar et token - Autorisasjonskode, og ber deretter om et tilgangstoken med dette tokenet, som med en reisebillett. All hovedinteraksjonen til dette autorisasjonsskriptet er basert på omdirigeringer mellom applikasjonen og autorisasjonsserveren. Du kan lese mer om dette tilskuddet her.

OAuth følger konseptet om at tilgangstokener som oppnås etter autorisasjon bør være midlertidige og endres helst hvert 10. minutt i gjennomsnitt. Autorisasjonskodebevilgningen er en tre-trinns bekreftelse gjennom omdirigeringer, hvert 10. minutt for å snu et slikt trinn, ærlig talt, er ikke den mest behagelige oppgaven for øynene. For å løse dette problemet er det et annet tilskudd - Refresh Token, som vi også brukte i vårt land. Alt er lettere her. Under verifisering fra en annen bevilgning, i tillegg til hovedtilgangstokenet, utstedes en annen - Refresh Token, som bare kan brukes én gang og levetiden er vanligvis mye lengre. Med dette Refresh Token, når TTL (Time to Live) for hovedtilgangstokenet slutter, vil forespørselen om et nytt tilgangstoken komme til endepunktet for en annen bevilgning. Det brukte Refresh-tokenet tilbakestilles umiddelbart til null. Denne kontrollen er to-trinns og kan utføres i bakgrunnen, umerkelig for brukeren.

3) Sett opp tilpassede datautdataformater

Etter at de valgte tilskuddene er implementert fungerer autorisasjonen, det er verdt å nevne å få data om sluttbrukeren. OIDC har et eget endepunkt for dette, hvor du kan be om brukerdata med ditt nåværende tilgangstoken og om det er oppdatert. Og hvis brukerens data ikke endres så ofte, og du må følge de gjeldende mange ganger, kan du komme til en slik løsning som JWT-tokens. Disse tokenene støttes også av standarden. Selve JWT-tokenet består av tre deler: header (informasjon om tokenet), nyttelast (evt. nødvendig data) og signatur (signatur, tokenet er signert av serveren og du kan senere sjekke kilden til signaturen).

I OIDC-implementeringen kalles JWT-tokenet id_token. Det kan bes om sammen med en vanlig tilgangstoken og alt som gjenstår er å bekrefte signaturen. Autorisasjonsserveren har et eget endepunkt for dette med en haug med offentlige nøkler i formatet J.W.K.. Og når vi snakker om dette, er det verdt å nevne at det er et annet endepunkt, som basert på standarden RFC5785 gjenspeiler gjeldende konfigurasjon av OIDC-serveren. Den inneholder alle endepunktadresser (inkludert adressen til den offentlige nøkkelringen som brukes til signering), støttede merker og omfang, brukte krypteringsalgoritmer, støttede tilskudd, etc.

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 å bruke id_token kan du dermed overføre alle nødvendige kjennetegn til nyttelasten til tokenet og ikke kontakte autorisasjonsserveren hver gang for å be om brukerdata. Ulempen med denne tilnærmingen er at endringen i brukerdata fra serveren ikke kommer umiddelbart, men sammen med et nytt tilgangstoken.

Implementeringsresultater

Så, etter å ha implementert vår egen OIDC-server og konfigurert tilkoblinger til den på applikasjonssiden, løste vi problemet med å overføre informasjon om brukere.
Siden OIDC er en åpen standard, har vi muligheten til å velge en eksisterende leverandør eller serverimplementering. Vi prøvde Keycloak, som viste seg å være veldig praktisk å konfigurere, etter å ha satt opp og endret tilkoblingskonfigurasjoner på applikasjonssiden, er den klar til bruk. På applikasjonssiden gjenstår det bare å endre tilkoblingskonfigurasjonene.

Snakker om eksisterende løsninger

Innenfor vår organisasjon, som den første OIDC-serveren, satte vi sammen vår egen implementering, som ble supplert etter behov. Etter en detaljert gjennomgang av andre ferdige løsninger kan vi si at dette er et omstridt poeng. Til fordel for beslutningen om å implementere sin egen server var det bekymringer fra leverandørene i mangel av nødvendig funksjonalitet, samt tilstedeværelsen av et gammelt system der det var forskjellige tilpassede autorisasjoner for noen tjenester og ganske mye av data om ansatte var allerede lagret. Men i ferdige implementeringer er det bekvemmeligheter for integrasjon. Keycloak har for eksempel et eget brukerstyringssystem og data lagres direkte i det, og det vil ikke være vanskelig å overkjøre brukerne dine der. For å gjøre dette har Keycloak en API som lar deg utføre alle nødvendige overføringshandlinger.

Et annet eksempel på en sertifisert, interessant, etter min mening, implementering er Ory Hydra. Det er interessant fordi det består av forskjellige komponenter. For å integrere, må du koble brukeradministrasjonstjenesten til deres autorisasjonstjeneste og utvide etter behov.

Keycloak og Ory Hydra er ikke de eneste hylleløsningene. Det er best å velge en implementering sertifisert av OpenID Foundation. Disse løsningene har vanligvis et OpenID-sertifiseringsmerke.

OpenID Connect: autorisasjon av interne applikasjoner fra tilpasset til standard

Ikke glem eksisterende betalte leverandører hvis du ikke vil beholde OIDC-serveren din. I dag er det mange gode alternativer.

Hva er neste

I nær fremtid skal vi stenge trafikk til interne tjenester på en annen måte. Vi planlegger å overføre vår nåværende SSO på balanseren ved hjelp av OpenResty til en proxy basert på OAuth. Det finnes allerede mange ferdige løsninger her, for eksempel:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Ytterligere materialer

jwt.io – god service for validering av JWT-tokens
openid.net/developers/certified - liste over sertifiserte OIDC-implementeringer

Kilde: www.habr.com

Legg til en kommentar