1

I'm uploading a file to Azure blob storage using REST API request. The file uploaded successfully using PHP curl request. But when I transfer the code into ESP32 HTTP client I'm getting an Authentication error. I also verify the HMAC key generated by the ESP32 Arduino code in PHP code. I'm thinking that I'm missing something in adding header. Here is my PHP code :

       $header = array (
        "x-ms-blob-type: BlockBlob",
        "x-ms-date: " . $date,
        "x-ms-version: " . $version,
        "Authorization: SharedKey account_name:" . $signature_str,
        "Content-Type: text/plain; charset=UTF-8",
        "Content-Length: " . strlen($fdata),
        );

    $url =  "https://acount_name.blob.core.windows.net/container/test.txt";
    $ch = curl_init ();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, 'PUT' );
    curl_setopt ( $ch, CURLOPT_URL, $url );
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fdata);
    curl_setopt ( $ch, CURLOPT_HEADER, True );
    echo($ch);
    curl_exec ( $ch );

and here is the corresponding Arduino IDE code:

    String sig = get_hmac();
      Serial.println(sig);

      if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
        HTTPClient http;
        http.begin("https://account_name.blob.core.windows.net/container/test.txt");  //Specify destination for HTTP request

        http.addHeader("x-ms-blob-type", "BlockBlob");
        http.addHeader("x-ms-date", Date);
        http.addHeader("x-ms-version", "2018-03-28");
        http.addHeader("Authorization", "SharedKey account_name:"+sig);
        http.addHeader("Content-Type", "text/plain; charset=UTF-8");
        http.addHeader("Content-Length",  "20");

        int httpResponseCode = http.PUT(d);   
        if (httpResponseCode > 0) {
          String response = http.getString(); 
          Serial.println(httpResponseCode);   
          Serial.println(response);        
        } else {
          Serial.print("Error on sending POST: ");
          Serial.println(httpResponseCode);
        }
        http.end();  //Free resources
      } else {
        Serial.println("Error in WiFi connection");
      }

The error I'm getting is :

The MAC signature found in the HTTP request 'sVrSFpplX+Gkcb4R/iSDf6eqUP4srkZuVD68/pAeYwE=' is not the same as any computed signature.....

Although the HMAC signature created from same String works in PHP here is the reference page of the API: https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob Thanks

  • the http.PUT(d); adds the Content-length header, Host header, User-Agent header, Accept-Encoding header and Connection header. Is it OK for the SharedKey authorization? – Juraj Jun 12 at 20:10
  • It looks like that error message is coming from the web-service; seems like this might be more debugging the webservice, than arudino. What status code are you getting? – esoterik Jun 13 at 2:25
  • the first code uses 'SharedKey mikeiot,' the second code uses 'SharedKey account_name:' could this be the problem? You are also hard coding the content-length in the second code, could you be sending an incorrect amount? – esoterik Jun 13 at 2:28
  • @Juraj I need custom header like given in Arduino code 'addHeader'. It's ok to send these headers. should I skip Content-length header? – Dani Jun 13 at 7:32
  • @esoterik I'm getting 403 response code from the server and the error message shown in post – Dani Jun 13 at 7:33
2

I got clue from @esoterik answer and manage to send request successfully. The problem were in adding header parameter:

 http.addHeader("Content-Length",  "20");

This duplicate the header( 2nd one added in PUT method). I just comment it and the code works. Thanks for every one response

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.