I ended up restructuring my app to use a vallet key pattern with a SAS key, and handling the blob storage on the frontend using the javascript azure blob storage npm package.
Subject: Azure Blob Storage - Issue with MAC Signature Mismatch in Block Blob Upload
Hello,
I'm currently facing an issue with uploading block blobs to Azure Blob Storage using the REST API. I'm constructing the string-to-sign as per the Azure documentation, but I'm consistently receiving a 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. error.
$str2sign = "PUT\n\n\n$blockSize\n\n$blockMimeType\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:$Date\nx-ms-version:2019-12-12\n$headerResource\n$urlResource";
Where $headerResource
is x-ms-blob-type:BlockBlob\nx-ms-date:$Date\nx-ms-version:2019-12-12
and $urlResource
is /$storageAccountname/$containerName/$blobName\nblockid:" . urlencode($blockId) . "\ncomp:block"
.
I'm then creating the signature as follows:
<?php
$sig = base64_encode(hash_hmac('sha256', urldecode(utf8_encode($str2sign)), base64_decode($accesskey), true));
?>
And the authorization header:
<?php
$authHeader = "SharedKey $storageAccountname:$sig";
?>
The headers for the request are set as follows:
<?php
$headers = [
'Authorization: ' . $authHeader,
'x-ms-date: ' . $Date,
'x-ms-version: 2019-12-12',
'Content-Length: ' . strlen($blockList),
'Content-Type: application/xml',
];
?>
And the request is sent using curl:
<?php
curl_setopt($ch, CURLOPT_URL, $URL);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $blockList);
$result = curl_exec($ch);
?>
Despite following the documentation, I'm still facing this issue. I've also ensured that the Content-Length
header is included in the string-to-sign if it is included in the request, and that the query parameters in the CanonicalizedResource part of the string-to-sign are in lexicographical order.
Interestingly, I have other functions for uploading and showing blobs that are working fine, which are using the same method for authentication. Here's an excerpt from the show
function:
<?php
// Azure Blob Storage download
$Date = gmdate('D, d M Y H:i:s \G\M\T');
$headerResource = "x-ms-date:$Date\nx-ms-version:2019-12-12";
$urlResource = "/$storageAccountname/$containerName/$blobName";
$arraysign = array();
$arraysign[] = 'GET'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = ''; /*Content-Length (include value when zero)*/
$arraysign[] = ''; /*Content-MD5*/
$arraysign[] = ''; /*Content-Type*/
$arraysign[] = ''; /*Date*/
$arraysign[] = ''; /*If-Modified-Since */
$arraysign[] = ''; /*If-Match*/
$arraysign[] = ''; /*If-None-Match*/
?>
I would appreciate any guidance or suggestions on what might be causing this issue and how to resolve it.
Thank you.
2 answers
Sort by: Most helpful
-
-
Anand Prakash Yadav 7,820 Reputation points Microsoft Vendor
2024-01-11T11:52:51.3733333+00:00 Luca Marchal, I'm glad that you were able to resolve your issue and thank you for posting your solution so that others experiencing the same thing can easily reference this! Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others ", I'll repost your solution in case you'd like to "Accept " the answer. Accepted answers show up at the top, resulting in improved discoverability for others.
Issue: Customer facing an issue with uploading block blobs to Azure Blob Storage using the REST API. Customer has constructed the string-to-sign.
Error Message: 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Solution: Customer ended up restructuring the app to use a Vallet key pattern with a SAS key and handling the blob storage on the frontend using the JavaScript Azure blob storage npm package.