使用PowerShell调用REST API恢复Azure软删除Blob时认证失败
解决Azure Blob软删除恢复的认证失败问题
问题原因分析
- Authorization头构造错误:你直接将存储账户Key作为签名放入Authorization头,不符合Azure SharedKey认证规则。SharedKey要求对请求的特定内容(HTTP方法、头信息、资源路径等)进行HMAC-SHA256加密,再转成Base64字符串作为签名,而非直接使用原始Key。
- 未处理默认Content-Type头:Invoke-RestMethod发送POST请求时会自动添加
Content-Type: application/x-www-form-urlencoded头,但你的签名生成过程未包含该头,导致服务器计算的签名与你发送的不匹配(错误信息中也显示服务器用的签名字符串包含了这个头)。
解决方法
方法一:正确生成SharedKey签名
修改脚本,按规则计算签名:
# Variables $storageAccountName = "mystorageAccountName" $containerName = "mycontainerName" $blobName = "myblobName" $resGroup = "myResourceGroup" $subId = "mySubscriptionID" $tenantID = "myTenantID" # Authenticate to your Azure account (interactive login) Connect-AzAccount -Subscription $subID -TenantId $tenantID # Get storage account key $storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $resGroup -AccountName $storageAccountName)[0].Value # Construct the URL to undelete the blob $uri = "https://$storageAccountName.blob.core.windows.net/$containerName/$blobName?comp=undelete" # Generate current date/time for the x-ms-date header $date = Get-Date $dateRfc1123 = $date.ToString("R") $apiVersion = "2017-04-17" $contentType = "application/x-www-form-urlencoded" # 构造要签名的字符串,包含所有必要的请求信息 $stringToSign = @" POST $contentType x-ms-date:$dateRfc1123 x-ms-version:$apiVersion /$storageAccountName/$containerName/$blobName comp:undelete "@ # 计算HMAC-SHA256签名 $keyBytes = [Convert]::FromBase64String($storageAccountKey) $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256 $hmacSha256.Key = $keyBytes $signatureBytes = $hmacSha256.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign)) $signature = [Convert]::ToBase64String($signatureBytes) # Construct the headers $headers = @{ "x-ms-date" = $dateRfc1123 "x-ms-version" = $apiVersion "Content-Type" = $contentType "Authorization" = "SharedKey $storageAccountName`:$signature" } # Invoke the REST API call to undelete the blob $response = Invoke-RestMethod -Uri $uri -Method POST -Headers $headers -Body $null # Output the response $response
方法二:使用Az.Storage模块Cmdlet(更简单可靠)
无需手动处理REST调用和签名,直接用Az模块提供的Cmdlet:
# Variables $storageAccountName = "mystorageAccountName" $containerName = "mycontainerName" $blobName = "myblobName" $resGroup = "myResourceGroup" $subId = "mySubscriptionID" $tenantID = "myTenantID" # Authenticate to your Azure account (interactive login) Connect-AzAccount -Subscription $subID -TenantId $tenantID # 获取存储上下文 $storageContext = (Get-AzStorageAccount -ResourceGroupName $resGroup -AccountName $storageAccountName).Context # 恢复软删除的Blob Undelete-AzStorageBlob -Container $containerName -Blob $blobName -Context $storageContext
该方法自动处理认证、头信息和签名,避免手动构造签名的错误,推荐使用。
内容的提问来源于stack exchange,提问作者Steve T
相关产品推荐
相关产品推荐

