Token Endpoint
The next step is to claim an access_token
used to retrieve user claims by exchanging the authorization code received in the previous step at the Interac Hub's token_endpoint
.
POST /oauth2/token HTTP/1.1
Host: hub_server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=val1&code=val2&client_assertion_type=val3&client_assertion=val4&client_id=val5&redirect_uri=val6&code_verifier=val7
The request body has several parameters:
REQUIREMENT | PARAMETER | EXAMPLE VALUE | DESCRIPTION |
---|---|---|---|
Required | grant_type | authorization_code | Always set to authorization_code to indicate OAuth 2.0 authorization code grant flow. |
Required | code | 5GT81abUDETEOpVegW....hQHRcR8Q | The authorization code returned in the authorization grant response. The provisioned authorization code can only be redeemed once. |
Required | client_assertion_type | urn:ietf:params:oauth:client-assertion-type:jwt-bearer | This is always set to urn:ietf:params:oauth:client-assertion-type:jwt-bearer per RFC 7523 JSON Web Token Profile. |
Required | client_assertion | eyJhbGciOiJSUzI1NiI...\_9xOx-1_sYxA | Signed Client Assertion Object A client assertion object in a signed JWT (JWS) compact-serialized format. Refer to RFC 7519 JSON Web Tokens and RFC 7515 JWS compact serialization. This JWS must be signed by the RP using the private portion of an RSA keypair. The public portion is the one published to the RP's JWKS endpoint and registered with the Hub during onboarding (via the RP's JWKS URL). A number of parameters need to be included in this JWS and are detailed in the subsequent table. |
Required | client_id | hub-int-team | The same client ID used in the authorization grant request. |
Required | redirect_uri | http://localhost:5000/loginResponse | The same redirect URL used in the authorization grant request. |
Optional | code_verifier | lFDBK1ByvwTCqM2....\_N6pOq-Z | The PKCE code verifier string that the code_challenge hash was derived from in the authorization grant request |
Signed Client Assertion Object header:The client assertion JWT object header contains the following parameters.
REQUIREMENT | PARAMETER | EXAMPLE VALUE | DESCRIPTION |
---|---|---|---|
Required | alg | RS256 | Always RS256 to indicate the algorithm used. |
Required | kid | cIlDeR8D4RexrZmUdKhBxMsD2bMX4l87_5JrARh4VIU | The kid (key ID) parameter of the signing key must be provided in the JOSE Header of the signed request object to indicate to the Hub which of the RP keys to be used to validate the signature. |
Signed Client Assertion Object parameters: The client_assertion
parameter contains the signed client assertion object, as defined in RFC 7521 Assertion Framework for OAuth 2.0. This is a signed JWT (JWS) signed with the RP's private key in compact serialized format. The signed request object includes several parameters identifying the RP client.
REQUIREMENT | PARAMETER | EXAMPLE VALUE | DESCRIPTION |
---|---|---|---|
Required | iss | hub-int-team | The RP's client_id |
Required | sub | hub-int-team | The RP's client_id |
Required | aud | http://localhost:5000/loginResponse | The token_endpoint value as defined in the Hub's openid-configuration endpoint |
Required | exp | 1675972884.457038 | The expiration time (in UNIX timestamp format) of this client assertion object |
Optional | iat | 1675972584.457038 | The time (in UNIX timestamp format) at which this client assertion object was issued at |
Required | jti | 35a5bae49a834eb684c8c88ef7190475 | A unique identifier for this client assertion object |
Referenced Standard(s):OpenID Connect Core 1.0 (3.1.2.1. Authentication Request)
Example Request / Response
curl -X 'POST' \
'https://https://gateway-devportal2.pp.vids.dev/oauth2/token' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code&code=CLxk1GfMntiKySTLwv7hv-M3se69csC6xBh1KoFbToQ.FSL2GGz2VlxAr4zXwbckzdrunfzbMSlixYKQEh5KW4I&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6ImNJbERlUjhENFJleHJabVVkS2hCeE1zRDJiTVg0bDg3XzVKckFSaDRWSVUifQ.eyJhdWQiOiJodHRwczovL2dhdGV3YXktZGV2cG9ydGFsMi5wcC52aWRzLmRldi9vYXV0aDIvdG9rZW4iLCJleHAiOjE2NzU5NzI4ODQuNDU3MDM4LCJpYXQiOjE2NzU5NzI1ODQuNDU3MDM4LCJpc3MiOiJodWItaW50LXRlYW0iLCJqdGkiOiIzNWE1YmFlNDlhODM0ZWI2ODRjOGM4OGVmNzE5MDQ3NSIsInN1YiI6Imh1Yi1pbnQtdGVhbSJ9.QL169STxXxL4-Cpxokmf5C1KNAXgfJyjLa5rnrrpLnhpPdpelT_IUt1oaZ1itTFDtYhFjx1tBzBJULkNVncAX0EDCLUT_lLVGBX5bx_uSKPcJm9YOJI3HCgVYU3r_JvFiQbzr-mvWrMkvuFr8hOevu3nCNMwN3MlfWZ1t-ymgLnwy7dteN7v1MakUhDSxWY7tCIW0kJPMPfJzN8ciCBW-iJq-GZYyPF0n9t3ulHVuFxBNYQReYD0amektL4Iy5f_NqgivYIjYNKgDxTZwpKocK2BfVx2jqvGi___-y21FDos15nMLI76Sk_Bt3K_hPQc6eSDDiFWZ9_spWkKMUs5bA&client_id=hub-int-team&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2FloginResponse&code_verifier=lFDBK1ByvwTCqM2hxrGVVWcLVvjKkIeTE1JZ4ms_ZhDxPiiA7qt0YWBh8qi9_j1n7WM2-QairlqSoPWKjFEruthLJWI5gvyWIpe7bQyeMo95FE8pK0jOvs40_N6pOq-Z'
- grant_type=authorization_code
- code=CLxk1GfMntiKySTLwv7hv-M3se69csC6xBh1KoFbToQ.FSL2GGz2VlxAr4zXwbckzdrunfzbMSlixYKQEh5KW4I
- client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
- client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6ImNJbERlUjhENFJleHJabVVkS2hCeE1zRDJiTVg0bDg3XzVKckFSaDRWSVUifQ.eyJhdWQiOiJodHRwczovL2dhdGV3YXktZGV2cG9ydGFsMi5wcC52aWRzLmRldi9vYXV0aDIvdG9rZW4iLCJleHAiOjE2NzU5NzI4ODQuNDU3MDM4LCJpYXQiOjE2NzU5NzI1ODQuNDU3MDM4LCJpc3MiOiJodWItaW50LXRlYW0iLCJqdGkiOiIzNWE1YmFlNDlhODM0ZWI2ODRjOGM4OGVmNzE5MDQ3NSIsInN1YiI6Imh1Yi1pbnQtdGVhbSJ9.QL169STxXxL4-Cpxokmf5C1KNAXgfJyjLa5rnrrpLnhpPdpelT_IUt1oaZ1itTFDtYhFjx1tBzBJULkNVncAX0EDCLUT_lLVGBX5bx_uSKPcJm9YOJI3HCgVYU3r_JvFiQbzr-mvWrMkvuFr8hOevu3nCNMwN3MlfWZ1t-ymgLnwy7dteN7v1MakUhDSxWY7tCIW0kJPMPfJzN8ciCBW-iJq-GZYyPF0n9t3ulHVuFxBNYQReYD0amektL4Iy5f_NqgivYIjYNKgDxTZwpKocK2BfVx2jqvGi___-y21FDos15nMLI76Sk_Bt3K_hPQc6eSDDiFWZ9_spWkKMUs5bA
JWT header decoded:
{
"alg": "RS256",
"kid": "cIlDeR8D4RexrZmUdKhBxMsD2bMX4l87_5JrARh4VIU"
}
JWT body decoded:
{
"aud": "https://gateway-devportal2.pp.vids.dev/oauth2/token",
"exp": 1675972884.457038,
"iat": 1675972584.457038,
"iss": "hub-int-team",
"jti": "35a5bae49a834eb684c8c88ef7190475",
"sub": "hub-int-team"
}
- client_id=hub-int-team
- redirect_uri=http%3A%2F%2Flocalhost%3A5000%2FloginResponse
- code_verifier=lFDBK1ByvwTCqM2hxrGVVWcLVvjKkIeTE1JZ4ms_ZhDxPiiA7qt0YWBh8qi9_j1n7WM2-QairlqSoPWKjFEruthLJWI5gvyWIpe7bQyeMo95FE8pK0jOvs40_N6pOq-Z
The response to this POST request is a JSON message with the following parameters:
- access_token: The token to be used in the subsequent Hub UserInfo API call.
- expires_in: number of seconds until this token expires (default is 1800 seconds).
- id_token: A JWS containing metadata about this Hub transaction for informational purposes. Note the sub field will be a unique identifier representing the end user involved with this flow, specific to the RP/DAC.
- scope: The OIDC scope(s) provided in the authorization request.
- token_type: This will always be bearer to indicate that this token must be included as a Bearer token in the call to the Hub's token_endpoint.
Note that refresh_tokens are not supported. When this access_token expires or is used once, the RP/DAC will no longer be able to access the Hub's userinfo endpoint.
{
"access_token": "ILcyQprq2MDuC9oxmiRDP0x1v7pvYh1UzhjuAB0nsyg.cfChPkBMaNxVWSQgSkauyRYgQrZTJ1skshsAWGr9Qds",
"expires_in": 1800,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzo3N2U5MDEzNS00YTM1LTRkMmYtYTIwMi1mOTE5MzY2YTc5ZDYiLCJ0eXAiOiJKV1QifQ.eyJhdF9oYXNoIjoiblVVWFZtRTZaM2dvS2ZQUF9DTk05USIsImF1ZCI6WyJodWItaW50LXRlYW0iXSwiYXV0aF90aW1lIjoxNjc1OTcyNTE0LCJjbGllbnRfaWQiOiJodWItaW50LXRlYW0iLCJleHAiOjE2NzU5NzYxODUsImZsb3ciOiJWTUVfT05MWSIsImlhdCI6MTY3NTk3MjU4NSwiaXNzIjoiaHR0cHM6Ly9nYXRld2F5LnByZXByb2QuaHViLXZlcmlmeS5pbnRlcmFjLWlkLmNhLyIsImpvYl9pZCI6ImE1OGE5YWQxLWM2NzgtNDM5YS1iN2IzLTkxOGVjZDFjNWE4YSIsImp0aSI6IjQzY2JlZDdjLTgzZTItNDc1MC05ZDZkLTUyYTFjMzU3OTRmMSIsIm5vbmNlIjoiMDk1MzMzMTdmNDhjNDgzODk4NDFhZmRhY2M2NDU1Y2YiLCJyYXQiOjE2NzU5NzI0NzAsInNjb3BlIjoib25seVZtZSIsInNpZCI6IjVlYzVlOTY3LWZjYzctNDBkYi1iOGY1LWRhNTBiMTRmMmUzNiIsInN1YiI6ImE1OGE5YWQxLWM2NzgtNDM5YS1iN2IzLTkxOGVjZDFjNWE4YSJ9.rUtZqbpx1v-HgcbSdqRBkJfHpJrjJgXJ9N61Nk4Sg9IW2ftWcA1LONSoC_eYWnfci06LeKxD_WCNtKod1wkAggnIOWoRO3y05xlDJuIKezGI0vikSdVjgJD34myt52thInThRsceveVJrtFx8IFqivQy7UMJ1qsLUwGfDFMOjL2e6aaG1uvjn_GnN7fYGw1cpajj-favHC_eUp5zUGcTZT6GFC1TxY21yS4C6e_6zotmeWFiTYHZszkkSOG8rle1DxqiVnoQ5lUgA1OeWWc5wEZXD3ElH-9aheQlxrowu0vLZaSlbEs3tHWX6ECvf5kRjgMJjO6JsXBSfbekkuYexX1FVxHi46T7HamObRVJkJaKbQVOSwbJV4Hy7YrBP5hS6sxkRYL6SXspnwmu6J0V4EUlQqlouamFP7GftIpHowWbyTi-WOuU4C1wGA-B-EV7Ll57velDMimrVJ0as7Zu0eT94Jc1TGsaSNy1l9GuNk60hPmA-uGyO3Lz-4MZuYv2bVDRiwHUQV6MJU1TrXejZUW5hshfiA1RyD5HYXIenDW06zDW0DbKx9OWbUg44B9WQfV5h-p1wse1zEaXqP2jdK-NXb_ScbcJV2_J4icdgh4oAW0tPTeGZGSfekZpnvdzGM1kz-EE4TB62BYFmT3gS0uhpy3nY69oxx8YzYm2zp0",
"scope": "openid onlyVme",
"token_type": "bearer"
}
Updated about 1 year ago