Зарегистрировать устройство с помощью API остальных службы предоставления устройств Azure?
Я должен зарегистрировать устройство на IoT-хабе, используя сервис DPS. Я не могу использовать.net SDK, так как прошивка устройства не поддерживает, поэтому мы решили использовать API на основе REST, чтобы сделать то же самое.
С C# SDK все, что мне нужно, это файл.PFX с паролем, DPS_IDSCOPE и конечная точка устройства примерно так (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, Content: System.Net.Http.StreamContent, заголовки: { x-ms-request-id: 6475343d-5a2e-407a-9e7f-896e0c489307 Strict-Transport-Безопасность: максимальный возраст =31536000; includeSubDomains Дата: четверг, 28 февраля 2019 11:42:59 GMT Длина контента: 0 }}
Ждем помощи...
2 ответа
Выполните действия, описанные здесь: https://docs.microsoft.com/en-us/azure/iot-dps/tutorial-net-provision-device-to-hub чтобы сначала создать регистрацию в DPS для этого устройства с помощью X.509 (нет необходимости использовать 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)
Этот POST хорошо объясняет это: 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, который является общедоступным, и вам не требуется никакой аутентификации / авторизации.