Azure IOT Hub Rest API Unauthorized

好久不见. 提交于 2019-12-13 16:54:26

问题


I am trying to use Azure Iot hub REST API to create device by following links

Create a new device identity

Control access to IoT Hub

And my http data is like

{
    "status":"connected",
    "authentication":{ "symmetricKey":{
                "primaryKey":"key in shared access policies",
                "secondaryKey":"key in shared access policies"}
             },
    "statusReason":"reason",
    "deviceId":"test123"
}

My header is like

 ["Content-Type": "application/json", "Authorization": "SharedAccessSignature sig=(key in shared access policies public key)=&se=1481687791&skn=iothubowner&sr=(my iot hub name).azure-devices.net%2fdevices%2ftest123"]

But i get error 401

{"Message":"ErrorCode:IotHubUnauthorizedAccess;Unauthorized","ExceptionMessage":"Tracking ID:(tracking id )-TimeStamp:12/14/2016 03:15:17"}

Anyone know how to fixed it , or to track the exceptionMessage ?


回答1:


The problem of 401 is, probably, in the way you are calculating the SAS. The full process to calculate a SAS for the IoT Hub (in C#) is:

private static readonly DateTime epochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

public static string SharedAccessSignature(string hostUrl, string policyName, string policyAccessKey, TimeSpan timeToLive)
{
  if (string.IsNullOrWhiteSpace(hostUrl))
  {
    throw new ArgumentNullException(nameof(hostUrl));
  }

  var expires = Convert.ToInt64(DateTime.UtcNow.Add(timeToLive).Subtract(epochTime).TotalSeconds).ToString(CultureInfo.InvariantCulture);
  var resourceUri = WebUtility.UrlEncode(hostUrl.ToLowerInvariant());
  var toSign = string.Concat(resourceUri, "\n", expires);
  var signed = Sign(toSign, policyAccessKey);

  var sb = new StringBuilder();
  sb.Append("sr=").Append(resourceUri)
    .Append("&sig=").Append(WebUtility.UrlEncode(signed))
    .Append("&se=").Append(expires);
  if (!string.IsNullOrEmpty(policyName))
  {
    sb.Append("&skn=").Append(WebUtility.UrlEncode(policyName));
  }
  return sb.ToString();
}

private static string Sign(string requestString, string key)
{
  using (var hmacshA256 = new HMACSHA256(Convert.FromBase64String(key)))
  {
    var hash = hmacshA256.ComputeHash(Encoding.UTF8.GetBytes(requestString));
    return Convert.ToBase64String(hash);
  }
}

If you want to create the device in the IoTHub you have to have a policy with full permissions that mean: Registry read and write, Service connect and Device connect. If you need a full functional example, in C#, about how use the IoT Hub REST API to create a device, check if a device exists and send messages to the IoT Hub I have wrote this post about it (the post is in spanish but I can imagine that what you need is just the code).




回答2:


it looks like your SAS is wrong. It shouldn't include the devices part in the end. If you open the Iot Hub Device Explorer you can Generate SAS token to access the Iot Hub API. You should create the SAS for the IoT hub level and for a device level (which include the devive id in the SAS like you have). So your SAS should look like this - SharedAccessSignature sr={iot hub name}.azure-devices.net&sig={sig}&se={se}&skn=iothubowner




回答3:


There are two edits you need to do:

  1. In your http data, only deviceId is required, other are optional, you can do it like this:

{ deviceId: "test123" }

Note that there are no double quotes around deviceId.

  1. Like @shachar said, you need remove "%2fdevices%2ftest123" in SAS token of the header. About generating SAS token you can utilize Device Explorer.

This is my test result:




回答4:


The format of SAS token you use is wrong. To create a device, you need to use SAS Token for IoT Hub. You could easily use Azure IoT Toolkit extension for Visual Studio Code to generate SAS Token for IoT Hub as below screenshot.

BTW, the format of SAS token for device is /^SharedAccessSignature sr=iot-hub-test.azure-devices.net%2Fdevices%2Fdevice1&sig=.+&se=.+$/, while the format of SAS token for IoT Hub is /^SharedAccessSignature sr=iot-hub-test.azure-devices.net&sig=.+&skn=iothubowner&se=.+$/




回答5:


//Following code is to generate the SAS token programatically.

string sasToken = new SharedAccessSignatureBuilder()
{  KeyName = name,
 Key = key,
 Target = target,
 TimeToLive = TimeSpan.FromDays(days)
}.ToSignature();

//use this sas token as authorization header before calling the iot restapi



来源:https://stackoverflow.com/questions/41134535/azure-iot-hub-rest-api-unauthorized

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!