I am trying to use the OAuth 2.0 JWT Bearer Token Flow to get my access token for future api requests using Python 3.7 but I am receiving the following error:
{"error":"unsupported_grant_type","error_description":"grant type not supported"}
Here is my code,
import requests
import base64
import datetime
import jks
import OpenSSL
import urllib
import math
iss = '3MVG9G9pzCUSkzZs8CmmhEFtWNL2CMUdfINoZ0jVZgIxmEHXLkj2DQASd4zvCJeGOML.fZje7.y5yMyU<last couple of characters removed'
aud = 'https://login.salesforce.com'
sub = '[email protected]'
exp = str(math.floor(((datetime.datetime.now()+ datetime.timedelta(minutes = 5))-datetime.datetime(1970,1,1,0,0,0)).total_seconds()))
jwtHeader = str('{"alg":"RS256"}')
jwtClaims = str('{"iss":"' + iss + '","sub":"' + sub + '","aud":"' + aud + '","exp":"' + exp + '"}')
jwtRequest = str(base64.urlsafe_b64encode(jwtHeader.encode('utf-8')).decode('utf-8')) + '.' + str(base64.urlsafe_b64encode(jwtClaims.encode('utf-8')).decode('utf-8'))
"import java key store extracted from Salesforce"
ks = jks.KeyStore.load('XXXXX.jks', 'XXXXX')
"convert to OpenSSL private key format using ASN1 - also do this for the cert"
_ASN1 = OpenSSL.crypto.FILETYPE_ASN1
pkey = OpenSSL.crypto.load_privatekey(_ASN1, pk_entry.pkey)
cert = OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM,
open('WMDataLake.crt').read()
)
"check private key conversion is correct"
OpenSSL.crypto.PKey.check(pkey)
"use private key to sign request"
oSSLsign = OpenSSL.crypto.sign(pkey, jwtRequest.encode('utf-8'), "RSA-SHA256")
"verify signature is correct"
OpenSSL.crypto.verify(cert, oSSLsign, jwtRequest.encode('utf-8'), "RSA-SHA256")
Signature = str(base64.urlsafe_b64encode(oSSLsign).decode('utf-8'))
signedJwtRequest = jwtRequest + '.' + Signature
grantype = str('urn:ietf:params:oauth:grant-type:jwt-bearer')
payload = 'grant_type=' + str(urllib.parse.quote(grantype))
payload += '&assertion=' + signedJwtRequest
r = requests.post("https://login.salesforce.com/services/oauth2/token", data=payload)
print(r.text)
This is my resulting payload:
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiIzTVZHOUc5cHpDVVNrelpzOENtbWhFRnRXTkwyQ01VZGZJTm9aMGpWWmdJeG1FSFhMa2oyRFFBU2Q0enZDSmVHT01MLmZaamU3Lnk1eU15VWJrRDNEIiwic3ViIjoic2VhbnF1aW5saXZhbjg4QGdtYWlsLmNvbSIsImF1ZCI6Imh0dHBzOi8vbG9naW4uc2FsZXNmb3JjZS5jb20iLCJleHAiOiIxNTYzMjc5OTY4In0=.b9oqWczSoGKiaB-fQijI0164ScgEb8tKPhWdUH_i7j0_1muGmjs9jn8J6V8wCIsKCjk7Po56ClMn56utYsJQ2axk1cmYUfJhFJZCOk3ozvEsD5VrqFpJZNZYFF4DGMIO4zUdG0lCq0jSC8Umbznoqp4VzrDS7k6S_7sEx6YCZCZIzx09JPZV-KBdbTNtbkXTwV36UHSQGXLpRnD6c47uWYaKxghnlLd4Nyzj5k2QBUf1CYdpu2JdRhHIO0_dBzEzDrbp1QpWRmypfVpd2VgDlOe1HXo2o__Nk6g0aPT5PyK2mqYH9fHmwWCmoYN55-l5_24KCrOjTrynPJ8UFSpYbg==
Is there something I am doing wrong when setting up the payload?
Many thanks for your help.