DPoP

“Demonstrating Proof-of-Posession” biedt de mogelijkheid om tokens te linken aan de orriginele aanvrager

DPoP is een techniek die toelaat om een (access- of refresh-) token te linken aan een publiek/privaat sleutelpaar. Wanneer een dergelijk token gebruikt wordt, zal de client moeten bewijzen dat deze in het bezit is van de private sleutel, gelinkt aan het token.
Op die manier worden tokens beperkter bruikbaar: met name enkel door clients die over het gelinkte sleutelpaar beschikken. DPoP beperkt effectief het aantal clients die deze tokens kunnen gebruiken, maar zijn geen alternatief voor client authenticatie.

Gedetailleerde werking van DPoP wordt beschreven in internet draft voor oauth dpop

Bij het ophalen van een access- of refresh token op het token endpoint stuurt de client een signed JWT door in een header met de naam dpop. Uitgeleverde tokens zullen dan gelinkt worden aan de JWK die gebruikt werd voor het signen van dit JWT. Het is dan aan de resource servers om - bij gebruik van deze tokens - te valideren dat de client kan aantonen dat hij over de private key beschikt die aan het token gelinkt werd (opnieuw via een DPoP header)

Op deze manier kan voorkomen worden dat gestolen of gelekte tokens gebruikt worden door malafide partijen: de tokens zijn immers enkel geldig wanneer kan aangetoond worden dat niet alleen het token, maar ook de private key van het gelinkte sleutelpaar in het bezit is van de client.

DPoP header

Wanneer een DPoP header wordt meegestuurd naar het token endpoint, zal de openid provider deze valideren en het token linken aan de JWK die gebruikt werd om de DPoP proof (value van de DPoP header) te ondertekenen. In het antwoord zal het token endpoint hier kennis van geven door de waarde DPoP toe te kennen aan de parameter token_type

Een DPoP proof is een JWT met in de header volgende parameters:

parameter omschrijving
typ geeft aan dat het over een dpop proof gaat. (dpop+jwt is de enige toegelaten waarde)
alg het gebruikte algoritme voor ondertekenen van de DPoP. symmetrische algoritmes of none zijn niet toegelaten.
jwk de JWK (enkele het publieke deel) die gebruikt werd om de JWT te signen

De DPoP proof bevat onderstaande claims

parameter omschrijving
iat timestamp van het aanmaken van de DPoP proof (seconden sinds 1/1/1970) Deze mag niet meer dan 30 seconden afwijken van de waarde op de server.
htm de gebruikte HTTP method, gelinkt aan dit JWT. In de meeste gevallen zal dit “POST” zijn.
htu het HTTP target endpoint (zonder query parameters en fragments). Voor het acm token endpoint is dat https://authenticatie.vlaanderen.be/op/v1/token
jti unieke waarde voor deze DPoP proof die replay voorkomt. Wanneer eenzelfde jti waarde wordt herkend in opeenvolgende requests, zal deze proof niet aanvaard worden.

Een voorbeeld van een (deserialized) dpop proof zou er als volgt kunnen uit zien:

{
  "typ":"dpop+jwt",
  "alg":"ES256",
  "jwk": {
    "kty":"EC",
    "x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
    "y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
    "crv":"P-256"
  }
}
.
{
  "jti":"-BwC3ESc6acc2lTc",
  "htm":"POST",
  "htu":"https://server.example.com/token",
  "iat":1562262616
}

DPop bound tokens

Wanneer een access token gebonden is aan een sleutelpaar via DPoP, zal het token endpoint dit aan geven door token_type=DPoP toe te voegen in het antwoord. In dat geval zal het id-token uitgebreid worden met een property cnf. Dit is een object met een property jkt, die als waarde de thumbprint van de JWK (gebruikt voor het signen van de DPoP proof) bevat.

Zowel in het id-token als in het antwoord van het introspection endpoint zal deze informatie terug komen.

Merk op dat de openid provider zelf niet beschikt over de private key van het gelinkte sleutelpaar. Bij gevolg dient de resource server zelf de validatie te doen van de DPoP header bij gebruik van DPoP beschermde tokens. Dit wordt hier in detail beschreven.

DPoP bound authorization codes

DPoP headers worden door de openid provider enkel geïnterpreteerd op het token endpoint omdat dit de plaats is waar tokens worden uitgeleverd. In de authorization code grant flow, kan het wenselijk zijn om ook de code al te binden aan een sleutelpaar, zodat de volledige authenticatie gelinkt kan worden aan een sleutelpaar.

Dit kan door bij het initiële request (naar het authorization endpoint) een parameter dpop_jkt mee te geven met daarin de thumbprint van de JWK die zal gebruikt worden om de DPoP proof te signen. Wanneer dat gebeurt, zal een authorization code enkel kunnen ingewisseld worden voor een access token indien een geldige DPoP proof wordt meegestuurd naar het token endpoint.

Een dergelijk request zou er als volgt kunnen uit zien:

 GET /op/v1/authz?response_type=code&client_id=bfbff34f-0c00-443f-8ed9-fb52e4919a0d&state=xyz
     &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
     &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
     &code_challenge_method=S256
     &dpop_jkt=NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs HTTP/1.1