Private/Get-AzTableAuthorizationHeader.ps1
|
function Get-AzTableAuthorizationHeader { <# .SYNOPSIS Builds the Authorization and date headers for an Azure Table Storage REST request. .DESCRIPTION Supports three authentication types: - SharedKey : HMAC-SHA256 signature using the storage account key - AccessToken : Bearer token passed directly in the context (no external dependency) - SasToken : No Authorization header; SAS appended to URL by the caller .OUTPUTS [hashtable] Headers that must be merged into the outgoing request. #> [CmdletBinding()] [OutputType([hashtable])] param ( [Parameter(Mandatory)] [PSCustomObject]$Context, [Parameter(Mandatory)] [ValidateSet('GET', 'POST', 'PUT', 'DELETE', 'PATCH')] [string]$Method, # Path component only, e.g. "Tables", "mytable()", "mytable(PartitionKey='pk',RowKey='rk')" [Parameter(Mandatory)] [string]$Resource, [string]$ContentType = '', [string]$ContentMD5 = '' ) $date = [System.DateTime]::UtcNow.ToString('R') $headers = @{ 'x-ms-date' = $date 'x-ms-version' = '2019-02-02' } switch ($Context.AuthType) { 'SharedKey' { # Extract any sub-path from the Endpoint (e.g. "/devstoreaccount1" for Azurite # IP-style URLs like http://127.0.0.1:10002/devstoreaccount1). For production # endpoints (https://account.table.core.windows.net) the path is "/" which # trims to an empty string, preserving the standard /{account}/{resource} form. $endpointPath = '' if (-not [string]::IsNullOrEmpty($Context.Endpoint)) { $endpointUri = [System.Uri]$Context.Endpoint $endpointPath = $endpointUri.AbsolutePath.TrimEnd('/') } $canonicalizedResource = "/$($Context.StorageAccountName)$endpointPath/$Resource" # StringToSign format for Table service Shared Key: # VERB\nContent-MD5\nContent-Type\nDate\nCanonicalizedResource $stringToSign = "$Method`n$ContentMD5`n$ContentType`n$date`n$canonicalizedResource" $plainKey = [System.Net.NetworkCredential]::new('', $Context.StorageAccountKey).Password $keyBytes = [System.Convert]::FromBase64String($plainKey) $hmac = [System.Security.Cryptography.HMACSHA256]::new($keyBytes) $signBytes = [System.Text.Encoding]::UTF8.GetBytes($stringToSign) $signature = [System.Convert]::ToBase64String($hmac.ComputeHash($signBytes)) $hmac.Dispose() $headers['Authorization'] = "SharedKey $($Context.StorageAccountName):$signature" } 'AccessToken' { $headers['Authorization'] = "Bearer $($Context.AccessToken)" } 'SasToken' { # Authorization header is not used; the SAS token is appended to the request URL. } } return $headers } |