Javascript Box JWT authentication Issues

Highlighted
New Contributor

Javascript Box JWT authentication Issues

Hi Friends,

 

I have developed some javascript code to access to box with JWT authentication.

Trying to get JWT token using javascript in stage environment and getting below error, We are trying to hit the https://api.box.com/oauth2/token from javascript, with grant_type : "urn:ietf:params:oauth:grant-type:jwt-bearer".

 

Error messages from the scripts:

{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}

 

My first script is like bellow:

====================================================================================

<!DOCTYPE html>
<html>

<head>
<title>JWT Token</title>
</head>

<body>

<div>JWT Token Process</div>

<script>
var loginUrl = "https://api.box.com/oauth2/token";
var xhr = new XMLHttpRequest();

const config = {
"boxAppSettings": {
"clientID": "12345",
"clientSecret": "xyz",
"appAuth": {
"publicKeyID": "345",
"privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\nREDACTED=\n-----END ENCRYPTED PRIVATE KEY-----\n",
"passphrase": "REDACTED"
}
},
"enterpriseID": "508727"
};

  1. var header = { "alg": "RS256", "typ": "JWT", "kid": config.boxAppSettings.appAuth.publicKeyID };
    var encodedHeader = btoa(header.toString('utf8'));
    console.log(encodedHeader);

let key = {
key: config.boxAppSettings.appAuth.privateKey,
passphrase: config.boxAppSettings.appAuth.passphrase
};
console.log(key);
const authenticationUrl = 'https://api.box.com/oauth2/token';

var array = new Uint32Array(1);
crypto.getRandomValues(array);
console.log(array[0]);

let claims = {
'iss': config.boxAppSettings.clientID,
'sub': config.enterpriseID,
'box_sub_type': 'enterprise',
'aud': authenticationUrl,
// This is an identifier that helps protect against
// replay attacks
'jti': array[0],
// We give the assertion a lifetime of 45 seconds
// before it expires
'exp': Math.floor(Date.now() / 1000) + 45
};

 

let keyId = config.boxAppSettings.appAuth.publicKeyID;
console.log(keyId);

var encodedClaim = btoa(claims.toString('utf8'));
console.log(encodedClaim);

var privateKey = config.boxAppSettings.appAuth.privateKey;
var encodedSignature = btoa(privateKey.toString('utf8'));

var encoded_jwt = encodedHeader + '.' + encodedClaim + '.' + encodedSignature;

console.log(encoded_jwt);


// Set the headers
var headers = {
'HTTP-Version': 'HTTP/1.1',
'Content-Type': 'application/x-www-form-urlencoded'
};

var bodyOptions = { 'grant_type': "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: encoded_jwt };

// Configure the request
var options = {
url: loginUrl,
method: 'POST',
headers: headers,
form: bodyOptions,
json: true
};


xhr.open('POST', loginUrl, true);
console.log(loginUrl);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
console.log("Setp2");


let assertion = encoded_jwt;
console.log(assertion);

var params = {
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: assertion,
client_id: config.boxAppSettings.clientID,
client_secret: config.boxAppSettings.clientSecret
};

var queryString = Object.keys(params).map(function (key) {
return key + '=' + params[key]
}).join('&');

console.log("Print queryString");
console.log(queryString);

console.log('going to send', queryString);
console.log("Setp5");
// xhr.send(sendObject);
xhr.send(queryString);
console.log("Setp6");

</script>
</body>

</html>

 

=====================================================

My Second script is like bellow:

====================================================================================

 

<!DOCTYPE html>
<html>

<head>
<title>JWT Auth</title>
</head>

<body>

<div>JWT Token Process</div>

<script>

const config = {
"boxAppSettings": {
"clientID": "12345",
"clientSecret": "xyz",
"appAuth": {
"publicKeyID": "5678",
"privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\nREDACTED=\n-----END ENCRYPTED PRIVATE KEY-----\n",
"passphrase": "REDACTED"
}
},
"enterpriseID": "508727"
};
let key = {
key: config.boxAppSettings.appAuth.privateKey,
passphrase: config.boxAppSettings.appAuth.passphrase
};
console.log(key);
const authenticationUrl = 'https://api.box.com/oauth2/token';

var array = new Uint32Array(1);
crypto.getRandomValues(array);
console.log(array[0]);

let claims = {
'iss': config.boxAppSettings.clientID,
'sub': config.enterpriseID,
'box_sub_type': 'enterprise',
'aud': authenticationUrl,
// This is an identifier that helps protect against
// replay attacks
'jti': array[0],
// We give the assertion a lifetime of 45 seconds
// before it expires
'exp': Math.floor(Date.now() / 1000) + 45
};
let keyId = config.boxAppSettings.appAuth.publicKeyID;
console.log(keyId);

var header = { "alg": "RS256", "typ": "JWT" };
var encodedHeader = btoa(header.toString('utf8'));
console.log("Print encodedHeader: ");
console.log(encodedHeader);

var encodedClaim = btoa(claims.toString('utf8'));
console.log("Print encodedClaim: ");
console.log(encodedClaim);

var privateKey = config.boxAppSettings.appAuth.privateKey;
var encodedSignature = btoa(privateKey.toString('utf8'));
console.log("Print encodedSignature: ");
console.log(encodedSignature);

var encoded_jwt = encodedHeader + '.' + encodedClaim + '.' + encodedSignature;
console.log("Print encoded_jwt: ");
console.log(encoded_jwt);

// Rather than constructing the JWT assertion manually, we are
// using the jsonwebtoken library.

let assertion = encoded_jwt;
console.log("Print assertion: ");
console.log(assertion);


// We are using the excellent axios package

var params = {
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: assertion,
client_id: config.boxAppSettings.clientID,
client_secret: config.boxAppSettings.clientSecret
};

var queryString = Object.keys(params).map(function (key) {
return key + '=' + params[key]
}).join('&');

console.log("Print queryString");
console.log(queryString);


// to simplify the API call

let accessToken = axios.post(

authenticationUrl,
queryString

/*

// JSON.stringify(
{

// This specifies that we are usinsg a JWT assertion

// to authenticate

grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
// grant_type: 'client_credentials',


// Our JWT assertion

assertion: assertion,

// The OAuth 2 client ID and secret

client_id: config.boxAppSettings.clientID,

client_secret: config.boxAppSettings.clientSecret

}
*/
// )

)

// Extract the access token from the API response

.then(response => response.data.access_token);

</script>
</body>

</html>

 

==============================================

 

Please someone guide us about what was went wrong in script and why did I get invaild param message from box server.

Thanks.