2
votes

I try to call some HTTP GET calls to the device twins of the MS Azure IoT Hub.

HTTP GET call via Postman

As you can see the GET call results in an unauthorized IoTHubUnauthorizedAccess error code.

I generated the token for the authorization header with the Azure Device Explorer as you can see in the picture below.

Generated SAS Token

Anyone any idea about this? I already searched here, and the only topic did not help me.

3

3 Answers

0
votes

It seems you are trying to access the Device Twins from a "device" (as you are using a SAS Token generated from a Device ID/Key pair) using REST APIs. This cannot be done as the interaction with Device Twins for "devices" is done through MQTT, not through HTTP (see links below for docs on IoT Hub endpoints and twins). I recommend you take a look at the Azure IOT device SDKs if you want to work with device Twins from a device. If you want to learn more about using MQTT, you can read this.

However if you want to work with device Twins from the backend perspective (as in using a backend app that sets desired properties for devices, reads devices reported properties and work with tags) then you need to use a SAS Token generated from one of the IoT Hub shared access policies name/key (not Device credentials). Try generating a SAS Token using the same Device Explorer tool, but on the "Configuration" tab for this.

Some docs on Device Twins that can help make all this clearer:

Device Twin description

IoT Hub endpoints

0
votes

You can use the Postman Pre-request script sandbox to generate the SAS token. Here's a blog post I wrote that details everything you need to do to generate the SAS token. http://blog.jongallant.com/2017/02/azure-iot-hub-device-twin-rest-apis-postman-newman/

Here's a Postman collection that will show you exactly how to execute the APIs: https://www.getpostman.com/collections/84a38008cd07accf565e

Here are more Postman / Azure related Posts (also my own): http://blog.jongallant.com/tags/postman/

Here's the code that I use in the Pre-request script sandbox:

var resourceName = postman.getEnvironmentVariable("resourceName");
var resourceKey = postman.getEnvironmentVariable("resourceKey");
var tokenExpirationPeriod = postman.getEnvironmentVariable("tokenExpirationPeriod");
var policyKeyName = postman.getEnvironmentVariable("policyKeyName");

postman.clearEnvironmentVariable("deviceTwinSasToken"); // clear out token on first run.

// See this doc for details: https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-security
var resourceUri = encodeURIComponent(resourceName + '.azure-devices.net'); // The resource uri
var expiry = Math.ceil((Date.now() / 1000) + tokenExpirationPeriod * 60); // Expire the token 60 minutes from now
var uriExpiry = resourceUri + '\n' + expiry; // this is the string format to gen signature from
var decodedKey = CryptoJS.enc.Base64.parse(resourceKey); // The SHA256 key is the Base64 decoded version of the IoT Hub key
var signature = CryptoJS.HmacSHA256(uriExpiry, decodedKey); // The signature generated from the decodedKey
var encodedUri = encodeURIComponent(CryptoJS.enc.Base64.stringify(signature)); // The url encoded version of the Base64 signature

// Construct authorization string (shared access signature)
var deviceTwinSasToken = "SharedAccessSignature sr=" + resourceUri + "&sig=" + encodedUri + "&se=" + expiry;

// Add token if one is present
if (policyKeyName) {
    deviceTwinSasToken += "&skn="+ policyKeyName;
}

// Put in variable to be used in other requests.
postman.setEnvironmentVariable("deviceTwinSasToken", deviceTwinSasToken);

console.log("Shared Access Signature:" + postman.getEnvironmentVariable("deviceTwinSasToken"));
0
votes

From your picture, you used the specified device SAS token. While you need use IoT Hub SAS token it can grant access control and permissions. You can get it using Device Explorer like this:

enter image description here

And you will get the device twin information after posting the Get request successfully, in the postman, it looks like this:

enter image description here