Sample code for 30+ languages & platforms
Xbase++ 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 Xbase++ Downloads

Xbase++
LOCAL nSuccess
LOCAL oConfig
LOCAL oKey
LOCAL oHeader
LOCAL oJwt
LOCAL oPrng
LOCAL cNonce
LOCAL oClaims
LOCAL cAssertion
LOCAL oCurl

nSuccess := 0

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

nSuccess := 0

oConfig := CreateObject("Chilkat.JsonObject")
nSuccess := oConfig:LoadFile("qa_data/tokens/box_jwt_config.json")
IF (nSuccess != 1)
    ? oConfig:LastErrorText
    oConfig:destroy()
    RETURN
ENDIF

oKey := CreateObject("Chilkat.PrivateKey")
nSuccess := oKey:LoadEncryptedPem(oConfig:StringOf("boxAppSettings.appAuth.privateKey"), oConfig:StringOf("boxAppSettings.appAuth.passphrase"))
IF (nSuccess != 1)
    ? oKey:LastErrorText
    oConfig:destroy()
    oKey:destroy()
    RETURN
ENDIF

oHeader := CreateObject("Chilkat.JsonObject")
oHeader:UpdateString("alg", "RS256")
oHeader:UpdateString("typ", "JWT")
oHeader:UpdateString("kid", oConfig:StringOf("boxAppSettings.appAuth.publicKeyID"))
oJwt := CreateObject("Chilkat.Jwt")
oPrng := CreateObject("Chilkat.Prng")
cNonce := oPrng:GenRandom(32, "hex")
IF (oPrng:LastMethodSuccess != 1)
    ? oPrng:LastErrorText
    oConfig:destroy()
    oKey:destroy()
    oHeader:destroy()
    oJwt:destroy()
    oPrng:destroy()
    RETURN
ENDIF

oClaims := CreateObject("Chilkat.JsonObject")
oClaims:UpdateString("iss", oConfig:StringOf("boxAppSettings.clientID"))
oClaims:UpdateString("sub", oConfig:StringOf("enterpriseID"))
oClaims:UpdateString("box_sub_type", "enterprise")
oClaims:UpdateString("aud", "https://api.box.com/oauth2/token")
oClaims:UpdateString("jti", cNonce)
oClaims:UpdateInt("exp", oJwt:GenNumericDate(45))
cAssertion := oJwt:CreateJwtPk(oHeader:Emit(), oClaims:Emit(), oKey)
IF (oJwt:LastMethodSuccess != 1)
    ? oJwt:LastErrorText
    oConfig:destroy()
    oKey:destroy()
    oHeader:destroy()
    oJwt:destroy()
    oPrng:destroy()
    oClaims:destroy()
    RETURN
ENDIF

oCurl := CreateObject("Chilkat.HttpCurl")
oCurl:SetVar("client_id", oConfig:StringOf("boxAppSettings.clientID"))
oCurl:SetVar("client_secret", oConfig:StringOf("boxAppSettings.clientSecret"))
oCurl:SetVar("assertion", cAssertion)
oCurl:ClearTargetOutput("*")
oCurl:ClearVar("access_token")
oCurl:AddTargetOutput("access_token", "access_token")
nSuccess := oCurl:DoYourThing('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 ((nSuccess != 1) .OR. (oCurl:StatusCode != 200))
    ? "Box request failed. HTTP status: " + Str(oCurl:StatusCode)
    ? "Failure reason: " + Str(oCurl:FailReason)
    oConfig:destroy()
    oKey:destroy()
    oHeader:destroy()
    oJwt:destroy()
    oPrng:destroy()
    oClaims:destroy()
    oCurl:destroy()
    RETURN
ENDIF

IF (oCurl:VarDefined("!") != 1)
    ? "Expected response fields are missing."
    oConfig:destroy()
    oKey:destroy()
    oHeader:destroy()
    oJwt:destroy()
    oPrng:destroy()
    oClaims:destroy()
    oCurl:destroy()
    RETURN
ENDIF

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

oConfig:destroy()
oKey:destroy()
oHeader:destroy()
oJwt:destroy()
oPrng:destroy()
oClaims:destroy()
oCurl:destroy()