Client authenticatie

Voor de authenticatie van de Client bij het Token Endpoint worden verschillende mogelijkheden aangeboden

Client authenticatie op basis van ClientID en Secret

Hierbij wordt er bij de onboarding een ClientID en een (gedeelde) Secret gegenereerd langs de OpenID Connect Provider 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=authorization_code&
  code=OV9FU_1lxJoAbc&
  redirect_uri=https%3A%2F%2Fmijntoepassing%2Fcallback

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=authorization_code&
  code=OV9FU_1lxJoAbc&
  redirect_uri=https%3A%2F%2Fmijntoepassing%2Fcallback

Client authenticatie via een JWT token

In dit geval genereert de Client een asymmetrisch keypaar en deelt het publieke deel met de OpenID Connect Provider: 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=authorization_code&
  code=OV9FU_1lxJoAbc&
  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 bekend zijn bij de OpenID Connect Provider.

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 OpenID Connect Provider 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

Meer info is terug te vinden in RFC7517

Publieke sleutel (JWK) voor JWT-authenticatie

Voor het gebruik van JWT als authenticatie, dient er een publieke sleutel (JWK) aangereikt te worden: deze moet aan volgende voorwaarden voldoen:

  • we verwachten hierbij een publieke sleutel uit een asymmetrisch keypaar (symmetrische keys bieden immers geen meerwaarde t.o.v. de client/secret die ook gebruikt kan worden)
  • gelieve er steeds op te letten dat enkel het publieke deel doorgestuurd wordt: als er een private key meegestuurd wordt, dan dient dit keypaar als gecomprommiteerd beschouwd te worden
  • als key-type (kty) kan er gekozen worden voor RSA (aanbevolen) of voor EC (Elliptic Curve)
  • als algoritme (alg) zijn er meerdere opties mogelijk, waaronder:
    • RS256 RSASSA-PKCS1-v1_5 met SHA-256 (aanbevolen)
    • RS384 RSASSA-PKCS1-v1_5 met SHA-384
    • RS512 RSASSA-PKCS1-v1_5 met SHA-512
    • P-256 and SHA-256 (voor EC)
    • P-384 and SHA-384 (voor EC)
    • P-521 and SHA-512 (voor EC)
  • de key-grootte moet minimaal 2048 bytes zijn. Een key-grootte van 4096 bytes is aanbevolen
  • Meer info is terug te vinden in RFC7517

x5c, x5t, x5t#S256

Het gebruik van de velden x5c, x5t en x5t#S256 wordt ondersteund en laat toe om de JWK sleutel te koppelen aan een certificaat. Wanneer dat gebeurt, zal de geldigheid (tijdframe, revocation en CA) gevalideerd worden. Het gebruik van deze velden is optioneel.

Om de sleutel te koppelen aan een certificaat, dient de parameter x5c aanwezig te zijn en een lijst van één of meerdere certificaten te bevatten. Elk certificaat is een base64 encoded (niet base64url-encoded) representatie van een DER PKIX certificaat. De publieke sleutel van het eerste certificaat in de lijst dient overeen te komen met de publieke sleutel in de JWK. De eventueel volgende certificaten dienen telkens het certificaat te zijn dat het vorige in de lijst heeft uitgegeven (de issuing CA).

Enkel certificaten die werden uitgegeven door vertrouwde CA’s zoals VOPKI certificaten worden vertrouwd. Het is erg belangrijk dat u de datum waarop de certificaten zullen vervallen monitort en uw sleutels uiterlijk kort voor die datum vernieuwt om te voorkomen dat uw sleutel ongeldig wordt en elke authenticatie van u client zal falen wegens een vervallen sleutel.

Een sleutel die ongeldig is geworden (omdat hij vervallen is, gerevoked werd of omdat de revocation status niet kon gevalideerd worden) zal niet in rekening genomen worden bij de validatie van JWT tokens die als authenticatie worden gebruikt.

De velden x5t en x5t#S256 laten toe om een hash (SHA-1 en SHA-256 respectievelijk) van het (eerste) certificaat uit de x5c parameter mee te geven. Het gebruik van deze parameters is optioneel, maar wanneer ze gebruikt worden is het verplicht om ook de parameter x5c in je sleutel op te nemen.

Uitwisselen JWK

Om het voor de OpenID Connect provider mogelijk te maken om authenticatie op basis van JWTs te valideren, dient de publieke sleutel gekend te zijn. Deze dient dus aan de beheerders van de provider bezorgd te worden alvorens de authenticatie kan slagen.

Als alternatief is het mogelijk om een JWK Set publiek beschikbaar te maken op het internet. Indien een JWKS endpoint geconfigureerd werd voor uw client, volstaat het om de publieke sleutels op het opgegeven endpoint te publiceren opdat er rekening mee gehouden zou worden. Houd er wel rekening mee dat de beschikbaarheid van dit endpoint cruciaal is! Wanneer geen keys beschikbaar zijn, zal de authenticatie voor uw client niet lukken en wordt uw client erg snel (tijdelijk) geblokkeerd. (meer details)

Voorbeeld van een publieke sleutel (JWK) zoals te bezorgen aan het integratieteam

{"alg":"RS256",
 "e":"AQAB",
 "kty":"RSA",
 "n":"u88iozziqVoqCSKAJlgXAe_Ic1bImuXWmv06siGzEbmCzDTPL8bv_ylGBQw1F6ohmmvVARl29vDqj8TP1GwELg_LzEfa87GxEHGTDR1_ZGBugYrS4vkwnlpY3ObZyv8xETi1zgp04XDQxtHlk2IrMzU4xAo2Kx535jV3owhL26VxGvt9gCH2yFBM2HyTUVUx5S-IlPiq3rn7opoKUPztjTDyqvwsPmDPhhSHMhJG9KrtZqPT4nYEF9RhlyYu0rwyOnCyNgQa6YbvCplYnNTtbC5R6P3JUrvLr_yARchbB_mlVrbYh9dYpORLbMyhkeO0zFzAHa70h-k3584soepf3dFpTL4ebBHlDlQ1kQHmAThPnFv373kDE5sd9SZwJo5nWTiLMfxio7cawSciSpxuFrlooGfRH77uz3fj7WuUSHEujouBFsfqNKCJPtDVpsry24B8gSYmnkaeTYDEC63MdCH3p2yYc5BIqPYTFVDijv89qGz7WBx_HzOonbI9DOSumo_I_a72xeMhoeiPZ0EGXhp957mh7xzfAH3x-p93fSgxEleKJyubAeNOpf2vBBVvBViDu-MzJC22ggTilKENOFEzuWPTYUOp4rNOCQnsup6CX7XvluitFPUE_R10e3H3tn1U1jdbrU1Rk101tCCzSQONParH_ocFvYipBPJmv20"}

Voorbeeld van een publieke sleutel (JWK) met x5c

{"e": "AQAB",
 "kid": "X6aI5c4haK02YMXzPaqdPwMy_LUOWXaPKpY4eOahOEc",
 "kty": "RSA",
 "n": "0GHuSu_a1JZZXTBBuHgkTGQB3GcoLrJ9S1poWC68ozdgBKUd3K_fLWcH6wc0Opv6S6d0-dZcm4luclHqd_OzDF2vEzRf2llrYovPeguIvM6QndmWI-szTHYieyLtHITPL3P39BuQFJ6UuAFzHH61iIC6u7qTCjfZfgeewns4U0OlevmhkTn19mKXE59A1ZIlyXlK-uryLJKQF_vQKjZxeLkGKup-9nGo9M8gSOxhPqeTkuNKOVOvnp85CNr8s8alnN-xKf8f4QKpwaBtMjCquoEzFiDzJ4fOH_io3giD-0kJ76lgs7Qpki14sfUE4etc1u7OY46EjQlmPzEkuLH6HJsJNO9fQK_W_oUH8VNinfIwJpdtD7doUkdqBJ2bb5amplaHyKw8mafbHpCVbrW-Ebu10KSSND5_szwMZdMVvgX6VaRx3UdZcXm53SVTWU6Pv64I5OWe0wyTmwqftkD5YxCLIjU0GYJbk8FxXGtccQj0rw5zEptIR6tJuOF_IstJvwatCUtIM_sEXx-kDkrXouyg_vP9LgaMqcH7U3AtEee1TK7pBse8RBb7NENEkGrFaByzGl-ffNiCofwr05iMS3Y6Xa9s6jTZ_LmpZYahKLS-4F_xuDHEwLw6YM-R1EWVwFt2D6hA11Om9oRkpizcHbEQH5Ng_-vYW_EFbcjSbqU",
 "x5c": ["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"],
 "x5t": "X6aI5c4haK02YMXzPaqdPwMy_LUOWXaPKpY4eOahOEc"}

Voorbeeld: Genereren van een JWK

Hierbij een voorbeeld in Python hoe een asymmetrisch keypaar aangemaakt kan worden:

pip install jwcrypto
python
>>> from jwcrypto.jwk import JWK
>>> import json
>>> key = JWK.generate(kty='RSA', alg='RS256', size=4096)
>>> public_key = key.export_public()

>>> key.export_private() => private key
>>> print(public_key) => public key te bezorgen aan het integratieteam

Voorbeeld: Genereren van een JWK gebaseerd op een x509 certificaat

Indien je een JWK keypaar wil exporteren uit een bestaand x509-certificaat, dan kan dit: de extra metadata als expiry date en issuer worden in dat geval echter niet gebruikt.

pip install jwcrypto
python
>>> from jwcrypto.jwk import JWK
>>> import json
>>> with open("mycert-with-key.pem", "rb") as pemfile:
>>>       jwk = JWK.from_pem(pemfile.read())
>>>
>>> public_key = jwk.export_public()
>>> private_key = jwk.export_private()

>>> print(public_key) => public key te bezorgen aan het integratieteam
>>> print(private_key) => voor gebruik als private key in de toepassing zelf