Sample code for 30+ languages & platforms
PureBasic

PRODA Get OAuth2 Access Token using JWT

See more PRODA Examples

Demonstrates how to get an OAuth2 access token for the PRODA Australian Government Online Services using a JWT.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkJsonObject.pb"
IncludeFile "CkJwt.pb"
IncludeFile "CkPrivateKey.pb"
IncludeFile "CkHttp.pb"
IncludeFile "CkHttpRequest.pb"
IncludeFile "CkHttpResponse.pb"

Procedure ChilkatExample()

    success.i = 0

    ; This example requires the Chilkat API to have been previously unlocked.
    ; See Global Unlock Sample for sample code.

    ; First create a JWT to be sent in the POST to https://vnd.proda.humanservices.gov.au/mga/sps/oauth/oauth20/token

    privKey.i = CkPrivateKey::ckCreate()
    If privKey.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ; Load an RSA private key from a PEM file.
    ; Chilkat provides alternative methods to load from other formats, or to load from a string or binary data.
    success = CkPrivateKey::ckLoadEncryptedPemFile(privKey,"qa_data/pem/rsa_passwd.pem","passwd")
    If success = 0
        Debug CkPrivateKey::ckLastErrorText(privKey)
        CkPrivateKey::ckDispose(privKey)
        ProcedureReturn
    EndIf

    jwt.i = CkJwt::ckCreate()
    If jwt.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ; Build the JOSE header
    jose.i = CkJsonObject::ckCreate()
    If jose.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    ; Use RS256.  Pass the string "RS384" or "RS512" to use RSA with SHA-384 or SHA-512.
    success = CkJsonObject::ckAppendString(jose,"alg","RS256")
    success = CkJsonObject::ckAppendString(jose,"typ","JWT")
    success = CkJsonObject::ckAppendString(jose,"kid","test-device")

    ; Now build the JWT claims (also known as the payload)
    claims.i = CkJsonObject::ckCreate()
    If claims.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkJsonObject::ckAppendString(claims,"iss","9646844092")
    success = CkJsonObject::ckAppendString(claims,"sub","test-device")
    success = CkJsonObject::ckAppendString(claims,"aud","https://proda.humanservices.gov.au")

    ; Set the timestamp of when the JWT was created to now.
    curDateTime.i = CkJwt::ckGenNumericDate(jwt,0)
    success = CkJsonObject::ckAddIntAt(claims,-1,"iat",curDateTime)

    ; Set the timestamp defining an expiration time (end time) for the token
    ; to be now + 1 hour (3600 seconds)
    success = CkJsonObject::ckAddIntAt(claims,-1,"exp",curDateTime + 3600)

    ; Produce the smallest possible JWT:
    CkJwt::setCkAutoCompact(jwt, 1)

    ; Create the JWT token.  This is where the RSA signature is created.
    jwtToken.s = CkJwt::ckCreateJwtPk(jwt,CkJsonObject::ckEmit(jose),CkJsonObject::ckEmit(claims),privKey)

    ; ---------------------------------------------------------------------
    ; Build and send the POST, which should look something like this:

    ; POST https://vnd.proda.humanservices.gov.au/mga/sps/oauth/oauth20/token HTTP/1.1
    ; Content-Type: application/x-www-form-urlencoded
    ; Content-Length: 666
    ; Host: vnd.proda.humanservices.gov.au
    ; 
    ; grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<jwt>&client_id=VendorClient03

    http.i = CkHttp::ckCreate()
    If http.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    req.i = CkHttpRequest::ckCreate()
    If req.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkHttpRequest::setCkHttpVerb(req, "POST")
    CkHttpRequest::setCkContentType(req, "application/x-www-form-urlencoded")

    ; Add the request params.
    CkHttpRequest::ckAddParam(req,"grant_type","urn:ietf:params:oauth:grant-type:jwt-bearer")
    CkHttpRequest::ckAddParam(req,"assertion",jwtToken)
    CkHttpRequest::ckAddParam(req,"client_id","VendorClient03")

    resp.i = CkHttpResponse::ckCreate()
    If resp.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkHttp::ckHttpReq(http,"https://vnd.proda.humanservices.gov.au/mga/sps/oauth/oauth20/token",req,resp)
    If success = 0
        Debug CkHttp::ckLastErrorText(http)
        CkPrivateKey::ckDispose(privKey)
        CkJwt::ckDispose(jwt)
        CkJsonObject::ckDispose(jose)
        CkJsonObject::ckDispose(claims)
        CkHttp::ckDispose(http)
        CkHttpRequest::ckDispose(req)
        CkHttpResponse::ckDispose(resp)
        ProcedureReturn
    EndIf

    Debug "Response status code = " + Str(CkHttpResponse::ckStatusCode(resp))
    Debug "Response body:"
    Debug CkHttpResponse::ckBodyStr(resp)


    CkPrivateKey::ckDispose(privKey)
    CkJwt::ckDispose(jwt)
    CkJsonObject::ckDispose(jose)
    CkJsonObject::ckDispose(claims)
    CkHttp::ckDispose(http)
    CkHttpRequest::ckDispose(req)
    CkHttpResponse::ckDispose(resp)


    ProcedureReturn
EndProcedure