我必须使用DPS服务在IoT中心上注册设备。我无法使用.net SDK,因为设备固件不支持,所以我们决定使用基于REST的API来完成此操作。
使用C#SDK,我需要的只是带有密码,DPS_IDSCOPE和设备终结点的.PFX文件,诸如此类(xyz.azure-devices-provisioning.net)。
现在我如何使用以上信息对azure rest API进行同样的操作。对于身份验证,我在下面看到了一个链接,该链接说我必须使用SAS令牌才能与Azure AD访问令牌相同。
现在,如果我信任上面的链接(但是我认为它不起作用),那么证书.PFX文件的用途在哪里?
我已经找到了用于注册设备的官方API。
https://docs.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,那么属性的名称是什么?
下面是我尝试使用并遇到相同错误的示例代码。
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令牌:
公共静态无效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;
}
}
Helper方法:
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:“不受支持的媒体类型”,版本:1.1,内容:System.Net.Http.StreamContent,标头: { x-ms-request-id:6475343d-5a2e-407a-9e7f-896e0c489307 严格的运输安全性:max-age = 31536000; includeSubDomains 日期:2019年2月28日星期四11:42:59 GMT 内容长度:0 }}
期待获得帮助...
答案 0 :(得分:1)
请按照此处概述的步骤操作: 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(将idScope替换为DPS中的一个。示例idScope为0ne00000012)
答案 1 :(得分:1)
这个帖子很好地解释了它:http://busbyland.com/azure-iot-device-provisioning-service-via-rest-part-1/
使用此处记录的端点:https://docs.microsoft.com/es-es/rest/api/iot-dps/runtimeregistration/registerdevice
您可以设法使用 HTTPRequest 注册您的设备,请参阅上面的 CURL 示例:
curl -L -i -X PUT --cert ./chain.pem --key ./iot-device-1.key.pem -H 'Content-Type: application/json' -H 'Content-Encoding: utf-8' -d '{"registrationId": "iot-device-1", "payload": {"CustomProperty": "CustomValue"}}' https://global.azure-devices-provisioning.net/XXXXXXXXXXX/registrations/iot-device-1/register?api-version=2019-03-31
您可以在开发环境中复制该请求。
请注意,使用的是公共的 global.azure-devices-provisioning.net,您不需要任何身份验证/授权。