使用 Azure 设备配置服务的其余 API 注册设备? [英] Register Device using rest API of Azure device provisioning service?
问题描述
我必须使用 DPS 服务在 IoT 中心注册设备.我无法使用 .net SDK,因为设备固件不支持,所以我们决定使用基于 REST 的 API 来做同样的事情.
使用 C# SDK,我只需要带密码的 .PFX 文件、DPS_IDSCOPE 和类似这样的设备端点 (xyz.azure-devices-provisioning.net).
现在我如何使用上述信息对 azure rest API 做同样的事情.对于身份验证,我看到下面的链接说我必须使用 SAS 令牌,因为 Azure AD 访问令牌不起作用.
现在下面是我尝试使用并遇到相同错误的示例代码.
方式 1(使用 .PFX 作为身份验证)
public static void RegisterDeviceWithEnrollementGroup(){尝试{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");字符串内容 = Newtonsoft.Json.JsonConvert.SerializeObject(null);var httpContent3 = new StringContent(content, Encoding.UTF8, "application/json");var pair = new List>{new KeyValuePair("registrationId", "device1"),new KeyValuePair("type", "x509"),};var content2 = new FormUrlEncodedContent(pairs);HttpResponseMessage response4 = client4.PutAsync(client4.BaseAddress.ToString(), content2).Result;var commandResult = string.Empty;如果(响应4.IsSuccessStatusCode){commandResult = response4.Content.ReadAsStringAsync().Result;}别的{commandResult = response4.Content.ReadAsStringAsync().Result;}Console.WriteLine("IoT hub API 调用结果 - " + commandResult);}捕获(异常){扔;}}
方式 2 - 使用 SAS 令牌:
public static void RegisterDeviceWithEnrollementGroup(){尝试{
HttpClient client4 = new HttpClient();
var sas = generateSasToken("XYZ.azure-devices-provisioning.net", "key", "provisioningserviceowner");client4.DefaultRequestHeaders.Add("授权", 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");字符串内容 = Newtonsoft.Json.JsonConvert.SerializeObject(null);var httpContent3 = new StringContent(content, Encoding.UTF8, "application/json");var pair = new List>{new KeyValuePair("registrationId", "device1"),new KeyValuePair("type", "x509"),};var content2 = new FormUrlEncodedContent(pairs);HttpResponseMessage response4 = client4.PutAsync(client4.BaseAddress.ToString(), content2).Result;var commandResult = string.Empty;如果(响应4.IsSuccessStatusCode){commandResult = response4.Content.ReadAsStringAsync().Result;}别的{commandResult = response4.Content.ReadAsStringAsync().Result;}Console.WriteLine("IoT hub API 调用结果 - " + commandResult);}捕获(异常){扔;}}
辅助方法:
public static string generateSasToken(string resourceUri, string key, string policyName, int expiryInSeconds = 3600){TimeSpan fromEpochStart = DateTime.UtcNow - new DateTime(1970, 1, 1);字符串到期 = Convert.ToString((int)fromEpochStart.TotalSeconds + expiryInSeconds);string stringToSign = WebUtility.UrlEncode(resourceUri) + "\n" + 到期;HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));字符串签名 = 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)){令牌 += "&skn=" + policyName;}返回令牌;}
现在请回答一些身体问题,我在这里做对还是错,因为我遇到了异常.
<块引用>{StatusCode: 415, ReasonPhrase: 'Unsupported Media Type', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:{x-ms-request-id: 6475343d-5a2e-407a-9e7f-896e0c489307严格传输安全:max-age=31536000;包含子域日期:2019 年 2 月 28 日星期四 11:42:59 GMT内容长度:0}}
期待帮助...
请按照此处列出的步骤操作:https://docs.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".
设备端点如下:
PUT https://global.azure-devices-provisioning.net/{idScope}/registrations/device1/register?api-version=2018-11-01(用您的 DPS 中的那个替换 idScope.示例 idScope 将是 0ne00000012)
I have to register a device on IoT hub using DPS service. I cannot use the .net SDK as device firmware does not support so we decided to use the REST based API's to do the same.
With C# SDK all I need are the .PFX file with password, DPS_IDSCOPE and device endpoint something like this (xyz.azure-devices-provisioning.net).
Now How I can use above information to do the same with azure rest API.For Authentication I have seen below link which says I have to use SAS token for the same as Azure AD access token wont work.
Now If I trust on above link (However I do not think it will work ) then where is the use of certificate .PFX file ?
I have found this official API to register the device .
https://docs.microsoft.com/en-us/rest/api/iot-dps/runtimeregistration/registerdevice
I have not understand how to pass the body information like structure of JSON.I know I have to use x509 as Attestation type but how I will form is it like
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("registrationId", "device1"),
new KeyValuePair<string, string>("type", "x509"),
};
Or if its a json then what will be the name of attribute ?
Now below are the sample code that I tried to use and getting same error.
Way-1 (Used .PFX as authentication)
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;
}
}
Way-2 - Using SAS token :
public static void RegisterDeviceWithEnrollementGroup()
{
try
{
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;
}
}
Helper method :
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;
}
Now Please answer some body whether I am doing correct or wrong here as I am getting exception.
{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 }}
Looking forward for the help ...
Please follow the steps outlined here: https://docs.microsoft.com/en-us/azure/iot-dps/tutorial-net-provision-device-to-hub to first create an Enrollment in DPS for this device using X.509 (no need to use EnrollmentGroup for a single device).
When registering a device with DPS, use the global endpoint - global.azure-devices-provisioning.net. Configure the HTTP client to include the device client certificate. Do not provide a SAStoken from the device.
You can setup the HTTP message content for device registration as follows:
httpRequest.Content = new StringContent("{\"registrationId\": \"device1\"}", Encoding.UTF8); httpRequest.Content.Headers.ContentType=MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
Note that the JSON content does NOT include "type" : "x509".
The device endpoint would be as follows:
PUT https://global.azure-devices-provisioning.net/{idScope}/registrations/device1/register?api-version=2018-11-01 (replace idScope with the one from your DPS. A sample idScope would be 0ne00000012)
这篇关于使用 Azure 设备配置服务的其余 API 注册设备?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!