Skip to content

Instantly share code, notes, and snippets.

@milolav
Created March 8, 2021 00:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milolav/da713d2e6dd4c9d32a2d3afab38c7a18 to your computer and use it in GitHub Desktop.
Save milolav/da713d2e6dd4c9d32a2d3afab38c7a18 to your computer and use it in GitHub Desktop.
Oauth2 certificate authentication in bash for Microsoft Graph and Google APIs
set -e
client_email='client@your-project-name.iam.gserviceaccount.com'
subject_email='subject@example.com' #user that will be impersonated
scopes='https://www.googleapis.com/auth/<scope1> https://www.googleapis.com/auth/<scope2>'
key_file='my.key' #certificate private key (for signing)
jwt_header="{\"alg\":\"RS256\",\"typ\":\"JWT\"}"
ts=$(date +%s)
part_iss="\"iss\":\"$client_email\""
part_sub="\"sub\":\"$subject_email\""
part_scope="\"scope\":\"$scopes\""
part_aud="\"aud\":\"https://oauth2.googleapis.com/token\""
part_exp="\"exp\":\"$(($ts + 600))\""
part_iat="\"iat\":\"$ts\""
jwt_payload="{$part_iss,$part_sub,$part_scope,$part_aud,$part_exp,$part_iat}"
token_data="$(echo -n $jwt_header | base64 -w 0 | tr '/+' '_-' | tr -d '=').$(echo -n $jwt_payload | base64 -w 0 | tr '/+' '_-' | tr -d '=')"
signature=$(echo -n $token_data | openssl dgst -sha256 -sign $key_file | base64 -w 0 | tr '/+' '_-' | tr -d '=')
assertion="$token_data.$signature"
resp=$(curl -Ssl -X POST 'https://oauth2.googleapis.com/token' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
--data-urlencode "assertion=$assertion" \
)
if echo $resp | grep -q 'access_token'; then
echo $resp | jq -j '.access_token' >access_token
else
echo $resp | jq -r '.error + " error:\n" + .error_description'
exit 1
fi
#!/bin/bash
set -e
client_id='<replace_with_client_id>'
tenant_id='<replace_with_tenant_id>'
cert_file='my.crt' #certificate (used for fingerprint)
key_file='my.key' #certificate private key (for signing)
cert_hash=$(openssl x509 -fingerprint -noout -in $cert_file | cut -d '=' -f 2 | xxd -r -p | base64 -w 0| tr '/+' '_-' | tr -d '=')
jwt_header="{\"alg\":\"RS256\",\"typ\":\"JWT\",\"x5t\":\"$cert_hash\"}"
ts=$(date +%s)
part_aud="\"aud\":\"https://login.microsoftonline.com/$tenant_id/oauth2/v2.0/token\""
part_nbf="\"nbf\":$ts"
part_exp="\"exp\":$(($ts + 600))"
part_jti="\"jti\":\"$(cat /proc/sys/kernel/random/uuid)\""
part_iss="\"iss\":\"$client_id\""
part_sub="\"sub\":\"$client_id\""
jwt_payload="{$part_aud,$part_exp,$part_iss,$part_jti,$part_nbf,$part_sub}"
token_data="$(echo -n $jwt_header | base64 -w 0 | tr '/+' '_-' | tr -d '=').$(echo -n $jwt_payload | base64 -w 0 | tr '/+' '_-' | tr -d '=')"
signature=$(echo -n $token_data | openssl dgst -sha256 -sign $key_file | base64 -w 0 | tr '/+' '_-' | tr -d '=')
assertion="$token_data.$signature"
resp=$(curl -Ssl -X POST "https://login.microsoftonline.com/$tenant_id/oauth2/v2.0/token" \
--data-urlencode "client_id=$client_id" \
--data-urlencode 'scope=https://graph.microsoft.com/.default' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode "client_assertion=$assertion" \
--data-urlencode 'grant_type=client_credentials' \
)
if echo $resp | grep -q 'access_token'; then
echo $resp | jq -j '.access_token' >access_token
else
echo $resp | jq -r '.error + " error:\n" + .error_description'
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment