• About
  • Contact
  • Search

Philip Van de Vyver - Azure Blog

PowerShell Authentication tokens for Azure REST API

August 11, 2023 ·

Table of contents

  • Introduction
    • Azure REST API Authentication
      • JSON Web Token (JWT)
      • Authentication to the Management API
  • Authentication with an App Registration - Example
  • Authentication with current account
    • Using Get-AccessToken
      • Example
    • Using the token stored in the profile
      • Example

Introduction

The Azure REST API is a powerful way for interacting with Azure service resources.

In this article, I want to explain the authentication options that you have with PowerShell to interact with the Azure REST API

Azure REST API Authentication

Authentication to the Azure REST API is done by using an OAuth2 bearer token.

With this token you can authenticate your request on the Azure REST API:

JSON Web Token (JWT)

The token itself is a JSON Web Token (JWT), it consist of three parts separated by dots (.), which are:

  • Header
  • Payload
  • Signature

Therefore, a JWT typically looks like the following.

xxxxx.yyyyy.zzzzz

Note:
To decode a JWT token, you can use the online tool over here: https://jwt.io/

To dump the claims in your bearer token so you can validate their contents you can use the following online tool: https://jwt.ms/

Authentication to the Management API

An Access token is a Bearer token that you will have to add in all request headers to be authenticated.

For example, you might send an HTTPS GET request method for an Azure Resource Manager provider to list subscriptions by using request header fields that are similar to the following:

$path = "/subscriptions"
$apiVersion = "2022-12-01"
$token = "<your-acquired-token>"

$authHeader = @{
    'Content-Type'  = 'application/json'
    'Authorization' = "Bearer $token"
}

# invoke Azure Management REST API
$uri = "https://management.azure.com$($path)?api-version=$($apiVersion)"
Write-Host "Invoking request to: '$uri'"
$data = Invoke-RestMethod -Method Get -Uri $uri -Headers $authHeader

Authentication with an App Registration

A convenient way of authentication is using an App Registration.

The access token can be aquired using an access token request with a shared secret.

Get-AppRegistrationAuthorizationToken function:

function Get-AppRegistrationAuthorizationToken {
	[CmdletBinding()]
	param
	(
		[Parameter(Mandatory = $true)]
		[string]$TenantID,
		[Parameter(Mandatory = $true)]
		[string]$ClientID,
		[Parameter(Mandatory = $true)]
		[string]$ClientSecret
	)

	$TokenEndpoint = "https://login.windows.net/$TenantID/oauth2/token"
	$ARMResource = "https://management.core.windows.net/"

	$Body = @{
		'resource'      = $ARMResource
		'client_id'     = $ClientID
		'grant_type'    = 'client_credentials'
		'client_secret' = $ClientSecret
	}

	$params = @{
		ContentType = 'application/x-www-form-urlencoded'
		Headers     = @{'accept' = 'application/json' }
		Body        = $Body
		Method      = 'Post'
		URI         = $TokenEndpoint
	}

	$token = Invoke-RestMethod @params

	Return ($token.access_token).ToString()
}

Example

# set variables
$client_id = "<your-app-registration-client-id>"
$app_secret = "<your-app-registration-secret>"
$tenantid = "<your-tenant-id>"
$token = Get-AppRegistrationAuthorizationToken -TenantID $tenantid -ClientID $client_id -ClientSecret $app_secret
$path = "/subscriptions"
$apiVersion = "2022-12-01"
$authHeader = @{
    'Authorization' = "Bearer $($token)"
}

# invoke Azure Management REST API
$uri = "https://management.azure.com$($path)?api-version=$($apiVersion)"
$result = Invoke-RestMethod -Method Get -Uri $uri -Headers $authHeader

# return result
$result.value 

Authentication with current account

When already authenticated, you can get the access token for the identity that is already logged in into Azure.

Using Get-AccessToken

The PowerShell command Get-AccessToken (from the Az.Accounts module) can be used to get a fresh access token.

Using the ResourceTypeName

Get-AzAccessToken
   [-ResourceTypeName <String>]
   [-TenantId <String>]
Get-AzAccessToken -ResourceTypeName Arm

or

Using the ResourceUrl

Get-AzAccessToken
   -ResourceUrl <String>
   [-TenantId <String>]
Get-AzAccessToken -ResourceUrl "https://management.core.windows.net/"

Example

# set variables
$token = Get-AzAccessToken -ResourceUrl "https://management.core.windows.net/"
$path = "/subscriptions"
$apiVersion = "2022-12-01"
$authHeader = @{
    'Authorization' = "Bearer $($token.Token)"
}

# invoke Azure Management REST API
$uri = "https://management.azure.com$($path)?api-version=$($apiVersion)"
$result = Invoke-RestMethod -Method Get -Uri $uri -Headers $authHeader

# return result
$result.value 

Using the token stored in the profile

Using the Microsoft.Azure.Commands.ResourceManager.Common Namespace .NET Namespace, you can use the AcquireAccessToken Method to get the stored token in profile.

Get-AzureCachedAccessToken function:

function Get-AzureCachedAccessToken {
    # get current Azure Profile
	$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile

    # gets the metadata used to authenticate Azure Resource Manager requests.
	$currentAzureContext = Get-AzContext

    # initiate client session to access profile
	$profileClient = New-Object Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient($azProfile)

    # get the token from the profile
	$token = $profileClient.AcquireAccessToken($currentAzureContext.Tenant.TenantId)
	return $token.AccessToken
}

Example

$token = Get-AzureCachedAccessToken

$path = "/subscriptions"
$apiVersion = "2022-12-01"
$authHeader = @{
    'Authorization' = "Bearer $($token)"
}

# invoke Azure Management REST API
$uri = "https://management.azure.com$($path)?api-version=$($apiVersion)"
$result = Invoke-RestMethod -Method Get -Uri $uri -Headers $authHeader

$result.value