azure - 使用 Azure 设备预配服务的 REST API 注册设备?

标签 azure x509certificate azure-iot-hub azure-iot-hub-device-management

我必须使用 DPS 服务在 IoT 中心注册设备。我无法使用 .net SDK,因为设备固件不支持,因此我们决定使用基于 REST 的 API 来执行相同的操作。

使用 C# SDK,我需要的只是带有密码、DPS_IDSCOPE 和设备端点(xyz.azure-devices-provisioning.net)的 .PFX 文件。

现在我如何使用上述信息对 azure rest API 执行相同的操作。对于身份验证,我在下面看到了链接,该链接说我必须使用 SAS token ,因为 Azure AD 访问 token 不起作用。

https://social.msdn.microsoft.com/Forums/en-US/19183e82-437e-4d6f-8498-ed33ba18a3fa/creating-iot-device-with-azure-dps-via-rest?forum=azureiothub

现在,如果我信任上面的链接(但我认为它不会起作用),那么证书 .PFX 文件的用途在哪里?

我找到了这个官方API来注册设备。

https://learn.microsoft.com/en-us/rest/api/iot-dps/runtimeregistration/registerdevice

我不明白如何传递 JSON 结构等主体信息。我知道我必须使用 x509 作为证明类型,但我将如何形成它就像

  var pairs = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("registrationId", "device1"),
            new KeyValuePair<string, string>("type", "x509"),

         };

或者如果它是 json 那么属性的名称是什么?

enter image description here

现在下面是我尝试使用并得到相同错误的示例代码。

Way-1(使用.PFX作为身份验证)

  public static void RegisterDeviceWithEnrollementGroup()
    {
        try
        {
            var handler = new WebRequestHandler();
            var certFile = Path.Combine(@"C:\IoT\", "device1.pfx");
            handler.ClientCertificates.Add(new X509Certificate2(certFile, "certificatepassword"));
            HttpClient client4 = new HttpClient(handler);

            client4.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client4.BaseAddress = new Uri("https://XYZ.azure-devices-provisioning.net/scopeid/registrations/device1/register?api-version=2018-11-01");
            string content = Newtonsoft.Json.JsonConvert.SerializeObject(null);
            var httpContent3 = new StringContent(content, Encoding.UTF8, "application/json");


            var pairs = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("registrationId", "device1"),
            new KeyValuePair<string, string>("type", "x509"),

         };

            var content2 = new FormUrlEncodedContent(pairs);


            HttpResponseMessage response4 = client4.PutAsync(client4.BaseAddress.ToString(), content2).Result;

            var commandResult = string.Empty;

            if (response4.IsSuccessStatusCode)
            {
                commandResult = response4.Content.ReadAsStringAsync().Result;
            }
            else
            {
                commandResult = response4.Content.ReadAsStringAsync().Result;
            }

            Console.WriteLine("IoT hub API call result - " + commandResult);
        }
        catch (Exception)
        {
            throw;
        }
    } 

方式 2 - 使用 SAS token :

公共(public)静态无效RegisterDeviceWithEnrollementGroup() { 尝试 {
HttpClient client4 = new HttpClient();

            var sas = generateSasToken("XYZ.azure-devices-provisioning.net", "key", "provisioningserviceowner");
             client4.DefaultRequestHeaders.Add("Authorization", sas);

            client4.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));


            client4.BaseAddress = new Uri("https://XYZ.azure-devices-provisioning.net/scopeid/registrations/device1/register?api-version=2018-11-01");
            string content = Newtonsoft.Json.JsonConvert.SerializeObject(null);
            var httpContent3 = new StringContent(content, Encoding.UTF8, "application/json");


            var pairs = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("registrationId", "device1"),
            new KeyValuePair<string, string>("type", "x509"),

         };

            var content2 = new FormUrlEncodedContent(pairs);


            HttpResponseMessage response4 = client4.PutAsync(client4.BaseAddress.ToString(), content2).Result;

            var commandResult = string.Empty;

            if (response4.IsSuccessStatusCode)
            {
                commandResult = response4.Content.ReadAsStringAsync().Result;
            }
            else
            {
                commandResult = response4.Content.ReadAsStringAsync().Result;
            }

            Console.WriteLine("IoT hub API call result - " + commandResult);
        }
        catch (Exception)
        {
            throw;
        }
    }

辅助方法:

 public static string generateSasToken(string resourceUri, string key, string policyName, int expiryInSeconds = 3600)
    {
        TimeSpan fromEpochStart = DateTime.UtcNow - new DateTime(1970, 1, 1);
        string expiry = Convert.ToString((int)fromEpochStart.TotalSeconds + expiryInSeconds);

        string stringToSign = WebUtility.UrlEncode(resourceUri) + "\n" + expiry;

        HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));
        string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

        string token = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}", WebUtility.UrlEncode(resourceUri), WebUtility.UrlEncode(signature), expiry);

        if (!String.IsNullOrEmpty(policyName))
        {
            token += "&skn=" + policyName;
        }

        return token;
    }

现在请回答一些人我在这里做的是正确还是错误,因为我遇到了异常。

{StatusCode: 415, ReasonPhrase: 'Unsupported Media Type', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { x-ms-request-id: 6475343d-5a2e-407a-9e7f-896e0c489307 Strict-Transport-Security: max-age=31536000; includeSubDomains Date: Thu, 28 Feb 2019 11:42:59 GMT Content-Length: 0 }}

期待帮助......

最佳答案

请按照此处概述的步骤操作: https://learn.microsoft.com/en-us/azure/iot-dps/tutorial-net-provision-device-to-hub 首先使用 X.509 在 DPS 中为此设备创建一个注册(无需为单个设备使用 EnrollmentGroup)。

向 DPS 注册设备时,请使用全局终结点 - global.azure-devices-provisioning.net。配置 HTTP 客户端以包含设备客户端证书。不要从设备提供 SAStoken。

您可以按如下方式设置设备注册的 HTTP 消息内容:

httpRequest.Content = new StringContent("{\"registrationId\":\"device1\"}", Encoding.UTF8); httpRequest.Content.Headers.ContentType=MediaTypeHeaderValue.Parse("application/json; charset=utf-8");

请注意,JSON 内容不包含“type”:“x509”。

设备端点如下:

放置https://global.azure-devices-provisioning.net/ {idScope}/registrations/device1/register?api-version=2018-11-01(将 idScope 替换为您的 DPS 中的 idScope。示例 idScope 为 0ne00000012)

关于azure - 使用 Azure 设备预配服务的 REST API 注册设备?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54924984/

相关文章:

Azure 物联网中心反馈接收器 ReceiveAsync 非常慢(15 秒)高延迟

azure-functions - 具有 IoT 中心触发获取发送设备的 Azure 功能

azure - 获取 : bad option; for several filesystems (e. g。 nfs、cifs)尝试在 K8 容器中挂载 azure 文件共享时

azure - 从本地 MySQL 提取数据并将其转换到 Azure Synapse 数据仓库

google-chrome - 是否可以使用 Azure 通知中心向 Chrome Web 用户发送推送通知?

x509certificate - 如何在Corda中手动生成网络参数

c# - X509证书和XmlDsig

java - 如何在 java 中使用 bouncycaSTLe 将 PrivateKeyUsage 扩展添加到证书?

azure - Microsoft Azure Iot Hub 中的分区有什么作用?

azure - VS 2015 架构比较未显示但已检测到的差异