Оказывается, в документах есть небольшая ошибка, после CanonicalizedHeaders
вам нужен еще и перевод строки, даже если в документах указано иное.Если вы внимательно прочитаете следующий пример кода в документации, там на самом деле есть новая строка:
PUT\n\ntext/plain; charset=UTF-8\n\nx-ms-date:Sun, 20 Sep 2009 20:36:40 GMT\nx-ms-meta-m1:v1\nx-ms-meta-m2:v2\n/testaccount1/mycontainer/hello.txt
В любом случае, вот полностью работающий скрипт для получения большого двоичного объекта из хранилища BLOB-объектов Azure:
function GenerateHeader(
[string]$accountName,
[string]$accountKey,
[string]$verb,
[string]$resource)
{
$xmsversion = '2015-02-21'
$xmsdate = Get-Date
$xmsdate = $xmsdate.ToUniversalTime()
$xmsdate = $xmsdate.toString('R')
$newLine = "`n";
$contentType = 'application/json'
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", $contentType)
$headers.Add("x-ms-date", $xmsdate)
$headers.Add("x-ms-version", $xmsversion)
$canonicalizedHeaders = "x-ms-date:$xmsdate"+$newLine+"x-ms-version:$xmsversion"
$canonicalizedResource = $resource
$stringToSign = $verb.ToUpper() + $newLine +`
$contentMD5 + $newLine +`
$contentType + $newLine +`
$dateHeader + $newLine +`
$canonicalizedHeaders + $newLine +`
$canonicalizedResource;
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accountKey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signature)
$headers.Add("Authorization", "SharedKeyLite " + $accountName + ":" + $signature)
return $headers
}
$accountName = ''
$accountKey = ''
$container = ''
$fileName = ''
$blobUri = "https://$accountName.blob.core.windows.net/$container/$fileName"
$outputPath = "$PSScriptRoot\$fileName"
$headers = GenerateHeader $accountName $accountKey 'GET' "/$accountName/$container/$fileName"
$webClient = New-Object System.Net.WebClient
foreach ($key in $headers.Keys)
{
$webClient.Headers.Add($key, $headers[$key])
}
$start_time = Get-Date
$webClient.DownloadFile($blobUri, $outputPath)
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
Write-Output $stringToSign