Generate an Azure AD Token using the REST API
Tags: azure
Published: 2020-02-25 14:50:50

---
title: Generate an Azure AD Token using the REST API
published: true
date: 2020-01-18 00:00:00 UTC
tags: azure
canonical_url: 
---

Recently, I had to access to a storage account using an application account, so I set up a SPN which has an RBAC right on my storage account, as I show in this blog post: [https://woivre.com/blog/2020/01/login-to-your-storage-accounts-using-azure-active-directory](https://dev.to/wilfriedwoivre/login-to-your-storage-accounts-using-azure-active-directory-10a2)

Now I need to generate my access token, thing that may be easy using ADAL libraries, however for my usecase I had the following constraints :

- Application account and a certificate authentication
- No additional libraries (Ciao ADAL)
- Powershell

First, we need to generate a JWT Token. As a reminder a JWT Token has the following syntax : **base64(header).base64(payload).base64(signature)**

Let’s start by building our header. To achieve this, we need to get the hash of our certificate :

```
$cert = Get-Item Cert:\CurrentUser\My\$ThumbprintValue

$hash = $cert.GetCertHash()
$hashValue = [System.Convert]::ToBase64String($hash) -replace '\+','-' -replace '/','_' -replace '='

```

Now, it’s possible to build our header and payload as following :

```
[hashtable]$header = @{alg = 'RS256'; typ= "JWT"; x5t = $thumprintValue}
[hashtable]$payload = @{aud = "https://login.microsoftonline.com/$TenantUrl/oauth2/token"; iss = $applicationId; sub=$applicationId; jti = "22b3bb26-e046-42df-9c96-65dbd72c1c81"; exp = $exp; nbf= 1536160449}

```

Now that we have all the information, we need to generate our signature and construct the token :

```
$headerjson = $header | ConvertTo-Json -Compress
$payloadjson = $payload | ConvertTo-Json -Compress

$headerjsonbase64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($headerjson)) -replace '\+','-' -replace '/','_' -replace '='
$payloadjsonbase64 = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($payloadjson)) -replace '\+','-' -replace '/','_' -replace '='

$jwt = $headerjsonbase64 + "." + $payloadjsonbase64
$toSign = [System.Text.Encoding]::UTF8.GetBytes($jwt)

$Signature = [Convert]::ToBase64String($rsa.SignData($toSign,[Security.Cryptography.HashAlgorithmName]::SHA256,[Security.Cryptography.RSASignaturePadding]::Pkcs1)) -replace '\+','-' -replace '/','_' -replace '='

$token = "$headerjsonbase64.$payloadjsonbase64.$Signature"

```

You can check that the creation the JWT Token on some sites such as : [https://jwt.io/](https://jwt.io/)

Here is it. We have the JWT Token which allows us to get the Access Token :

```

$url = "https://login.microsoftonline.com/$TenantUrl/oauth2/token"
$body = "resource=https%3A%2F%2F$storageAccountName.blob.core.windows.net%2F&client_id=$applicationId&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=$token&grant_type=client_credentials"
$responseToken = Invoke-WebRequest -Method POST -ContentType "application/x-www-form-urlencoded" -Headers @{"accept"="application/json"} -Body $body $url -Verbose

$accessToken = ($responseToken.Content | ConvertFrom-Json).access_token

```

After generating the token, it is possible to add it to the headers so we can call the storage account’s REST API.

```
$headerSMA = @{"Authorization" = "Bearer " + $accessToken; "x-ms-version" = "2017-11-09"}
Invoke-WebRequest -Headers $headerSMA -Method GET "https://$storageAccountName.blob.core.windows.net/$containerName/$blobName" -OutFile $outFile

```

That’s how we request the Azure API without using the ADAL. even if it is more easier using ADAL and you have less things to know.