OSR:2019/JWT: verschil tussen versies

Uit Kennisnet Developers Documentatie
Naar navigatie springen Naar zoeken springen
k
 
(80 tussenliggende versies door 2 gebruikers niet weergegeven)
Regel 1: Regel 1:
  +
{{Info|''' Let op:'''<br>Onderstaande implementatie werd gebruikt in OSR versie 1 voor het 'registreren' en 'updaten' van endpoints.<br>Vanaf versie 2 (uitgebracht op 14/11/2019) is deze in zijn geheel '''niet meer nodig'''.}}
  +
  +
 
==Waarom JWT==
 
==Waarom JWT==
Voor de services registreren en updaten van endpoints wordt JWT toegepast om vast te stellen dat het bericht onderweg niet aangepast is en ondertekend is door degene die het bericht heeft opgesteld.<br>
+
Voor de services 'registreren' en 'updaten' van endpoints wordt JWT toegepast om vast te stellen dat het bericht onderweg niet aangepast is en ondertekend is door degene die het bericht heeft opgesteld.<br>
 
Binnen de onderwijsketen maken we afspraken over de manier waarop we ondertekening uitvoeren en controleren.<br>
 
Binnen de onderwijsketen maken we afspraken over de manier waarop we ondertekening uitvoeren en controleren.<br>
 
Deze afspraken worden vastgelegd in een Edukoppeling profiel, analoog aan de Edukoppeling afspraken die er voor de beveiliging van SOAP berichten worden gemaakt.<br>
 
Deze afspraken worden vastgelegd in een Edukoppeling profiel, analoog aan de Edukoppeling afspraken die er voor de beveiliging van SOAP berichten worden gemaakt.<br>
   
==Hoe JWT toe te passen==
+
==JWT nader bekeken==
  +
Er is een online tool beschikbaar om jwt tokens mee samen te stellen: <br>
Het JWT token wordt als http header meegestuurd. Het JWT token bestaat uit 3 onderdelen:<br>
 
  +
{{ComItem|Homepage|jwt.io|https://jwt.io/}}
header, payload data en ondertekening.<br>
 
   
  +
Op de volgende pagina vindt u referenties naar JWT documentatie:
De 3 onderdelen worden gescheiden door een punt en het geheel wordt base64 geencodeerd:
 
  +
[[OSR:belangrijke_JWT_documentatie|Belangrijke JWT documentatie]]<br>
   
  +
Het aanmaken van JWT tokens worden voor het grootste gedeelte automatisch door de libraries van uw ontwikkelplatform gegenereerd.<br>
[[Bestand:jwt_structuur.jpg|thumb|left]]
 
  +
(zie jwt.io voor een lijst met beschikbare libraries).<br><br>
   
  +
Het JWT token wordt als http header meegestuurd. Om een JWT token te creëren moeten de volgende stappen worden uitgevoerd:
<br><br><br><br><br><br><br><br><br>
 
==JWT nader bekeken==
 
   
  +
*1. Stel het registreer/update endpoint bericht samen dat naar OSR wordt gestuurd.<br>
De header en payload van het JWT token worden ondertekend met het algoritme en bijbehorende parameters dat in de header van het JWT token is beschreven.<br>
 
  +
*2. Maak een base64 geëncodeerde SHA256 hash voor het bericht aan.<br>
Voor de ondertekening wordt de private sleutel van het PKI-overheids/ODOC certificaat gebruikt. De publieke sleutel wordt meegeleverd in het bericht, zodat de ontvangende partij het bericht kan valideren.<br>
 
  +
*3. Maak de header en payload.
  +
*4. Maak het JWS token en onderteken het bericht met behulp van de private key en encodeer het totale bericht.<br>
   
   
  +
*1. Stel het registreer/update endpoint bericht samen dat naar OSR wordt gestuurd.<br>
Er is een online tool beschikbaar om jwt tokens samen te stellen: {{ComItem|Homepage|jwt.io|https://jwt.io/}}
 
  +
hieronder is een voorbeeld bericht weergegeven van endpoint registreren:<br>
   
  +
<syntaxhighlight lang="json">
  +
{
  +
"mandate_token":"6a47bfdd-81a7-46cd-b41f-d907e91ebdfc",
  +
"administration_id": "0000000700004HR77707",
  +
"service_version_namespace": "http://xml.eld.nl/schemas/Overstapservice/20170601",
  +
"url": "https://t2.nl"
  +
}
  +
</syntaxhighlight>
  +
  +
*2. Maak een base64 geëncodeerde SHA256 hash voor het bericht aan.<br>
  +
  +
Het OSR biedt ter ondersteuning van het ontwikkeltraject een service aan om een json-bericht te hashen met base64 SHA256 encoding.
  +
  +
<syntaxhighlight lang="json">
  +
POST /api/v1/jwt/hash
  +
</syntaxhighlight>
  +
  +
'''Belangrijk:'''<br>
  +
Deze service maakt geen onderdeel uit van de kwalificatie- en productiefase.
  +
Er dient uiteindelijk zelf een hash-algoritme geïntegreerd te zijn in de te ontwikkelen software.
  +
  +
Het OSR controleert uiteindelijk de hash op basis van het registreer/update bericht.<br>
  +
  +
  +
Foutcodes
  +
  +
{|class="wikitable"
  +
! style="text-align:left;"| Route
  +
! style="text-align:left;"| Code
  +
! style="text-align:left;"| Melding
  +
|-
  +
| | jwt/hash
  +
| | 200
  +
| | hash
  +
|-
  +
| | jwt/hash
  +
| | 400
  +
| | Invalid Content-Type. Please use this api endpoint with Content-Type 'application/json' to create a valid JWT hash.
  +
|-
  +
| | jwt/hash
  +
| | 400
  +
| | Invalid json message received
  +
|}
  +
  +
  +
  +
*3. Maak de header en payload.
  +
Header en payload bevatten een aantal parameters (claims), deze worden hieronder uitgewerkt.
  +
  +
Voeg de hash toe aan payload data.<br>
   
Hieronder is een voorbeeld weergegeven van het gedecodeerde JWT token:<br>
 
   
 
<syntaxhighlight lang="json">
 
<syntaxhighlight lang="json">
Regel 48: Regel 104:
   
 
{
 
{
"iat": 1548330681,
+
"iat": 1552905888,
"nbf": 1548330681,
+
"nbf": 1552905888,
"exp": 1548334281,
+
"exp": 1552909488,
  +
"sub": "http://osr-api.kennisnet.nl/api/v1",
"aud": "00000003272448340204",
 
"iss": "00000003272448340116",
+
"aud": "edustd:oin:00000003272448340116",
  +
"iss": "edustd:oin:00000003272448340204",
"hash": "DmSGW0lCV3OSNp/rVgGpodZ/Hcuje5ciQkiDqPhFpAk="
 
  +
"edustd:body": {
  +
"hash": "3yi2BToDbJPmL2\/7qR616vCeh6DkQYIhjXskRXyXAOo=",
  +
"alg": "B64SHA256"
  +
}
 
}
 
}
  +
</syntaxhighlight>
   
   
</syntaxhighlight>
 
   
  +
==Header parameters==
 
  +
===Overzicht parameters ===
  +
  +
Ter aanvulling kunt u de meest recente versie van het document met Edukoppeling-definities van REST-services [[:Bestand:Ondertekenen_en_adresseren_in_REST.pdf|hier]] bekijken.
  +
  +
====Header parameters====
 
{|class="wikitable"
 
{|class="wikitable"
! style="text-align:left;"| Parameters
+
! style="text-align:left;"| #
  +
! style="text-align:left;"| Claim
 
! style="text-align:left;"| Waarde
 
! style="text-align:left;"| Waarde
 
! style="text-align:left;"| Omschrijving
 
! style="text-align:left;"| Omschrijving
 
! style="text-align:left;"| Verplicht/Optioneel
 
! style="text-align:left;"| Verplicht/Optioneel
!
 
 
|-
 
|-
| | alg
+
| h1
  +
| alg
 
| RS256
 
| RS256
 
| Het algoritme van de key wordt hier aangegeven
 
| Het algoritme van de key wordt hier aangegeven
 
| Verplicht
 
| Verplicht
 
|-
 
|-
| | type
+
| h2
| JWT
+
| jwk
| Typering van het token
 
| Verplicht
 
|-
 
| | Jwk kty
 
| RSA
 
| Key type
 
| Verplicht
 
|-
 
| | n
 
 
|
 
|
| Modulus van het pem certificaat
+
| Bevat het parameters van het PKIo certificaat dat gebruikt is voor de ondertekening van het bericht.
| Verplicht
 
|-
 
| | e
 
| AQAB
 
| Exponent van het pem certificaat
 
 
| Verplicht
 
| Verplicht
 
|-
 
|-
| | x5c
+
| h2.1
  +
| kty
 
|
 
|
  +
| Type van het PKIo certificaat, “RSA”.
| x509 certifcate chain. Hiermee kan worden geverifieerd of het certificaat is uitgegeven door de juiste CA en of het op blacklist staat van de revoke list
 
 
| Verplicht
 
| Verplicht
 
|-
 
|-
| | x5t
+
| h2.2
  +
| n
 
|
 
|
| Thumbprint van x509 certificaat
+
| Modulus van de publieke RSA sleutel van het x509 (PKIo) certificaat, geëncodeerd als base64url integer.
 
| Verplicht
 
| Verplicht
 
|-
 
|-
  +
| h2.3
| | x5t#256
 
|
+
| e
|
+
| AQAB
  +
| Exponent van de publieke RSA sleutel, geencodeerd als besa64url integer.
 
| Verplicht
 
| Verplicht
 
|-
 
|-
| | kid
+
| h2.4
|
+
| x5c *
  +
|
| Een naam om het certificaat te onderscheiden
 
  +
| Een lijst met de base64-geëncodeerde pem representatie van de publieke sleutel van het PKIo certificaat.
 
| Verplicht
 
| Verplicht
 
|-
 
|-
| | alg
+
| h2.5
|
+
| kid
  +
|
| Algoritme van de key
 
  +
| Key ID, wordt gebruikt om de juiste sleutel te kunnen kiezen als er meerdere publieke sleutels in de lijst zijn opgegeven.
| Verplicht
 
  +
| Optioneel
 
|-
 
|-
| | use
+
| h2.6
| sig
+
| use
  +
| sign
| Hoe de key gebruikt moet worden. Bij OSR gaat het om het ondertekenen van een bericht.
 
  +
| Zegt waar de sleutel voor gebruikt wordt, kan “sign” of “enc” bevatten voor respectievelijk ondertekenen of versleutelen. Hiermee kun je aangeven waar deze sleutel voor gebruikt wordt.
| Verplicht
 
  +
| Optioneel
|
 
 
|}
 
|}
   
  +
<nowiki>*</nowiki> Naast x5c zal ook x5u onderdeel gaan uitmaken van de Edukoppeling Standaard, maar OSR ondersteund deze claim in de huidige release nog niet.
==Payload parameters==
 
  +
  +
====Payload parameters====
 
{|class="wikitable"
 
{|class="wikitable"
! style="text-align:left;"| Parameters
+
! style="text-align:left;"| #
  +
! style="text-align:left;"| Claim
  +
! style="text-align:left;"| Waarde
 
! style="text-align:left;"| Omschrijving
 
! style="text-align:left;"| Omschrijving
 
! style="text-align:left;"| Verplicht/Optioneel
 
! style="text-align:left;"| Verplicht/Optioneel
!
 
 
|-
 
|-
  +
|p1
| | iat
 
  +
|iss
| Issued at. Dit geeft de datum aan wanneer het JWT token is aangemaakt.
 
  +
|
| Verplicht
 
  +
|Afzender van het bericht (issuer), notatie:<br>
  +
‘edustd:oin’: [de OIN van de afzenderorganisatie] of<br>
  +
‘edustd:oin’: [de OIN van de afzenderorganisatie inclusief administratie-kenmerk]
  +
|Verplicht
 
|-
 
|-
  +
|p2
| | nbf
 
  +
|aud
| Not before. Dit geeft de startdatum aan wanneer het JWT token gebruikt mag worden
 
  +
|
| Verplicht
 
  +
|Geadresseerden van het bericht (audience). Hier kan een enkele geadresseerde worden ingevuld in een string-notatie, of een lijst van geadresseerden. De notatie voor geadresseerden:<br>
  +
‘edustd:oin’: [OIN van de geadresseerde] of<br>
  +
‘edustd:oin’: [OIN van de geadresseerde inclusief zijn administratie-kenmerk].
  +
|Verplicht
 
|-
 
|-
  +
|p3
| | exp
 
  +
|sub
| Expiration date. Dit geeft aan tot wanneer het JWT token gebruikt mag worden
 
  +
|
| Verplicht
 
  +
|Onderwerp van de berichtuitwisseling (subject). Hier is mogelijk om hier het service-version kenmerk (d.w.z. de namespace van de service) in te vullen, zodat deze informatie beschikbaar is om additionele gegevens van de service en zijn endpoint in het OSR op te zoeken. Indien ingevuld, moet de volgende namespace worden gebruikt: http://osr-api.kennisnet.nl/api/v1
  +
|Optioneel
 
|-
 
|-
  +
|p4
| aud
 
  +
|iat
| Audience. Dit geeft aan voor wie het JWT token is aangemaakt. In het geval een POST/PUT naar OSR is dit altijd Kennisnet
 
  +
|
| Verplicht
 
  +
|Timestamp (seconden sinds epoch) waarop het token is aangemaakt (issued at).
  +
|Verplicht
 
|-
 
|-
  +
|p5
| iss
 
  +
|nbf
| Issuer. Degene die het JWT token heeft aangemaakt
 
  +
|
| Verplicht
 
  +
|Tijdstip (seconden sinds epoch) vanaf welke het JWT token geldig is (not before). Als niet opgegeven, gelijk aan ‘iat’.
  +
|Optioneel
 
|-
 
|-
  +
|p6
| hash*
 
  +
|exp
| Hash waarde van de body data. De daadwerkelijke body data van de POST/PUT operatie| Verplicht
 
  +
|
| Verplicht
 
  +
|Tijdstip (seconden sinds epoch) tot welke het JWT token geldig is (expires). Als niet opgegeven, een uur (3.600.000 milliseconden) na iat.
  +
|Optioneel
  +
|-
  +
|p7
  +
|edustd:body
  +
| "edustd:body":{"hash":"...","alg":"B64SHA256"}
  +
|Container voor velden 7.1 en 7.2.
  +
|Verplicht
  +
|-
  +
|p7.1
  +
|hash
  +
|
  +
|De base64-geëncodeerde hashwaarde van het bericht zelf.
  +
|Verplicht
  +
|-
  +
|p7.2
  +
|alg
  +
| B64SHA256
  +
|Het algoritme waarmee de hashwaarde van het bericht is bepaald.
  +
|Verplicht
 
|}
 
|}
  +
   
 
'''* De volgende transformaties moeten worden gedaan om de hash te verkrijgen:<br>
 
'''* De volgende transformaties moeten worden gedaan om de hash te verkrijgen:<br>
 
'''* body -> SHA256 -> base64 encoding <br>
 
'''* body -> SHA256 -> base64 encoding <br>
  +
  +
  +
*4. Onderteken het bericht met behulp van de private key en encodeer het totale bericht.<br>
  +
De header en payload van het JWT token worden ondertekend met het algoritme en bijbehorende parameters dat in de header van het JWT token is beschreven.<br>
  +
Voor de ondertekening wordt de private sleutel van het PKI-overheids/ODOC certificaat gebruikt. De publieke sleutel wordt meegeleverd in het bericht, zodat de ontvangende partij het bericht kan valideren.<br>
  +
  +
  +
Het uiteindelijk JWT token bestaat uit 3 onderdelen:<br>
  +
header, payload data en ondertekening. Alle onderdelen zijn base64 url geencodeerd.<br>
  +
  +
De 3 onderdelen worden gescheiden door een punt:
  +
  +
[[Bestand:jwt_structuur.jpg|thumb|left]]
  +
  +
<br><br><br><br><br><br><br><br><br><br><br>
  +
  +
= Voorbeeldcode =
  +
[[OSR:PHP_JOSE_Library|PHP using JOSE Library]]
  +
  +
[[Category:OSR]]

Huidige versie van 14 nov 2019 om 12:00

Info.gif Let op:
Onderstaande implementatie werd gebruikt in OSR versie 1 voor het 'registreren' en 'updaten' van endpoints.
Vanaf versie 2 (uitgebracht op 14/11/2019) is deze in zijn geheel niet meer nodig.


Waarom JWT

Voor de services 'registreren' en 'updaten' van endpoints wordt JWT toegepast om vast te stellen dat het bericht onderweg niet aangepast is en ondertekend is door degene die het bericht heeft opgesteld.
Binnen de onderwijsketen maken we afspraken over de manier waarop we ondertekening uitvoeren en controleren.
Deze afspraken worden vastgelegd in een Edukoppeling profiel, analoog aan de Edukoppeling afspraken die er voor de beveiliging van SOAP berichten worden gemaakt.

JWT nader bekeken

Er is een online tool beschikbaar om jwt tokens mee samen te stellen:

Homepage icon.png jwt.io

Op de volgende pagina vindt u referenties naar JWT documentatie: Belangrijke JWT documentatie

Het aanmaken van JWT tokens worden voor het grootste gedeelte automatisch door de libraries van uw ontwikkelplatform gegenereerd.
(zie jwt.io voor een lijst met beschikbare libraries).

Het JWT token wordt als http header meegestuurd. Om een JWT token te creëren moeten de volgende stappen worden uitgevoerd:

  • 1. Stel het registreer/update endpoint bericht samen dat naar OSR wordt gestuurd.
  • 2. Maak een base64 geëncodeerde SHA256 hash voor het bericht aan.
  • 3. Maak de header en payload.
  • 4. Maak het JWS token en onderteken het bericht met behulp van de private key en encodeer het totale bericht.


  • 1. Stel het registreer/update endpoint bericht samen dat naar OSR wordt gestuurd.

hieronder is een voorbeeld bericht weergegeven van endpoint registreren:

{
"mandate_token":"6a47bfdd-81a7-46cd-b41f-d907e91ebdfc",
"administration_id": "0000000700004HR77707",
"service_version_namespace": "http://xml.eld.nl/schemas/Overstapservice/20170601",
"url": "https://t2.nl"
}
  • 2. Maak een base64 geëncodeerde SHA256 hash voor het bericht aan.

Het OSR biedt ter ondersteuning van het ontwikkeltraject een service aan om een json-bericht te hashen met base64 SHA256 encoding.

POST /api/v1/jwt/hash

Belangrijk:
Deze service maakt geen onderdeel uit van de kwalificatie- en productiefase. Er dient uiteindelijk zelf een hash-algoritme geïntegreerd te zijn in de te ontwikkelen software.

Het OSR controleert uiteindelijk de hash op basis van het registreer/update bericht.


Foutcodes

Route Code Melding
jwt/hash 200 hash
jwt/hash 400 Invalid Content-Type. Please use this api endpoint with Content-Type 'application/json' to create a valid JWT hash.
jwt/hash 400 Invalid json message received


  • 3. Maak de header en payload.

Header en payload bevatten een aantal parameters (claims), deze worden hieronder uitgewerkt.

Voeg de hash toe aan payload data.


header
{
  "alg": "RS256",
  "type": "JWT",
  "jwk": {
    "kty": "RSA",
    "n": "25wryfsgd_OVH4_RAy6afe-ruuzKrK58zJK- …jjj ",
    "e": "AQAB",
    "x5c": [
      "MIIFijCCA3KgAwIBAgIJANIncLtaUQHdMA… /rV"
    ],
    "x5t": "vzAuinLys_OgCFLDv_G2CJQdUhY",
    "x5t#256": "jkrWxwlbDlMSA3OzQOMhBJo0tjlLbp4IbDpAgwYOFGA",
    "kid": "Kennisnet signing certificate",
    "alg": "RS256",
    "use": "sig"
  }
}

Payload data

{
  "iat": 1552905888,
  "nbf": 1552905888,
  "exp": 1552909488,
  "sub": "http://osr-api.kennisnet.nl/api/v1",
  "aud": "edustd:oin:00000003272448340116",
  "iss": "edustd:oin:00000003272448340204",
  "edustd:body": {
    "hash": "3yi2BToDbJPmL2\/7qR616vCeh6DkQYIhjXskRXyXAOo=",
    "alg": "B64SHA256"
  }
}



Overzicht parameters

Ter aanvulling kunt u de meest recente versie van het document met Edukoppeling-definities van REST-services hier bekijken.

Header parameters

# Claim Waarde Omschrijving Verplicht/Optioneel
h1 alg RS256 Het algoritme van de key wordt hier aangegeven Verplicht
h2 jwk Bevat het parameters van het PKIo certificaat dat gebruikt is voor de ondertekening van het bericht. Verplicht
h2.1 kty Type van het PKIo certificaat, “RSA”. Verplicht
h2.2 n Modulus van de publieke RSA sleutel van het x509 (PKIo) certificaat, geëncodeerd als base64url integer. Verplicht
h2.3 e AQAB Exponent van de publieke RSA sleutel, geencodeerd als besa64url integer. Verplicht
h2.4 x5c * Een lijst met de base64-geëncodeerde pem representatie van de publieke sleutel van het PKIo certificaat. Verplicht
h2.5 kid Key ID, wordt gebruikt om de juiste sleutel te kunnen kiezen als er meerdere publieke sleutels in de lijst zijn opgegeven. Optioneel
h2.6 use sign Zegt waar de sleutel voor gebruikt wordt, kan “sign” of “enc” bevatten voor respectievelijk ondertekenen of versleutelen. Hiermee kun je aangeven waar deze sleutel voor gebruikt wordt. Optioneel

* Naast x5c zal ook x5u onderdeel gaan uitmaken van de Edukoppeling Standaard, maar OSR ondersteund deze claim in de huidige release nog niet.

Payload parameters

# Claim Waarde Omschrijving Verplicht/Optioneel
p1 iss Afzender van het bericht (issuer), notatie:

‘edustd:oin’: [de OIN van de afzenderorganisatie] of
‘edustd:oin’: [de OIN van de afzenderorganisatie inclusief administratie-kenmerk]

Verplicht
p2 aud Geadresseerden van het bericht (audience). Hier kan een enkele geadresseerde worden ingevuld in een string-notatie, of een lijst van geadresseerden. De notatie voor geadresseerden:

‘edustd:oin’: [OIN van de geadresseerde] of
‘edustd:oin’: [OIN van de geadresseerde inclusief zijn administratie-kenmerk].

Verplicht
p3 sub Onderwerp van de berichtuitwisseling (subject). Hier is mogelijk om hier het service-version kenmerk (d.w.z. de namespace van de service) in te vullen, zodat deze informatie beschikbaar is om additionele gegevens van de service en zijn endpoint in het OSR op te zoeken. Indien ingevuld, moet de volgende namespace worden gebruikt: http://osr-api.kennisnet.nl/api/v1 Optioneel
p4 iat Timestamp (seconden sinds epoch) waarop het token is aangemaakt (issued at). Verplicht
p5 nbf Tijdstip (seconden sinds epoch) vanaf welke het JWT token geldig is (not before). Als niet opgegeven, gelijk aan ‘iat’. Optioneel
p6 exp Tijdstip (seconden sinds epoch) tot welke het JWT token geldig is (expires). Als niet opgegeven, een uur (3.600.000 milliseconden) na iat. Optioneel
p7 edustd:body "edustd:body":{"hash":"...","alg":"B64SHA256"} Container voor velden 7.1 en 7.2. Verplicht
p7.1 hash De base64-geëncodeerde hashwaarde van het bericht zelf. Verplicht
p7.2 alg B64SHA256 Het algoritme waarmee de hashwaarde van het bericht is bepaald. Verplicht


* De volgende transformaties moeten worden gedaan om de hash te verkrijgen:
* body -> SHA256 -> base64 encoding


  • 4. Onderteken het bericht met behulp van de private key en encodeer het totale bericht.

De header en payload van het JWT token worden ondertekend met het algoritme en bijbehorende parameters dat in de header van het JWT token is beschreven.
Voor de ondertekening wordt de private sleutel van het PKI-overheids/ODOC certificaat gebruikt. De publieke sleutel wordt meegeleverd in het bericht, zodat de ontvangende partij het bericht kan valideren.


Het uiteindelijk JWT token bestaat uit 3 onderdelen:
header, payload data en ondertekening. Alle onderdelen zijn base64 url geencodeerd.

De 3 onderdelen worden gescheiden door een punt:

Jwt structuur.jpg












Voorbeeldcode

PHP using JOSE Library