Search code examples
c#azure-iot-hubshared-access-signatures

Post request to Azure IoT Hub using Postman keeps returning Unauthorized


I am testing out an IoT Hub in Azure as a potential solution for making HTTPS post requests from Postman to Azure storage. I have already experimented with Azure Event Hub and was able to successfully post to an Event Hub.

Now I am attempting to do the same with Postman to an IoT Hub. I have checked a number of other sources to ensure that I am using the correct endpoint, such as the following: Microsoft_Learn_IOT_Hub_Q&A.

The output I continue to get is as pictured: UnathorizedAccessResponse

I created the IoT hub and registered a device, following Microsoft's Tutorial, and was able to watch data messages generated and redirected in Azure IoT Explorer, so I know that the IoT Hub itself is working fine.

When I moved over to Postman, I am sending a POST request to https://myhub.azure-devices.net/devices/TestDevice1/messages/events?api-version=2020-03-13 My Content-Type is application/json and all I am sending for now in the Body is the following:

{
    "Text": "Hello World!"
}

So that left me at a point where I just needed the Authorization header. I added the Authorization header and went to generate the SAS token using the following source code in C#: Generate-SAS-token And again as I am running it:

TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
var week = 60 * 60 * 24 * 7;
var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + week);
string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);

This same generation code worked for the Event Hub which was already successful, so I didn't make any changes to it, except for the inputs:

string resourceUri = "myhub.azure-devices.net/devices/TestDevice1";
string keyName = "device";
string key = "<insert key here>";

To retrieve the key, I went to the Shared access policies tab under myhub's Security settings, and selected the Policy "device". I then copied the Primary key from there.

At this point, I received the UnauthorizedAccess error code when sending my Postman Request.

I have tried a couple other keys for the SAS token, including for the policy iothubowner, and the key that comes with TestDevice1 under the Devices tab.

I am not sure what else I am doing wrong? Thanks for your help.


Solution

  • When you want to send a message from a device, SAS token you generate will need to use the device key. It seems you're trying to use the IoT Hub key.

    1. In the Azure portal, navigate to your IoT Hub.
    2. Click on 'Devices' under 'Device managemnt'.
    3. Click on the name of your device ('TestDevice1' in your case).
    4. You should now see the device details. The 'Primary Key' and 'Secondary Key' are the keys you can use for your SAS token. There is no key name associated with a device, so for keyName you should use the empty string ("").
    5. Now, update your C# code as follows:
    string resourceUri = "myhub.azure-devices.net/devices/TestDevice1";
    string key = "<insert primary or secondary key from the device here>";