0
votes

I am trying to send messages to Azure Event Hub by using nodemcu (ESP8266). I am using REST API of the Azure Event Hub. I followed this instructions however I didn't worked for me.

Currently, I am taking this response: 401 SubCode=40103: Invalid authorization token signature

I provided fingerprint to connect with HTTPS. (In tutorial there was no need so I confused a bit.)

I am suspicious about SAS but I checked again and again.

As an alternative, I also intended to use AMQP but I couldn't find a library that supports it.

Is there any alternative ways to send messages to Event Hub.

#include <WiFiClientSecure.h>
#include <String.h>
#include "sha256.h"
#include "Base64.h"

// START: Azure Evet Hub settings
const char* KEY = "<key>";    // event hub access key 
const char* KEY_NAME = "<key-name>";                 // event hub key name  ( policy name) 
const char* HOST = "<event-hub-namespace>.servicebus.windows.net";              // event hub name (name of service bus)
const char* END_POINT = "/<event-hub>/messages";                 // name of the evnthub which we create inside eventhub namespace
// END: Azure Evet Hub settings 

// START: WiFi settings
const char* SSID = "<ssid>";
const char* PASSWORD = "<password>";
// END: WiFi settings

String request;
String data;
String fullSas;
WiFiClientSecure client;

// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char fingerprint[] PROGMEM = "<fingerprint>";
void setup() {
  Serial.begin(115200);

  // START: Naive URL Encode
  String url = "https://" + (String)HOST + (String)END_POINT;
  url.replace(":", "%3A");
  url.replace("/", "%2F");
  Serial.println(url);
  // END: Naive URL Encode

  // START: Create SAS
  // https://azure.microsoft.com/en-us/documentation/articles/service-bus-sas-overview/
  // Where to get secods since the epoch: local service, SNTP, RTC
  int expire = 1609459200;
  String stringToSign = url + "\n" + expire;

  // START: Create signature
  Sha256.initHmac((const uint8_t*)KEY, 44);
  Sha256.print(stringToSign);
  char* sign = (char*) Sha256.resultHmac();
  int signLen = 32;
  // END: Create signature

  // START: Get base64 of signature
  int encodedSignLen = base64_enc_len(signLen);
  char encodedSign[encodedSignLen];
  base64_encode(encodedSign, sign, signLen); 
  String encodedSas = (String) encodedSign;
  // Naive URL encode
  encodedSas.replace("=", "%3D");
  //Serial.println(encodedSas);
  // END: Get base64 of signature

  // SharedAccessSignature
   fullSas = "sr=" + url + "&sig="+ encodedSas + "&se=" + expire +"&skn=" + KEY_NAME;
  // END: create SAS
//Serial.println("SAS below");
//Serial.println(fullSas);
//Serial.println();
  // START: Wifi connection
  Serial.print("connecting to ");
  Serial.println(SSID);

  WiFi.begin(SSID, PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  // END: Wifi connection

}

void loop() {
  //delay(100);
  WiFiClientSecure client;

  Serial.printf("Using fingerprint '%s'\n", fingerprint);
  client.setFingerprint(fingerprint);

  if (!client.connect(HOST, 443)) {
    Serial.println("connection failed");
    return;
  }

   data = "{'Temperature':25.25 , 'Deviceid':'esp3'}";
   request = String("POST ") + END_POINT + " HTTP/1.1\r\n" +
               "Host: " + HOST + "\r\n" +
               "Authorization: SharedAccessSignature " + fullSas + "\r\n" +                
               "Content-Type: application/atom+xml;type=entry;charset=utf-8\r\n" + 
               "Content-Length: " + data.length() + "\r\n\r\n" +
               data;
    Serial.println(request);
  client.print(request);
 delay(100);  
}
2
I dont understand what you are doing with the certificate (and its fingerprint). Event Hubs only support SAS tokens: docs.microsoft.com/en-us/azure/event-hubs/… (and Azure AD, but thats a different topic)silent
Without fingerprint, it just prints out connection failed.Emilcan Arıcan

2 Answers

0
votes

Have a look to this post that provides a POC using nodemcu and Azure Event Hub. But, basically every request from your IoT device to the Event Hub needs to be authenticated, and in this case you should use Shared Access Signatures (SAS) Tokens and enforce HTTPS.

0
votes

Apparently, the SAS creation part is not working properly. When I use a python script (provided here) to create the SAS, it worked. I wonder why it became broken after 4 years.