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

Delphi DLL
var
success: Boolean;
config: HCkJsonObject;
key: HCkPrivateKey;
header: HCkJsonObject;
jwt: HCkJwt;
prng: HCkPrng;
nonce: PWideChar;
claims: HCkJsonObject;
assertion: PWideChar;
curl: HCkHttpCurl;

begin
success := False;

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

success := False;

config := CkJsonObject_Create();
success := CkJsonObject_LoadFile(config,'qa_data/tokens/box_jwt_config.json');
if (success <> True) then
  begin
    Memo1.Lines.Add(CkJsonObject__lastErrorText(config));
    Exit;
  end;
key := CkPrivateKey_Create();
success := CkPrivateKey_LoadEncryptedPem(key,CkJsonObject__stringOf(config,'boxAppSettings.appAuth.privateKey'),CkJsonObject__stringOf(config,'boxAppSettings.appAuth.passphrase'));
if (success <> True) then
  begin
    Memo1.Lines.Add(CkPrivateKey__lastErrorText(key));
    Exit;
  end;
header := CkJsonObject_Create();
CkJsonObject_UpdateString(header,'alg','RS256');
CkJsonObject_UpdateString(header,'typ','JWT');
CkJsonObject_UpdateString(header,'kid',CkJsonObject__stringOf(config,'boxAppSettings.appAuth.publicKeyID'));
jwt := CkJwt_Create();
prng := CkPrng_Create();
nonce := CkPrng__genRandom(prng,32,'hex');
if (CkPrng_getLastMethodSuccess(prng) <> True) then
  begin
    Memo1.Lines.Add(CkPrng__lastErrorText(prng));
    Exit;
  end;
claims := CkJsonObject_Create();
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));
assertion := CkJwt__createJwtPk(jwt,CkJsonObject__emit(header),CkJsonObject__emit(claims),key);
if (CkJwt_getLastMethodSuccess(jwt) <> True) then
  begin
    Memo1.Lines.Add(CkJwt__lastErrorText(jwt));
    Exit;
  end;
curl := CkHttpCurl_Create();
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');
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 ((success <> True) or (CkHttpCurl_getStatusCode(curl) <> 200)) then
  begin
    Memo1.Lines.Add('Box request failed. HTTP status: ' + IntToStr(CkHttpCurl_getStatusCode(curl)));
    Memo1.Lines.Add('Failure reason: ' + IntToStr(CkHttpCurl_getFailReason(curl)));
    Exit;
  end;
if (CkHttpCurl_VarDefined(curl,'!') <> True) then
  begin
    Memo1.Lines.Add('Expected response fields are missing.');
    Exit;
  end;
//  Reuse the token in this HttpCurl instance. JWT tokens are renewed by making
//  a new assertion/token request, not by using a refresh token.
Memo1.Lines.Add('JWT access token obtained.');

CkJsonObject_Dispose(config);
CkPrivateKey_Dispose(key);
CkJsonObject_Dispose(header);
CkJwt_Dispose(jwt);
CkPrng_Dispose(prng);
CkJsonObject_Dispose(claims);
CkHttpCurl_Dispose(curl);