我必须使用 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 那么属性的名称是什么?
现在下面是我尝试使用并得到相同错误的示例代码。
方式 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 令牌:
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;
}
}
辅助方法:
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 Strict-Transport -安全性:最大年龄=31536000;includeSubDomains 日期:2019 年 2 月 28 日星期四 11:42:59 GMT 内容长度:0 }}
期待帮助...