OpenID Connect: autorisatie van interne applicaties van maatwerk naar standaard

Een paar maanden geleden implementeerde ik een OpenID Connect-server om de toegang voor honderden van onze interne applicaties te beheren. Vanuit onze eigen ontwikkelingen, handig op kleinere schaal, zijn we overgegaan naar een algemeen geaccepteerde standaard. Toegang via de centrale service vereenvoudigt eentonige operaties aanzienlijk, vermindert de kosten van het implementeren van autorisaties, stelt u in staat om veel kant-en-klare oplossingen te vinden en uw hersens niet te pijnigen bij het ontwikkelen van nieuwe. In dit artikel zal ik het hebben over deze overgang en de hobbels die we hebben weten op te vullen.

OpenID Connect: autorisatie van interne applicaties van maatwerk naar standaard

Lang geleden... Hoe het allemaal begon

Enkele jaren geleden, toen er te veel interne applicaties waren voor manuele controle, schreven we een applicatie om de toegang binnen het bedrijf te controleren. Het was een eenvoudige Rails-applicatie die verbinding maakte met een database met informatie over medewerkers, waar de toegang tot verschillende functionaliteiten werd geconfigureerd. Tegelijkertijd brachten we de eerste SSO op, die was gebaseerd op de verificatie van tokens van de kant van de client en de autorisatieserver, het token werd in gecodeerde vorm verzonden met verschillende parameters en geverifieerd op de autorisatieserver. Dit was niet de handigste optie, aangezien elke interne applicatie een flinke laag logica moest beschrijven en de medewerkersdatabases volledig gesynchroniseerd waren met de autorisatieserver.

Na enige tijd hebben we besloten om de taak van gecentraliseerde autorisatie te vereenvoudigen. SSO is overgedragen aan de balancer. Met behulp van OpenResty werd een sjabloon aan Lua toegevoegd dat tokens controleerde, wist naar welke applicatie het verzoek ging en kon controleren of daar toegang was. Deze benadering vereenvoudigde de taak van het controleren van de toegang tot interne applicaties aanzienlijk - in de code van elke applicatie was het niet langer nodig om aanvullende logica te beschrijven. Als gevolg hiervan hebben we het verkeer extern afgesloten en wist de applicatie zelf niets van autorisatie.

Eén probleem bleef echter onopgelost. Hoe zit het met applicaties die informatie over werknemers nodig hebben? Het was mogelijk om een ​​API te schrijven voor de autorisatieservice, maar dan zou je voor elk van die applicaties extra logica moeten toevoegen. Daarnaast wilden we af van de afhankelijkheid van één van onze zelfgeschreven applicaties, die later vertaald zou worden in OpenSource, op onze interne autorisatieserver. We zullen het er een andere keer over hebben. De oplossing voor beide problemen was OAuth.

aan gemeenschappelijke normen

OAuth is een begrijpelijke, algemeen aanvaarde autorisatiestandaard, maar omdat alleen de functionaliteit niet voldoende is, begonnen ze meteen OpenID Connect (OIDC) te overwegen. OIDC zelf is de derde implementatie van de open authenticatiestandaard, die is overgegaan in een add-on via het OAuth 2.0-protocol (een open autorisatieprotocol). Deze oplossing lost het probleem van het ontbreken van gegevens over de eindgebruiker op en maakt het ook mogelijk om van autorisatieprovider te veranderen.

We hebben echter geen specifieke provider gekozen en besloten integratie met OIDC toe te voegen voor onze bestaande autorisatieserver. In het voordeel van deze beslissing was het feit dat OIDC zeer flexibel is op het gebied van eindgebruikersautorisatie. Zo was het mogelijk om OIDC-ondersteuning op uw huidige autorisatieserver te implementeren.

OpenID Connect: autorisatie van interne applicaties van maatwerk naar standaard

Onze manier om onze eigen OIDC-server te implementeren

1) De gegevens in de gewenste vorm gebracht

Om OIDC te integreren, is het nodig om de huidige gebruikersgegevens in een voor de standaard begrijpelijke vorm te brengen. In OIDC heet dit Claims. Claims zijn in wezen laatste velden in de gebruikersdatabase (naam, e-mail, telefoon, enz.). bestaat standaard lijst met postzegels, en alles wat niet in deze lijst staat, wordt als aangepast beschouwd. Daarom is het eerste punt waar u op moet letten als u een bestaande OIDC-provider wilt kiezen, de mogelijkheid van gemakkelijke aanpassing van nieuwe merken.

De groep keurmerken is gecombineerd in de volgende subset - Toepassingsgebied. Tijdens de autorisatie wordt niet toegang gevraagd tot specifieke merken, maar tot scopes, ook als sommige van de merken uit de scope niet nodig zijn.

2) Implementeerde de nodige subsidies

Het volgende onderdeel van de OIDC-integratie is de selectie en implementatie van autorisatietypes, de zogenaamde grants. Het verdere interactiescenario tussen de geselecteerde applicatie en de autorisatieserver hangt af van de geselecteerde toekenning. Een voorbeeldschema voor het kiezen van de juiste beurs is weergegeven in onderstaande figuur.

OpenID Connect: autorisatie van interne applicaties van maatwerk naar standaard

Voor onze eerste aanvraag hebben we gebruik gemaakt van de meest voorkomende subsidie, de Autorisatiecode. Het verschil met anderen is dat het een drietrapsstap is, d.w.z. wordt extra getest. Eerst doet de gebruiker een verzoek om autorisatietoestemming, ontvangt een token - Autorisatiecode en vraagt ​​​​vervolgens met dit token, alsof het een reisticket is, een toegangstoken aan. Alle belangrijke interactie van dit autorisatiescript is gebaseerd op omleidingen tussen de applicatie en de autorisatieserver. U kunt meer lezen over deze subsidie hier.

OAuth houdt zich aan het concept dat de verkregen toegangstokens na autorisatie tijdelijk dienen te zijn en bij voorkeur gemiddeld elke 10 minuten worden gewijzigd. De toekenning van de autorisatiecode is een verificatie in drie stappen door middel van omleidingen, om de 10 minuten om zo'n stap om te zetten, eerlijk gezegd, is niet de meest aangename taak voor de ogen. Om dit probleem op te lossen, is er nog een subsidie ​​- Refresh Token, die we ook in ons land hebben gebruikt. Alles is hier gemakkelijker. Tijdens de verificatie van een andere subsidie ​​wordt er naast het hoofdtoegangstoken nog een token uitgegeven - Refresh Token, dat slechts één keer kan worden gebruikt en waarvan de levensduur meestal veel langer is. Met dit Refresh Token, wanneer de TTL (Time to Live) van het hoofdtoegangstoken eindigt, komt het verzoek om een ​​nieuw toegangstoken bij het eindpunt van een andere verlening. Het gebruikte Refresh Token wordt onmiddellijk op nul gezet. Deze controle bestaat uit twee stappen en kan op de achtergrond worden uitgevoerd, onmerkbaar voor de gebruiker.

3) Stel aangepaste formaten voor gegevensuitvoer in

Nadat de geselecteerde subsidies zijn geïmplementeerd, autorisatie werkt, is het vermeldenswaard dat u gegevens over de eindgebruiker krijgt. OIDC heeft hiervoor een apart endpoint, waar je gebruikersgegevens kunt opvragen met je huidige toegangstoken en als deze up-to-date is. En als de gebruikersgegevens niet zo vaak veranderen en u de huidige gegevens vaak moet volgen, kunt u tot een oplossing komen als JWT-tokens. Ook deze tokens worden door de standaard ondersteund. Het JWT-token zelf bestaat uit drie delen: header (informatie over het token), payload (eventuele noodzakelijke gegevens) en handtekening (handtekening, het token wordt ondertekend door de server en u kunt later de bron van zijn handtekening controleren).

In de OIDC-implementatie wordt het JWT-token id_token genoemd. Het kan samen met een normaal toegangstoken worden aangevraagd en het enige dat overblijft is om de handtekening te verifiëren. De autorisatieserver heeft hiervoor een apart eindpunt met een aantal publieke sleutels in het formaat Ctte. En hierover gesproken, het is vermeldenswaard dat er nog een ander eindpunt is, dat gebaseerd is op de standaard RFC5785 weerspiegelt de huidige configuratie van de OIDC-server. Het bevat alle eindpuntadressen (inclusief het adres van de openbare sleutelring die wordt gebruikt voor ondertekening), ondersteunde merken en bereiken, gebruikte versleutelingsalgoritmen, ondersteunde subsidies, enz.

Bijvoorbeeld op 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"
 ]
}

Met behulp van id_token kunt u dus alle benodigde kenmerken overbrengen naar de payload van het token en niet elke keer contact opnemen met de autorisatieserver om gebruikersgegevens op te vragen. Het nadeel van deze aanpak is dat de wijziging in gebruikersgegevens van de server niet direct komt, maar samen met een nieuw toegangstoken.

Implementatie resultaten

Dus na het implementeren van onze eigen OIDC-server en het configureren van verbindingen ermee aan de applicatiekant, hebben we het probleem van het overdragen van informatie over gebruikers opgelost.
Omdat OIDC een open standaard is, hebben we de mogelijkheid om een ​​bestaande provider of serverimplementatie te kiezen. We hebben Keycloak geprobeerd, wat erg handig bleek te zijn om te configureren, na het instellen en wijzigen van verbindingsconfiguraties aan de applicatiekant, is het klaar voor gebruik. Aan de applicatiekant rest alleen nog het wijzigen van de verbindingsconfiguraties.

Over bestaande oplossingen gesproken

Binnen onze organisatie hebben we als eerste OIDC-server een eigen implementatie in elkaar gezet, die waar nodig werd aangevuld. Na een gedetailleerd overzicht van andere kant-en-klare oplossingen, kunnen we zeggen dat dit een betwistbaar punt is. Voor de beslissing om hun eigen server te implementeren, waren er zorgen van de kant van providers over het ontbreken van de nodige functionaliteit, evenals de aanwezigheid van een oud systeem waarin er verschillende aangepaste autorisaties waren voor sommige services en heel veel aan gegevens over werknemers was al opgeslagen. In kant-en-klare implementaties zijn er echter gemakken voor integratie. Zo heeft Keycloak een eigen gebruikersbeheersysteem en wordt data er direct in opgeslagen, en zal het niet moeilijk zijn om je gebruikers daar in te halen. Om dit te doen, heeft Keycloak een API waarmee u alle noodzakelijke overdrachtsacties volledig kunt uitvoeren.

Een ander voorbeeld van een gecertificeerde, naar mijn mening interessante implementatie is Ory Hydra. Het is interessant omdat het uit verschillende componenten bestaat. Om te integreren, moet u uw gebruikersbeheerservice koppelen aan hun autorisatieservice en indien nodig uitbreiden.

Keycloak en Ory Hydra zijn niet de enige kant-en-klare oplossingen. U kunt het beste kiezen voor een door de OpenID Foundation gecertificeerde implementatie. Deze oplossingen hebben meestal een OpenID-certificeringsbadge.

OpenID Connect: autorisatie van interne applicaties van maatwerk naar standaard

Vergeet ook bestaande betaalde providers niet als u uw OIDC-server niet wilt behouden. Tegenwoordig zijn er veel goede opties.

What's Next

In de nabije toekomst gaan we het verkeer naar de interne diensten op een andere manier afsluiten. We zijn van plan om onze huidige SSO op de balancer met behulp van OpenResty over te zetten naar een proxy op basis van OAuth. Er zijn hier al veel kant-en-klare oplossingen, bijvoorbeeld:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Aanvullende materialen

jwt.io – goede service voor het valideren van JWT-tokens
openid.net/developers/certified - lijst met gecertificeerde OIDC-implementaties

Bron: www.habr.com

Voeg een reactie