Aanvraag Token Exchange

De Client vraagt de Token Exchange aan en authenticeert zich hiervoor

De Client initieert een token exchange verzoek richting het Token Endpoint (zie het Discovery Endpoint).

oAuth token exchange - aanvraag

Dit token request bevat volgende parameters:

Parameter Omschrijving
grant_type VERPLICHT Waarde die verplicht “urn:ietf:params:oauth:grant-type:token-exchange” is
subject_token  VERPLICHT Access of refresh token, uitgegeven aan de frontend applicatie
subject_token_type VERPLICHT subject_token type (“urn:ietf:params:oauth:token-type:access_token” of “urn:ietf:params:oauth:token-type:refresh_token”
audience  OPTIONEEL(*) Client-id die de audience (de API) uniek identificeert
resource  OPTIONEEL(*) URI (die begint met http) die de audience (de API) uniek identificeert
scope OPTIONEEL de scopes (gescheiden door een spatie) die nodig zijn om de API te bevragen
requested_token_type OPTIONEEL Het gewenste token type. Mogelijke waarden: “urn:ietf:params:oauth:token-type:access_token” (default) of “urn:ietf:params:oauth:token-type:jwt”
actor_token OPTIONEEL Extra token, waarvan de gelinkte gebruiker als actor wordt geregistreerd
actor_token_type AFHANKELIJK moet “urn:ietf:params:oauth:token-type:access_token” zijn. Deze waarde is verplicht indien actor_token gespecifieerd werd, zoniet dan is dit verboden

(*) één van beide is verplicht, want anders heeft de token exchange geen meerwaarde

Toelichting bij een aantal optionele parameters:

audience

De audience is een unieke identifier voor de API. Een Client kan een access token opvragen voor een specifieke audience op voorwaarde dat die audience de Client effectief vertrouwt: er wordt dan een access token aangemaakt voor die audience namens de aangemelde gebruiker. De vertrouwensrelatie tussen API en Client dient bij de opzet van de API expliciet gedefinieerd te worden opdat deze Token Exchange mogelijk zou zijn.

resource

Een resource is een absolute URL die een API uniek identificeert. De URLs die hier gebruikt kunnen worden, dienen vooraf geregistreerd te worden bij de intake van de API. Deze resource-parameter is nuttig indien de Client geen notie heeft van de ClientID, maar wel weet welke resource hij nodig heeft (welke URL hij wil benaderen).

scope

Via de scope parameter kan men de scopes (gescheiden door een spatie) aanvragen die aan het uitgeleverde access token gekoppeld moeten worden. Het is mogelijk dat de uitgeleverde scopes verschillen van de gevraagde scopes: enkel scopes die geldig zijn voor alle gevraagde (geldige) audiences én waarvoor de gebruiker over de correcte rechten beschikt zullen worden uitgeleverd.

Wanneer geen scope gespecifieerd werd in het request, worden de scopes van het subject_token gevalideerd.

requested_token_type

Bij token exchange vraagt men standaard een access token aan voor de opgegeven audience (dus met requested_token_type “urn:ietf:params:oauth:token-type:access_token”). Hierbij ontvangt men een access token, waarmee men de verdere info kan bevragen op het introspectie endpoint.

Indien als requested_token_type “urn:ietf:params:oauth:token-type:jwt” wordt gevraagd, dan zal er in plaats van een (opaque) access token meteen een JWT uitgeleverd worden, waarin alle informatie meteen aanwezig is. Het is zinloos om deze JWT nogmaals naar het introspectie endpoint te sturen (bovendien zal deze introspectie sowieso falen): alle benodigde informatie zit immers reeds in de JWT. Om te valideren dat deze JWT wel degelijk van de Authorization Server van Toegangsbeheer afkomstig is, kan men de signature ervan valideren: de keys waarmee het JWT is getekend, kan je terugvinden op het keys endpoint (zie het Discovery Endpoint).

actor_token

Wanneer een actor_token wordt gespecifieerd, maakt de Client duidelijk dat er een delegatie gebeurt. In dat geval zal een act claim toegevoegd worden aan de claims van het access token.

Een request zonder actor_token, maakt het voor de API onmogelijk om een onderscheid te maken tussen de gebruiker of een actor. In dat geval spreken we van impersonatie

De act claim maakt aan de API duidelijk dat de actor optreedt in naam van de gebruiker, maar dat de gebruiker niet zelf het request naar de API stuurt. Wanneer de delegatie gebeurt door een client, zal voor deze client de client_credentials grant toegestaan moeten worden (vraag dit dan aan bij het integratieteam).

Daarna kan de client via de client credentials grant een token aanvragen met de scope delegation. Deze speciale scope bevat geen informatie, maar heeft tot doel om een actor token te kunnen aanvragen dat gebruikt kan worden tijdens de token exchange.

chaining van actor_tokens

Een access token dat bekomen werd na een token exchange, kan zelf opnieuw gebruikt worden als subject_token in een token exchange, al dient het initiële token dat gebruikt werd voor de token-exchange uitgeleverd te zijn na een OpenID Connect authenticatie. Wanneer bij een dergelijke keten van token exchanges telkens een actor token wordt meegegeven, zal dit ook worden weergegeven op het introspection endpoint. Een act claim zal dan op zijn beurt opnieuw een act claim bevatten, die de keten weergeeft.

  {
    "act": {
        "sub": "8fc3bf07-d041-4868-8790-7d5206a64562",
        "act": {
            "sub": "afddd7fc-b23f-11eb-99ed-03dd47f3aa67"
        }
    }
  }

Uiteraard gelden voor de hele ketting dezelfde voorwaarden als voor één token exchange: de trust relatie tussen de Client en de API en de autorisatie van de gebruiker voor het gebruik van de API en toekenning van de juiste scopes gelden voor iedere stap in deze ketting.

Authenticatie

De Client dient zich te authenticeren zodat

  • De OP kan valideren dat het subject token werd uitgeleverd aan de Client
  • De vertrouwensrelatie tussen de Client en de audience(s) (API) gevalideerd kan worden
  • Het toepassingsgebied van het subject_token niet ongewenst kan uitgebreid worden met het toepassingsgebied van de API

Token exchange is dus niet bruikbaar voor Clients die hun secret niet geheim kunnen houden (bvb. public clients). Zij dienen de flow namens een gebruiker te volgen, waar de integriteit van de requests kan gegarandeerd worden door gebruik te maken van PKCE.

Client authenticatie op basis van ClientID en Secret

Hierbij wordt er bij de onboarding een ClientID en een Secret gegenereerd langs de Authorization Server zijde en aan de Client bezorgd. Deze ClientID en Secret kunnen door de Client op 2 verschillende manieren aangeboden worden aan het Token Endpoint.

ClientID en Secret via POST-parameters

Hierbij worden de ClientID en de Secret via POST-parameters doorgestuurd.

Voorbeeld:

POST /op/v1/token HTTP/1.1
Host: authenticatie.vlaanderen.be
Content-Type: application/x-www-form-urlencoded

  client_id=28358814-5c20-4c13-bbff-db5dd8c4ae93&
  client_secret=CgNjSBQwSolxUcFe7A0U-16j7uccp34-Z5eigKOoCpn5WMHjcb0IkseYA8zhMdYKlpzNJh4Qj4OhjvkVEXq6clvKlutFv5H&
  grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
  subject_token=Bokejssjdej34jkzbd5shsjSQdxjbdn2kdoveicj47k&
  subject_token_type=urn:ietf:params:oauth:token-type:access_token&
  audience=37f875cb-a7bd-4724-ac39-4729092f8412&
  scope=AppRead

ClientID en Secret via Basic Authentication

De ClientID en Secret worden via Basic Authentication “Authorization”-header meegestuurd.

POST /op/v1/token HTTP/1.1
Host: authenticatie.vlaanderen.be
Authorization: Basic MjgzNTg4MTQtNWMyMC00YzEzLWJiZmYtZGI1ZGQ4YzRhZTkzOkNnTmpTQlF3U29seFVjRmU3QTBVLTE2ajd1Y2NwMzQtWjVlaWdLT29DcG41V01IamNiMElrc2VZQTh6aE1kWUtscHpOSmg0UWo0T2hqdmtWRVhxNmNsdktsdXRGdjVI
Content-Type: application/x-www-form-urlencoded

  grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
  subject_token=Bokejssjdej34jkzbd5shsjSQdxjbdn2kdoveicj47k&
  subject_token_type=urn:ietf:params:oauth:token-type:access_token&
  audience=37f875cb-a7bd-4724-ac39-4729092f8412&
  scope=AppRead

Client authenticatie via een JWT token

In dit geval genereert de Client bij de onboarding een asymmetrisch keypaar en bezorgt de Authorization Server het publieke deel ervan: het private deel wordt enkel lokaal op de Client bewaard.

Bij de authenticatie op het Token Endpoint worden volgende parameters meegestuurd:

  • “client_assertion_type” met als waarde “urn:ietf:params:oauth:client-assertion-type:jwt-bearer”
  • “client_assertion” met daarin één enkele JWT

Voorbeeld:

POST /op/v1/token HTTP/1.1
Host: authenticatie.vlaanderen.be
Content-Type: application/x-www-form-urlencoded

  grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
  subject_token=Bokejssjdej34jkzbd5shsjSQdxjbdn2kdoveicj47k&
  subject_token_type=urn:ietf:params:oauth:token-type:access_token&
  audience=37f875cb-a7bd-4724-ac39-4729092f8412&
  scope=AppRead&
  client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
  client_assertion=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIyODM1ODgxNC01YzIwLTRjMTMtYmJmZi1kYjVkZDhjNGFlOTMiLCJzdWIiOiIyODM1ODgxNC01YzIwLTRjMTMtYmJmZi1kYjVkZDhjNGFlOTMiLCJhdWQiOiJodHRwczovL2F1dGhlbnRpY2F0aWUudmxhYW5kZXJlbi5iZS9vcCIsImV4cCI6MTU5MjIwODA2MCwianRpIjoiRGt6bmpzdTQzZHprZDN6amQ1IiwiaWF0IjoxNTkyMjA4MDAwfQ.3dPodaVhJ2d3cXWn0v2YGeZqs5XScJF2lm4MaweDnf4

In bovenstaand request bevatte “client_assertion” een JWT met volgende inhoud:

{
  "iss": "28358814-5c20-4c13-bbff-db5dd8c4ae93",
  "sub": "28358814-5c20-4c13-bbff-db5dd8c4ae93",
  "aud": "https://authenticatie.vlaanderen.be/op",
  "exp": 1592208060,
  "jti": "Dkznjsu43dzkd3zjd5",
  "iat": 1592208000
}

De JWT in de client_assertion dient uiteraard gesigned te zijn met één van de keys die voor die Client geregistreerd staan op de Authorization Server.

Daarnaast moet/kan deze JWT volgende claims bevatten:

Claim Omschrijving
iss (issuer) VERPLICHT Deze dient de ClientID te bevatten
sub (subject) VERPLICHT Deze dient de ClientID te bevatten
aud (audiance) VERPLICHT Deze dient de issuer te bevatten, zijnde https://authenticatie-ti.vlaanderen.be/op voor TEST of https://authenticatie.vlaanderen.be/op voor PROD
exp (expiration time) VERPLICHT Een expiration time moet aanwezig zijn: de huidige tijd mag niet recenter zijn dan de expiration time en deze mag ook niet te ver in de toekomst liggen (maximum 10 minuten)
jti (jwt id) OPTIONEEL AANBEVOLEN Men kan een unieke ID meegeven voor de JWT: de Authorization Server kan dit gebruiken om replay attacks tegen te gaan
iat (issued at) OPTIONEEL Tijdstip waarop de JWT werd gegenereerd: deze mag niet te ver in de toekomst liggen
nbf (not before) OPTIONEEL Indien aanwezig worden tokens niet aanvaard voor de aangegeven timestamp