DEV Community

Wilfried Woivré
Wilfried Woivré

Posted on • Originally published at woivre.com on

2 2

Generate an Azure AD Token using the REST API

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

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 '='

Enter fullscreen mode Exit fullscreen mode

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}

Enter fullscreen mode Exit fullscreen mode

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"

Enter fullscreen mode Exit fullscreen mode

You can check that the creation the JWT Token on some sites such as : 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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay