Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save phillipharding/d6cc4b84221cf5304e41d97beb62ea6c to your computer and use it in GitHub Desktop.
Save phillipharding/d6cc4b84221cf5304e41d97beb62ea6c to your computer and use it in GitHub Desktop.
Generate an Azure AD Access Token using the Client Credentials flow with a Certificate Secret to use for calling the SharePoint REST API

Azure AD Token Generation using a Certificate Secret Client Credentials Flow

Microsoft identity platform and the OAuth 2.0 client credentials flow

Details about the client credentials flow

https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow

Microsoft identity platform application authentication certificate credentials

Details about the certificate assertion value for the client credentials flow

https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials

JWTGEN

A command-line tool to create the client_assertion value

https://github.com/vandium-io/jwtgen

JWT.IO

Tool to create and/or validate a JWT token or client_assertion

https://jwt.io

Create an Azure AD App Registration and add a Certificate (Public Key)

Get the Certificate Thumbprint

This is displayed on the Certificates & Secrets section in the Azure AD portal

A certificate thumbprint is a HEX string such as C43593F392A8B00645BD4F256F9DCBC2F7BB2410

Convert the Certificate Thumbprint Hex string to Base64

https://base64.guru/converter/encode/hex

Dont simply Base64 encode the Thumbprint as the thumbprint is a Hex string

The linked converter tool decodes the Hex string into it's original data, then encodes it to Base64

Remove any trailing = characters

Create the client_assertion value

Use the jwtgen tool or https://jwt.io, jwt.io is harder because you have to manually create the header and claims JSON bodies.

The https://jwt.io, tool can be used to validate (any) JWT token if you have the Certificate Public and Private keys.

To use the jwtgen tool you'll need the certificate private key (.pem) file

BASH

jwtgen -a RS256 -p <certificate private key>.pem -c "iss=<app client id>" -c "sub=<app client id>" -c "aud=https://login.microsoftonline.com/<tenant id>/oauth2/token" -c "jti=<random guid>" -c "nbf=1484592741" -e 3600 --headers "{\"typ\":\"JWT\",\"alg\":\"RS256\",\"x5t\":\"<base64 encoded thumbprint>\"}" -v

or

jwtgen -a RS256 -p <certificate private key>.pem -c "iss=<app client id>" -c "sub=<app client id>" -c "aud=https://login.microsoftonline.com/<tenant id>/oauth2/token" -c "jti=<random guid>" -c "nbf=1484592741" -e 3600 --headers '{"typ":"JWT","alg":"RS256","x5t":"<base64 encoded thumbprint>"}' -v

POSH

jwtgen -a RS256 -p <certificate private key>.pem -c "iss=<app client id>" -c "sub=<app client id>" -c "aud=https://login.microsoftonline.com/<tenant id>/oauth2/token" -c "jti=<random guid>" -c "nbf=1484592741" -e 3600 --headers '{\"typ\":\"JWT\",\"alg\":\"RS256\",\"x5t\":\"<base64 encoded thumbprint>\"}' -v

The client_assertion is a JWT token with a header, payload/claims and signature section separated by the . character.

e.g.

payload/claims:
{
  "iat": 1619003832,
  "exp": 1619007432,
  "iss": "<app client id>",
  "aud": "https://login.microsoftonline.com/<tenant id>/oauth2/token",
  "jti": "<random guid>",
  "nbf": 1484592741,
  "sub": "<app client id>"
}
headers:
{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "<base64 encoded certificate thumbprint>"
}

and looks like...

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVuTWhzNUtvc0FaRnZVOGxiNTNMd3ZlN0pCQSJ9.eyJpY <lots of characters> pAzkyEKPdZTu44X12peEzeV4-fwLyg

Note that the aud claim in the JWT token should match the URL of the token issuance endpoint that you send token requests to;

For Azure AD OAuth 2.0 v1 this is: https://login.microsoftonline.com/{tenant_id}/oauth2/token

For Azure AD OAuth 2.0 v2 this is: https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token

Send the Token Request

Using the Azure AD OAuth 2.0 v1 Token Endpoint;

POST https://login.microsoftonline.com/<tenant id>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

&client_id=<client id>
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<client_assertion value>
&grant_type=client_credentials
&resource=https://<tenant-name>.sharepoint.com

Using the Azure AD OAuth 2.0 v2 Token Endpoint;

POST https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

&client_id=<client id>
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<client_assertion value>
&grant_type=client_credentials
&scope=https://<tenant-name>.sharepoint.com/.default
&tenant=<tenant-id>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment