Sample code for 30+ languages & platforms
Tcl Requires Chilkat v11.5.0+

Box: Get a Service Account Token with JWT

See more Box Examples

Use the encrypted private key in a Box application configuration file to sign a short-lived assertion and exchange it for an access token. Configure and authorize a JWT Server app first. The enterprise subject obtains the service-account token.

See the Box API guide for setup and the complete workflow.

Chilkat Tcl Downloads

Tcl

load ./chilkat.dll

set success 0

#  Requires Chilkat 11.5.0 or later and a previously unlocked Chilkat bundle.
#  See Global Unlock Sample.
#  Guide: Box API Guide.

set success 0

set config [new_CkJsonObject]

set success [CkJsonObject_LoadFile $config "qa_data/tokens/box_jwt_config.json"]
if {$success != 1} then {
    puts [CkJsonObject_lastErrorText $config]
    delete_CkJsonObject $config
    exit
}

set key [new_CkPrivateKey]

set success [CkPrivateKey_LoadEncryptedPem $key [CkJsonObject_stringOf $config "boxAppSettings.appAuth.privateKey"] [CkJsonObject_stringOf $config "boxAppSettings.appAuth.passphrase"]]
if {$success != 1} then {
    puts [CkPrivateKey_lastErrorText $key]
    delete_CkJsonObject $config
    delete_CkPrivateKey $key
    exit
}

set header [new_CkJsonObject]

CkJsonObject_UpdateString $header "alg" "RS256"
CkJsonObject_UpdateString $header "typ" "JWT"
CkJsonObject_UpdateString $header "kid" [CkJsonObject_stringOf $config "boxAppSettings.appAuth.publicKeyID"]
set jwt [new_CkJwt]

set prng [new_CkPrng]

set nonce [CkPrng_genRandom $prng 32 "hex"]
if {[CkPrng_get_LastMethodSuccess $prng] != 1} then {
    puts [CkPrng_lastErrorText $prng]
    delete_CkJsonObject $config
    delete_CkPrivateKey $key
    delete_CkJsonObject $header
    delete_CkJwt $jwt
    delete_CkPrng $prng
    exit
}

set claims [new_CkJsonObject]

CkJsonObject_UpdateString $claims "iss" [CkJsonObject_stringOf $config "boxAppSettings.clientID"]
CkJsonObject_UpdateString $claims "sub" [CkJsonObject_stringOf $config "enterpriseID"]
CkJsonObject_UpdateString $claims "box_sub_type" "enterprise"
CkJsonObject_UpdateString $claims "aud" "https://api.box.com/oauth2/token"
CkJsonObject_UpdateString $claims "jti" $nonce
CkJsonObject_UpdateInt $claims "exp" [CkJwt_GenNumericDate $jwt 45]
set assertion [CkJwt_createJwtPk $jwt [CkJsonObject_emit $header] [CkJsonObject_emit $claims] $key]
if {[CkJwt_get_LastMethodSuccess $jwt] != 1} then {
    puts [CkJwt_lastErrorText $jwt]
    delete_CkJsonObject $config
    delete_CkPrivateKey $key
    delete_CkJsonObject $header
    delete_CkJwt $jwt
    delete_CkPrng $prng
    delete_CkJsonObject $claims
    exit
}

set curl [new_CkHttpCurl]

CkHttpCurl_SetVar $curl "client_id" [CkJsonObject_stringOf $config "boxAppSettings.clientID"]
CkHttpCurl_SetVar $curl "client_secret" [CkJsonObject_stringOf $config "boxAppSettings.clientSecret"]
CkHttpCurl_SetVar $curl "assertion" $assertion
CkHttpCurl_ClearTargetOutput $curl "*"
CkHttpCurl_ClearVar $curl "access_token"
CkHttpCurl_AddTargetOutput $curl "access_token" "access_token"
set success [CkHttpCurl_DoYourThing $curl "curl -X POST \"https://api.box.com/oauth2/token\" --data-urlencode \"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer\" --data-urlencode \"client_id={{client_id}}\" --data-urlencode \"client_secret={{client_secret}}\" --data-urlencode \"assertion={{assertion}}\""]
if {expr [$success != 1]  ||  [[CkHttpCurl_get_StatusCode $curl] != 200]} then {
    puts "Box request failed. HTTP status: [CkHttpCurl_get_StatusCode $curl]"
    puts "Failure reason: [CkHttpCurl_get_FailReason $curl]"
    delete_CkJsonObject $config
    delete_CkPrivateKey $key
    delete_CkJsonObject $header
    delete_CkJwt $jwt
    delete_CkPrng $prng
    delete_CkJsonObject $claims
    delete_CkHttpCurl $curl
    exit
}

if {[CkHttpCurl_VarDefined $curl "!"] != 1} then {
    puts "Expected response fields are missing."
    delete_CkJsonObject $config
    delete_CkPrivateKey $key
    delete_CkJsonObject $header
    delete_CkJwt $jwt
    delete_CkPrng $prng
    delete_CkJsonObject $claims
    delete_CkHttpCurl $curl
    exit
}

#  Reuse the token in this HttpCurl instance. JWT tokens are renewed by making
#  a new assertion/token request, not by using a refresh token.
puts "JWT access token obtained."

delete_CkJsonObject $config
delete_CkPrivateKey $key
delete_CkJsonObject $header
delete_CkJwt $jwt
delete_CkPrng $prng
delete_CkJsonObject $claims
delete_CkHttpCurl $curl