Created
September 28, 2017 03:19
-
-
Save floudet/5f5870d0551fcdb663969df6fcf7bfce to your computer and use it in GitHub Desktop.
Request OAuth2.0 Access tokens for Box.com using JWT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Request OAuth2.0 Access tokens for Box.com using JWT | |
# | |
# Thanks: | |
# https://developer.box.com/v2.0/docs/construct-jwt-claim-manually | |
# https://developer.box.com/v2.0/blog/box-tokener-a-nodejs-command-line-tool-to-generate-box-api-tokens | |
# http://willhaley.com/blog/generate-jwt-with-bash/ | |
PRIVATE_KEY="" | |
PASSPHRASE="" | |
CLIENT_ID="" | |
CLIENT_SECRET="" | |
KEY_ID="" | |
USER_ID="" | |
EXP=30 | |
# Display Usage | |
_usage() { | |
echo "Usage: $0 -k private_key -p passphrase -c client_id -s client_secret -i key_id -u user_id [ -e expiration ]" | |
echo "Mandatory: " | |
echo " -k file path to private key" | |
echo " -p passphrase associated with the private key" | |
echo " -c Client ID (API key for Box Platform)" | |
echo " -s Client Secret" | |
echo " -i the public key id found in developer console" | |
echo " -u User ID" | |
echo "Optional: " | |
echo " -e JWT expiration in seconds (max 60, default 30)" | |
exit -1 | |
} | |
# Get options from command line | |
if [[ -z $1 ]]; then _usage; exit -1; fi | |
if [[ $1 == "--help" ]]; then _usage; exit -1; fi | |
while getopts "k:p:c:s:i:u:e:" ARG | |
do | |
case "$ARG" in | |
k) | |
PRIVATE_KEY=$OPTARG | |
;; | |
p) | |
PASSPHRASE=$OPTARG | |
;; | |
c) | |
CLIENT_ID=$OPTARG | |
;; | |
s) | |
CLIENT_SECRET=$OPTARG | |
;; | |
i) | |
KEY_ID=$OPTARG | |
;; | |
u) | |
USER_ID=$OPTARG | |
;; | |
e) | |
EXP=$OPTARG | |
;; | |
*) _usage | |
;; | |
esac | |
done | |
# Check options | |
if [[ -z $PRIVATE_KEY || $PRIVATE_KEY == "" ]];then | |
echo "-k option is mandatory" | |
_usage | |
fi | |
if [[ -z $PASSPHRASE || $PASSPHRASE == "" ]];then | |
echo "-p option is mandatory" | |
_usage | |
fi | |
if [[ -z $CLIENT_ID || $CLIENT_ID == "" ]];then | |
echo "-c option is mandatory" | |
_usage | |
fi | |
if [[ -s $CLIENT_SECRET || $CLIENT_SECRET == "" ]];then | |
echo "-s option is mandatory" | |
_usage | |
fi | |
if [[ -s $KEY_ID || $KEY_ID == "" ]];then | |
echo "-i option is mandatory" | |
_usage | |
fi | |
if [[ -s $USER_ID || $USER_ID == "" ]];then | |
echo "-u option is mandatory" | |
_usage | |
fi | |
if [[ $EXP -lt 1 || $EXP -gt 60 ]];then | |
echo "JWT expiration should be between 1 and 60" | |
exit -1 | |
fi | |
TOKEN_EXP=$(($(date +%s) + $EXP)) # max 60s | |
JTI=$(cat /dev/urandom | LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1) | |
# RS256 = RSA Signature with SHA-256 | |
read -r -d '' JA_HEADER << EOM | |
{ | |
"alg": "RS256", | |
"typ": "JWT", | |
"kid": "$KEY_ID" | |
} | |
EOM | |
# CLAIM = PAYLOAD | |
read -r -d '' JA_CLAIM << EOM | |
{ | |
"iss": "$CLIENT_ID", | |
"sub": "$USER_ID", | |
"box_sub_type": "user", | |
"aud": "https://api.box.com/oauth2/token", | |
"jti": "$JTI", | |
"exp": $TOKEN_EXP | |
} | |
EOM | |
function base64_encode() { | |
declare INPUT=${1:-$(</dev/stdin)} | |
echo -n "${INPUT}" | openssl enc -base64 -A | |
} | |
function json() { | |
declare INPUT=${1:-$(</dev/stdin)} | |
echo -n "${INPUT}" | jq -c . | |
} | |
function rs256_sign() { | |
declare INPUT=${1:-$(</dev/stdin)} | |
echo -n "${INPUT}" | openssl dgst -sha256 -sign $PRIVATE_KEY -passin pass:$PASSPHRASE | |
} | |
JA_HEADER_BASE64=$(echo "${JA_HEADER}" | json | base64_encode) | |
JA_CLAIM_BASE64=$(echo "${JA_CLAIM}" | json | base64_encode) | |
JA_HEADER_CLAIM=$(echo "${JA_HEADER_BASE64}.${JA_CLAIM_BASE64}") | |
JA_SIGNATURE=$(echo "${JA_HEADER_CLAIM}" | rs256_sign | base64_encode) | |
JWT_ASSERTION=$(echo "${JA_HEADER_CLAIM}.${JA_SIGNATURE}") | |
curl https://api.box.com/oauth2/token \ | |
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&assertion=$JWT_ASSERTION" \ | |
-X POST |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment