Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create the access token using app user id in Box-API?

I'm trying to create the access token using box app user id. I have use the following code to create the box app user

curl https://api.box.com/2.0/users \
-H "Authorization: Bearer <TOKEN>" \
-d '{"name": "Ned Stark", "is_platform_access_only": true}' \
-X POST

Then it is give the following result

{"type":"user","id":"2199107004","name":"Ned Stark","login":"[email protected]","created_at":"2017-08-03T00:58:04-07:00"

Is it possible to generate the access token using box app user id.?

Edited

I have generate the Public key in BOX API. Then I have file which is having Public key and Private key detail like as bellow,

{
  "boxAppSettings": {
    "clientID": <Client ID>,
    "clientSecret": <clientsecret>,
    "appAuth": {
      "publicKeyID": <publickeyid>,
      "privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\Key heresn-----END ENCRYPTED PRIVATE KEY-----\n",
      "passphrase": <phrase>
    }
  },
  "enterpriseID": <enterpriseId>
}

Then I have generate header and payload, which is as follow

$header = ["typ"=> "JWT", "alg"=>"RS256","kid"=> <public key id>];

$payload = [
    "iss"=> "<client id>",
    "sub"=> "<APP USER ID>",
    "box_sub_type"=> "user",
    "aud"=>"https://api.box.com/oauth2/token",
    "jti"=>"<I don't know what is this>",
    "exp"=>1428699385
];
$header = base64_encode(json_encode($header));
$payload = base64_encode(json_encode($payload));

After this I got stuck how to implement the private and public key here. Actually I'm having the JSON file which is downloaded from BOX API. And I can't understand what is the JTI? How to add the public key and|or private key JSON file in this? How to do it?


And I have generate the private key manually as per document, as follow

openssl genrsa -aes256 -out private_key.pem 2048

Then I gave the password as "12345". And generate public key as follow,

openssl rsa -pubout -in private_key.pem -out public_key.pem

Then I added the public key in BOX-API and I made a code as follow,

$data = file_get_contents('private_key.pem');
$result = openssl_pkey_get_private($data,"12345"); 
print_r($result);

It gives the following result

Resource id #4

These is not looking like encrypted data. And how to implement private and public when calling box api in php.?

like image 687
mkHun Avatar asked Aug 03 '17 07:08

mkHun


People also ask

How do I get access token box API?

If you are using OAuth 2.0, use the provided Refresh Token to obtain a new Access Token. If you are using server authentication, JWT or Client Credentials Grant, make an API call to the token endpoint to request a new Access Token.

What is access token in API?

What is an Access Token? A credential that can be used by an application to access an API. Access Tokens can be either an opaque string or a JSON Web Token (JWT) . They inform the API that the bearer of the token has been authorized: to access a particular service or services.

How do I get refresh token box API?

To refresh the access token, select the Refresh access token API call within the Authorization folder of the Postman collection. Next, click the Send button to request a new access_token .


1 Answers

I won't recommend you to implement this yourself since there are already a couple of libraries implementing this protocol. However I split my answer into 2 parts the first part explains how to use an open source package to solve your problem, the second part helps you out if you want to do private keys signing.

Using a package

There are a couple of php packages that support JWT signing, at the moment of writing the one that is used most is lcobucci/jwt, but there are also other implementations found here: https://packagist.org/search/?q=jwt

You can use composer to install it. Since version 4.0 is not documented right now I suggest you install 3.2 and have a look at the README file of that version.

You can require this in your project using: composer require lcobucci/jwt:^3.2

Your code sample suggests you need RSA256, the library has an example for that:

<?php
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Keychain; // just to make our life simpler
use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys

$signer = new Sha256();
$keychain = new Keychain();
$token = (new Builder())
    ->setIssuer('http://example.com') // Configures the issuer (iss claim)
    ->setAudience('http://example.org') // Configures the audience (aud claim)
    ->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
    ->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)
    ->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim)
    ->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)
    ->set('uid', 1) // Configures a new claim, called "uid"
    ->sign($signer,  $keychain->getPrivateKey('file://{path to your private key}')) // creates a signature using your private key
    ->getToken(); // Retrieves the generated token

Signing and verifying

When using public and private keys you always have to be sure to keep your private key safe. You can however easily publish your public key to the world without compromising security.

Signing is done using the private key, since you don't want people to be able to fake your signature, signing with the public part would make it possible for everyone to do it. This also means that the verify step always uses the public key, because everyone should be able to do it.

Doing it in PHP

The code example you provided simply loads a private key, but does not do any action with it. In order to sign you will need to use openssl_sign with your variable. Resource #xx simply means a reference to something external in php.

<?php
// Data to sign
$payload = 'TEST';
// Generate a new key, load with: openssl_pkey_get_private
$privateKey = openssl_pkey_new(array('private_key_bits' => 512)); // NOT SECURE BUT FAST
// Extract public part from private key
$details = openssl_pkey_get_details($privateKey);
// Use openssl_pkey_get_public to load from file
$publicKey = $details['key'];

// Generated by openssl_sign
$signature = null;
// Sign with private key
openssl_sign($payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);

// Use base64 because the signature contains binairy data
echo 'Signed data: '.base64_encode($signature).PHP_EOL;

// Use publicKey to verify signature
$valid = openssl_verify($payload, $signature, $publicKey, OPENSSL_ALGO_SHA256);
echo 'Signature is '.($valid ? 'Valid' : 'Invalid').PHP_EOL;

What else

If you still want to implement the complete protocol I suggest you have another look at the package. And as already suggested by the comments the complete specification:

https://www.rfc-editor.org/rfc/rfc7519.txt

Last hint: JWT uses some different characters for base64 than php so be sure to handle that correctly.

like image 108
ReenL Avatar answered Oct 20 '22 16:10

ReenL