如何通过 REST API 将消息发送到使用自签名证书作为 Azure IoT 中心中的身份验证的设备

问题描述 投票:0回答:1

我正在使用 Golang 向 Azure IoT 中心发送消息,我们可能知道也可能不知道,Azure 没有适用于 Golang 的 SDK。

我找到了有关如何使用 SAS 令牌在整个 REST API 中执行此操作的答案

我在 SO

中使用 SAS 令牌找到了 Azure IoT 中心的 REST API

代码来自SO

func main() {
    
    sasToken :="SharedAccessSignature sr=<your IoT Hub name>.azure-devices.net/devices/<your device ID>&sig=<your signature>&se=<expiry time>&skn=<policy name>"

    
    deviceID := "sampath671"
    iotHubName := "certificate122ravi"

    
    url := fmt.Sprintf("https://%s.azure-devices.net/devices/%s?api-version=2020-05-31-preview", iotHubName, deviceID)

    
    requestBody := map[string]interface{}{
        "deviceId":                  deviceID,
        "status":                    "disabled",                        
        "statusReason":              "Device disabled for maintenance",
        "connectionState":           "Disconnected",                    
        "lastActivityTime":          "2024-03-12T12:00:00Z",        
        "cloudToDeviceMessageCount": 10,                                
    }
    requestBodyBytes, err := json.Marshal(requestBody)
    if err != nil {
        log.Fatal(err)
    }

    
    req, err := http.NewRequest("PUT", url, bytes.NewBuffer(requestBodyBytes))
    if err != nil {
        log.Fatal(err)
    }

    
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", sasToken)


    currentETag, err := getCurrentETag(deviceID, sasToken, iotHubName)
    if err != nil {
        log.Fatal(err)
    }

但我找不到任何有关使用 Azure IoT 中心认证的信息,我的 Azure IoT 中心设备需要 x509 身份验证 那么有人可以帮我解决具有 x509 身份验证的 Azure IoT 中心设备问题吗?

提前致谢。

azure go azure-iot-hub azure-rest-api
1个回答
0
投票

即使在 Azure IoT 中心创建SymmetricKey 类型的 X.509 自签名设备,用于管理 IoT 中心服务(包括设备消息传递、设备管理和作业调度)的 REST API 也使用

Authorization
标头作为来自此文档的共享访问签名 (SAS) 令牌。因此,发送设备事件/发送设备到云消息REST API使用 SAS 令牌。我们可以仅使用 SAS 令牌将消息发送到 X.509 自签名设备。

enter image description here

Go 中的以下代码用于在 Azure IoT 中心中使用身份验证类型 X.509 自签名创建或更新 IoT 设备身份:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

type DeviceAuthentication struct {
    Type             string `json:"type"`
    X509Thumbprint   X509Thumbprint `json:"x509Thumbprint"`
}

type X509Thumbprint struct {
    PrimaryThumbprint   string `json:"primaryThumbprint"`
    SecondaryThumbprint string `json:"secondaryThumbprint"`
}

type DeviceCapabilities struct {
    IotEdge bool `json:"iotEdge"`
}

type Device struct {
    Authentication           DeviceAuthentication `json:"authentication"`
    Capabilities             DeviceCapabilities   `json:"capabilities"`
    CloudToDeviceMessageCount int                  `json:"cloudToDeviceMessageCount"`
    ConnectionState          string               `json:"connectionState"`
    ConnectionStateUpdated   string               `json:"connectionStateUpdatedTime"`
    DeviceId                 string               `json:"deviceId"`
    DeviceScope              string               `json:"deviceScope"`
    Etag                     string               `json:"etag"`
    GenerationId             string               `json:"generationId"`
    LastActivityTime         string               `json:"lastActivityTime"`
    Status                   string               `json:"status"`
    StatusReason             string               `json:"statusReason"`
    StatusUpdatedTime        string               `json:"statusUpdatedTime"`
}

func main() {
    sasToken := "SharedAccessSignature sr=<your IoT Hub name>.azure-devices.net/devices/<your device ID>&sig=<your signature>&se=<expiry time>&skn=<policy name>"

    deviceID := "sampleDevice"
    iotHubName := "your-iot-hub-name"

    url := fmt.Sprintf("https://%s.azure-devices.net/devices/%s?api-version=2020-05-31-preview", iotHubName, deviceID)

    requestBody := Device{
        Authentication: DeviceAuthentication{
            Type: "selfSigned",
            X509Thumbprint: X509Thumbprint{
                PrimaryThumbprint:   "YOUR_PRIMARY_THUMBPRINT",
                SecondaryThumbprint: "YOUR_SECONDARY_THUMBPRINT",
            },
        },
        Capabilities:             DeviceCapabilities{IotEdge: false},
        CloudToDeviceMessageCount: 0,
        ConnectionState:          "Disconnected",
        ConnectionStateUpdated:   "2024-04-04T00:00:00Z",
        DeviceId:                 deviceID,
        DeviceScope:              "",
        Etag:                     "",
        GenerationId:             "",
        LastActivityTime:         "2024-04-04T00:00:00Z",
        Status:                   "enabled",
        StatusReason:             "",
        StatusUpdatedTime:        "2024-04-04T00:00:00Z",
    }

    requestBodyBytes, err := json.Marshal(requestBody)
    if err != nil {
        log.Fatal(err)
    }

    req, err := http.NewRequest("PUT", url, bytes.NewBuffer(requestBodyBytes))
    if err != nil {
        log.Fatal(err)
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", sasToken)

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    responseBody, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    if resp.StatusCode != http.StatusOK {
        log.Fatalf("Failed to create/update device: %s", responseBody)
    }

    fmt.Println("Device created/updated successfully!")
    fmt.Println("Response Body:", string(responseBody))
}

enter image description here

下面的代码通过 REST API 将设备到云消息发送到使用 X.509/SAS 身份验证的设备:

package main

import (
    "bytes"
    "fmt"
    "log"
    "net/http"
)

func main() {
    // Replace these variables with your actual values
    iotHubName := "your-iot-hub-name"
    deviceID := "your-device-id"
    sasToken := "SharedAccessSignature sr=<your IoT Hub name>.azure-devices.net&sig=<your signature>&se=<expiry time>&skn=<policy name>"

    // Message payload
    message := []byte(`{"data":"Hello from your device!"}`)

    // Construct the URL
    url := fmt.Sprintf("https://%s.azure-devices.net/devices/%s/messages/events?api-version=2020-03-13", iotHubName, deviceID)

    // Create a POST request with the message payload
    req, err := http.NewRequest("POST", url, bytes.NewBuffer(message))
    if err != nil {
        log.Fatal(err)
    }

    // Set the required headers
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", sasToken)

    // Send the request
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    // Check the response status
    if resp.StatusCode == http.StatusNoContent {
        fmt.Println("Message sent successfully!")
    } else {
        fmt.Printf("Failed to send message. Status code: %d\n", resp.StatusCode)
    }
}

enter image description here

要检查消息是否发送,请使用 Azure CLI 监视来自特定设备的 Azure IoT 中心的事件

az iot hub monitor-events --hub-name HubName --device-id deviceidname

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.