How to create Client Assertion JWT token when connecting to Azure AD?

Question:

My issue is that I’m not sure what to use to sign the JWT token to make Client assertion when sending back authorized code to the Azure AD to get access token. The supported auth method is "private_key_jwt". The only thing provided is client_id, tenant_id, and manifest file endpoint.

Asked By: Marko M

||

Answers:

To go through this whole process , we should create certs first. I use self-signed certs for demo here .

Step 1 : Create .cer and .key files, we will upload .cer to Azure AD App and use .key file to sign our JWT tokens.

1)Create a self signed cert which password is 123456 by Powershell :

$cert = New-SelfSignedCertificate -certstorelocation cert:localmachinemy -dnsname stantest.com
$pwd = ConvertTo-SecureString -String '123456' -Force -AsPlainText
$path = 'cert:localMachinemy' + $cert.thumbprint 
Export-PfxCertificate -cert $path -FilePath <path of your pfx file> -Password $pwd

2)Create .cer file based on .pfx file in CMD:

openssl pkcs12 -in <path of .pfx file> -clcerts -nokeys -out <path of .cer> 

3)Create .key file based on .pfx file in CMD:

openssl pkcs12 -in <path of .pfx file> -nocerts -nodes  -out <path of .pem file>
openssl rsa -in <path of .pem file> -out <path of .key file>

Finally , we will get files below :
enter image description here

STEP 2 : Upload .cer file to your Azure AD app and note its Thumbprint value:

enter image description here

STEP 3 : Use the python code below to sign a JWT and exchange an access token for Microsoft Graph APIs(make sure your app has been granted permission to list users) :

import sys 
import json
import logging

import requests
import msal

config = {
    "client_id":"your application ID here",
    "authority":"https://login.microsoftonline.com/Your tenant name or ID",
    "thumbprint":"cert thumbprint value in step2",
    "private_key_file":r"the path of .pem file of private key",
    "scope": ["https://graph.microsoft.com/.default"],
    "endpoint":"https://graph.microsoft.com/v1.0/users?$top=1"
}


app = msal.ConfidentialClientApplication(
    config["client_id"], authority=config["authority"],
    client_credential={"thumbprint": config["thumbprint"], "private_key": open(config['private_key_file']).read()},
    )


result = app.acquire_token_for_client(scopes=config["scope"])

if "access_token" in result:
    print("Access Token value: " + result['access_token']);
    # Calling graph using the access token
    graph_data = requests.get(  # Use token to call downstream service
        config["endpoint"],
        headers={'Authorization': 'Bearer ' + result['access_token']},).json()
    print("Graph API call result: %s" % json.dumps(graph_data, indent=2))
else:
    print(result.get("error"))
    print(result.get("error_description"))
    print(result.get("correlation_id"))  # You may need this when reporting a bug

Result :
enter image description here

Answered By: Stanley Gong

for more clarification about the thumbprint:
on Mac: use a Quick Look in finder and use SHA1 Fingerprint in Thumbprint field.cert quick look image

Answered By: Akram Bazina