Search code examples
phpazureazure-storage

Azure Lease Blob API 403 Error


I'm trying to lease blob for deleting it but my lease blob API code does not work due to happening 403 error.

Generate Signature Code (PHP)

<?php
$account = "myaccount";
$container = "mycontainer";
$accessKey = "myaccesskey";
$blob = "myblob";
$date = gmdate('D, d M Y H:i:s T');
$headers = [
  'x-ms-date:${date}',
 'x-ms-lease-action:acquire',
  'x-ms-lease-duration:-1',
  'x-ms-lease-id:49383176-ad23-4f85-acbf-01edcd02d177',
  'x-ms-version:2017-04-17',
];
$stringToSign = [
  // VERB
  'PUT',
  // Content-Encoding
  '',
  // Content-Language
  '',
  // Content-Length
  '',
  // Content-MD5
  '',
  // Content-Type
  '',
  // Date
  '',
  // If-Modified-Since
  '',
  // If-Match
  '',
  // If-None-Match
  '',
  // If-Unmodified-Since
  '',
  // Range
  '',
];
$stringToSign = array_merge($stringToSign, $headers, ["/$account/$container/$filename"], ["comp:lease"]);
$stringToSign = implode("\n", $stringToSign);
$signature = base64_encode(hash_hmac('sha256', $stringToSign, base64_decode($accessKey), true));
echo $signature
?>

I added content-length header because 411 error occurred.

Lease Blob API (curl command)

STG_ACCOUNT="myaccount"
CONT_NAME="mycontainer"
BLOCK_NAME="myblob"
DATE=`date +"%a, %d %b %Y %H:%M:%S GMT" --utc`
ACCESS_KEY="signature"
LEASE_ID="49383176-ad23-4f85-acbf-01edcd02d177"

curl -i -X PUT https://$STG_ACCOUNT.blob.core.windows.net/$CONT_NAME/$BLOCK_NAME?comp=lease  -H "Content-Length:0"  -H "Authorization: SharedKey $STG_ACCOUNT:$ACCESS_KEY" -H "x-ms-date:$DATE" -H "x-ms-lease-action:acquire" -H "x-ms-lease-duration:-1" -H "x-ms-lease-id:$LEASE_ID" -H "x-ms-version:2017-04-17"

Error

HTTP/2 403
content-length: 774
content-type: application/xml
server: Microsoft-HTTPAPI/2.0
x-ms-request-id: 98f7dbe2-801e-0017-78f2-b5d325000000
date: Wed, 07 Mar 2018 09:02:11 GMT

<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:98f7dbe2-801e-0017-78f2-b5d325000000
Time:2018-03-07T09:02:12.1896957Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request 'qaRQQPDc8T8lFCTq5W6ZkjrJoX6W+a419RMd8MWJsUg=' is not the same as any computed signature. Server used following string to sign: 'PUT











x-ms-date:Wed, 07 Mar 2018 09:02:11 GMT
x-ms-lease-action:acquire
x-ms-lease-duration:-1
x-ms-lease-id:49383176-ad23-4f85-acbf-01edcd02d177
x-ms-version:2017-04-17
/myaccount/mycontainer/myblob
comp:lease'.</AuthenticationErrorDetail></Error>

I have already tried other blob service API such a get blob but it was succeed. So I suppose that these codes have a few mistakes. Please help me.


Solution

  • I believe the problem is with Content-Length request header. Please replace 0 for content length in your $stringToSign with an empty string.

    From the documentation:

    Content-Length Header in Version 2015-02-21 and Later

    When using version 2015-02-21 or later, if Content-Length is zero, then set the Content-Length part of the StringToSign to an empty string.

    UPDATE:

    Upon further inspection, your $stringToSign is missing comp:lease. Please try by changing the following line of code:

    $stringToSign = array_merge($stringToSign, $headers, ["/$account/$container/$filename"]);
    

    to

    $stringToSign = array_merge($stringToSign, $headers, ["/$account/$container/$filename"], ["comp:lease"]);