Azure IOT Hub Rest API未经授权

时间:2016-12-14 03:45:57

标签: rest azure azure-iot-hub

我正在尝试使用Azure Iot中心REST API通过以下链接创建设备

Create a new device identity

Control access to IoT Hub

我的http数据就像

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

我的标题就像

 ["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"]

但我收到错误401

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

任何人都知道如何修复它,或者跟踪exceptionMessage?

5 个答案:

答案 0 :(得分:2)

401的问题可能与计算SAS的方式有关。 计算物联网中心的SAS(在C#中)的完整过程是:

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);
  }
}

如果您想在IoTHub中创建设备,您必须拥有一个具有完全权限的策略,这意味着: 注册表读写,服务连接和设备连接。 如果您需要一个完整的功能示例(在C#中),关于如何使用IoT Hub REST API创建设备,请检查设备是否存在并向IoT Hub发送消息我已写过this post关于它的信息(帖子是用西班牙语,但我可以想象你需要的只是代码。

答案 1 :(得分:0)

看起来你的SAS错了。它不应该包括最后的设备部分。如果打开Iot Hub设备资源管理器,则可以生成SAS令牌以访问Iot Hub API。您应该为IoT集线器级别和设备级别(包括SAS中的devive id)创建SAS。 所以你的SAS应该是这样的 - SharedAccessSignature sr = {iot hub name} .azure-devices.net& sig = {sig}& se = {se}& skn = iothubowner

答案 2 :(得分:0)

您需要进行两次编辑:

  1. 在您的http数据only deviceId is required, other are optional中,您可以这样做:
  2. { deviceId: "test123" }

    请注意,deviceId附近有没有双引号

    1. 像@shachar所说,你需要删除"%2fdevices%2ftest123"在标头的SAS令牌中。关于生成SAS令牌,您可以使用Device Explorer
    2. 这是我的测试结果:

      enter image description here

答案 3 :(得分:0)

您使用的SAS令牌格式错误。要创建设备,您需要将SAS令牌用于IoT中心。您可以轻松使用Azure IoT Toolkit extension for Visual Studio Code为IoT中心生成SAS令牌,如下图所示。

SAS Token for IoT Hub

顺便说一句,设备的SAS令牌的格式为/^SharedAccessSignature sr=iot-hub-test.azure-devices.net%2Fdevices%2Fdevice1&sig=.+&se=.+$/,而IoT中心的SAS令牌的格式为/^SharedAccessSignature sr=iot-hub-test.azure-devices.net&sig=.+&skn=iothubowner&se=.+$/

答案 4 :(得分:0)

//以下代码用于以编程方式生成SAS令牌。

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

///在调用物联网restapi之前,将此sas令牌用作授权标头