Microsoft Azure IoT Python SDK 可以成功配置但无法使用相同凭据连接

问题描述

我在 Linux 上使用 Python 3.8.2 和 azure iot python sdk 版本 2。我在 Azure 门户中设置了设备配置,可以使用以下代码成功配置我的设备。

配置代码

# Imports for Azure
from azure.iot.device import ProvisioningDeviceClient,X509
from azure.iot.device import IoTHubDeviceClient,Message

def runAzureProvisioning(azureConfig):

    # -------------------------------------------------------------------------
    # copyright (c) Microsoft Corporation. All rights reserved.
    # Licensed under the MIT License. See License.txt in the project root for
    # license information.
    # --------------------------------------------------------------------------

    provisioning_host = azureConfig["PROVISIONING_HOST"]
    id_scope = azureConfig["PROVISIONING_IDScopE"]
    registration_id = azureConfig["DPS_X509_REGISTRATION_ID"]

    x509 = X509(
        cert_file=azureConfig["X509_CERT_FILE"],key_file=azureConfig["X509_KEY_FILE"],pass_phrase=azureConfig["PASS_PHRASE"],)

    provisioning_device_client = ProvisioningDeviceClient.create_from_x509_certificate(
        provisioning_host=provisioning_host,registration_id=registration_id,id_scope=id_scope,x509=x509,)

    registration_result = provisioning_device_client.register()

    # The result can be directly printed to view the important details.
    app.config['LOGGER'].info(registration_result)

    if registration_result.status == "assigned":
        app.config['LOGGER'].info("Will send telemetry from the provisioned device")
        # Create device client from the above result
        device_client = IoTHubDeviceClient.create_from_x509_certificate(
            x509=x509,hostname=registration_result.registration_state.assigned_hub,device_id=registration_result.registration_state.device_id,)

        # Connect the client.
        device_client.connect()

        for i in range(1,2):
            app.config['LOGGER'].info("sending message #" + str(i))
            device_client.send_message("test payload message " + str(i))
            time.sleep(1)
        return 0,f"{registration_result.registration_state.device_id}"

    else:
        app.config['LOGGER'].info("Can not send telemetry from the provisioned device")
        return 1,"Can not send telemetry from the provisioned device"

供应输出

2021-02-10 19:59:58,313 - azure.iot.device.common.mqtt_transport:137 - INFO - creating mqtt client
2021-02-10 19:59:58,317 - azure.iot.device.common.mqtt_transport:150 - INFO - Creating client for connecting using MQTT over TCP
2021-02-10 19:59:58,412 - azure.iot.device.provisioning.provisioning_device_client:70 - INFO - Registering with Provisioning Service...
2021-02-10 19:59:58,416 - azure.iot.device.provisioning.provisioning_device_client:91 - INFO - Enabling reception of response from Device Provisioning Service...
2021-02-10 19:59:58,428 - azure.iot.device.common.pipeline.pipeline_stages_base:955 - INFO - ReconnectStage(ConnectOperation): State changes LOGICALLY_disCONNECTED->LOGICALLY_CONNECTED.  Adding to wait list and sending new connect op down
2021-02-10 19:59:58,435 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:171 - INFO - MQTTTransportStage(ConnectOperation): connecting
2021-02-10 19:59:58,443 - azure.iot.device.common.mqtt_transport:374 - INFO - connecting to mqtt broker
2021-02-10 19:59:58,447 - azure.iot.device.common.mqtt_transport:385 - INFO - Connect using port 8883 (TCP)
2021-02-10 20:00:01,583 - azure.iot.device.common.mqtt_transport:180 - INFO - connected with result code: 0
2021-02-10 20:00:01,589 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:275 - INFO - _on_mqtt_connected called
2021-02-10 20:00:01,599 - azure.iot.device.common.pipeline.pipeline_stages_base:552 - INFO - ConnectionLockStage(ConnectOperation): processing 0 items in queue
2021-02-10 20:00:01,607 - azure.iot.device.common.pipeline.pipeline_stages_base:1141 - INFO - ReconnectStage: completing waiting ops with error=None
2021-02-10 20:00:01,612 - azure.iot.device.common.pipeline.pipeline_stages_base:411 - INFO - AutoConnectStage(MQTTSubscribeOperation): Connected.  Sending down and adding callback to check result
2021-02-10 20:00:01,621 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:225 - INFO - MQTTTransportStage(MQTTSubscribeOperation): subscribing to $dps/registrations/res/#
2021-02-10 20:00:01,625 - azure.iot.device.common.mqtt_transport:474 - INFO - subscribing to $dps/registrations/res/# with qos 1
2021-02-10 20:00:01,706 - azure.iot.device.common.mqtt_transport:234 - INFO - suback received for 1
2021-02-10 20:00:01,718 - azure.iot.device.provisioning.provisioning_device_client:98 - INFO - Successfully subscribed to Device Provisioning Service to receive responses
2021-02-10 20:00:01,736 - azure.iot.device.common.pipeline.pipeline_stages_base:411 - INFO - AutoConnectStage(MQTTPublishOperation): Connected.  Sending down and adding callback to check result
2021-02-10 20:00:01,741 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:211 - INFO - MQTTTransportStage(MQTTPublishOperation): publishing on $dps/registrations/PUT/iotdps-register/?$rid=aa969347-7e41-41e4-b874-54b995f129ef
2021-02-10 20:00:01,747 - azure.iot.device.common.mqtt_transport:533 - INFO - publishing on $dps/registrations/PUT/iotdps-register/?$rid=aa969347-7e41-41e4-b874-54b995f129ef
2021-02-10 20:00:01,817 - azure.iot.device.common.mqtt_transport:248 - INFO - payload published for 2
2021-02-10 20:00:02,066 - azure.iot.device.common.mqtt_transport:255 - INFO - message received on $dps/registrations/res/202/?$rid=aa969347-7e41-41e4-b874-54b995f129ef&retry-after=3
2021-02-10 20:00:02,074 - azure.iot.device.provisioning.pipeline.pipeline_stages_provisioning_mqtt:129 - INFO - Received payload:b'{"operationId":"4.bd46492d8689531e.a04c1182-f5d8-4ea7-b2fd-4902abb2f789","status":"assigning"}' on topic:$dps/registrations/res/202/?$rid=aa969347-7e41-41e4-b874-54b995f129ef&retry-after=3
2021-02-10 20:00:02,086 - azure.iot.device.provisioning.pipeline.pipeline_stages_provisioning:399 - WARNING - RegistrationStage(RequestAndResponSEOperation): Op will transition into polling after interval 2.  Setting timer.
2021-02-10 20:00:04,099 - azure.iot.device.provisioning.pipeline.pipeline_stages_provisioning:384 - INFO - RegistrationStage(RequestAndResponSEOperation): polling
2021-02-10 20:00:04,111 - azure.iot.device.common.pipeline.pipeline_stages_base:411 - INFO - AutoConnectStage(MQTTPublishOperation): Connected.  Sending down and adding callback to check result
2021-02-10 20:00:04,116 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:211 - INFO - MQTTTransportStage(MQTTPublishOperation): publishing on $dps/registrations/GET/iotdps-get-operationstatus/?$rid=04db5bb9-5e70-45cf-91a6-6d9df8a34478&operationId=4.bd46492d8689531e.a04c1182-f5d8-4ea7-b2fd-4902abb2f789
2021-02-10 20:00:04,120 - azure.iot.device.common.mqtt_transport:533 - INFO - publishing on $dps/registrations/GET/iotdps-get-operationstatus/?$rid=04db5bb9-5e70-45cf-91a6-6d9df8a34478&operationId=4.bd46492d8689531e.a04c1182-f5d8-4ea7-b2fd-4902abb2f789
2021-02-10 20:00:04,190 - azure.iot.device.common.mqtt_transport:248 - INFO - payload published for 3
2021-02-10 20:00:04,206 - azure.iot.device.common.mqtt_transport:255 - INFO - message received on $dps/registrations/res/200/?$rid=04db5bb9-5e70-45cf-91a6-6d9df8a34478
2021-02-10 20:00:04,213 - azure.iot.device.provisioning.pipeline.pipeline_stages_provisioning_mqtt:129 - INFO - Received payload:b'{"operationId":"4.bd46492d8689531e.a04c1182-f5d8-4ea7-b2fd-4902abb2f789","status":"assigned","registrationState":{"x509":{"enrollmentGroupId":"New-Gateway-Jack"},"registrationId":"New-Gateway-Jack","createdDateTimeUtc":"2021-02-10T20:00:02.2501194Z","assignedHub":"New-Gateway-Test-Jack.azure-devices.net","deviceid":"New-Gateway-Jack","substatus":"initialAssignment","lastUpdatedDateTimeUtc":"2021-02-10T20:00:02.4704038Z","etag":"IjM1MDA2OGJjLTAwMDAtMDEwMC0wMDAwLTYwMjQzYjQyMDAwMCI="}}' on topic:$dps/registrations/res/200/?$rid=04db5bb9-5e70-45cf-91a6-6d9df8a34478
2021-02-10 20:00:04,231 - azure.iot.device.provisioning.abstract_provisioning_device_client:221 - INFO - Successfully registered with Provisioning Service
2021-02-10 20:00:04,235 - /usr/bin/company/cloudcredentials/app.py:442 - INFO - New-Gateway-Jack
New-Gateway-Test-Jack.azure-devices.net
initialAssignment
null
assigned
2021-02-10 20:00:04,239 - /usr/bin/company/cloudcredentials/app.py:445 - INFO - Will send telemetry from the provisioned device
2021-02-10 20:00:04,273 - azure.iot.device.common.mqtt_transport:137 - INFO - creating mqtt client
2021-02-10 20:00:04,277 - azure.iot.device.common.mqtt_transport:150 - INFO - Creating client for connecting using MQTT over TCP
2021-02-10 20:00:04,303 - azure.iot.device.iothub.sync_clients:112 - INFO - Connecting to Hub...
2021-02-10 20:00:04,315 - azure.iot.device.common.pipeline.pipeline_stages_base:955 - INFO - ReconnectStage(ConnectOperation): State changes LOGICALLY_disCONNECTED->LOGICALLY_CONNECTED.  Adding to wait list and sending new connect op down
2021-02-10 20:00:04,321 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:171 - INFO - MQTTTransportStage(ConnectOperation): connecting
2021-02-10 20:00:04,329 - azure.iot.device.common.mqtt_transport:374 - INFO - connecting to mqtt broker
2021-02-10 20:00:04,333 - azure.iot.device.common.mqtt_transport:385 - INFO - Connect using port 8883 (TCP)
2021-02-10 20:00:04,951 - azure.iot.device.common.mqtt_transport:180 - INFO - connected with result code: 0
2021-02-10 20:00:04,957 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:275 - INFO - _on_mqtt_connected called
2021-02-10 20:00:04,966 - azure.iot.device.common.pipeline.pipeline_stages_base:552 - INFO - ConnectionLockStage(ConnectOperation): processing 0 items in queue
2021-02-10 20:00:04,969 - azure.iot.device.iothub.sync_clients:86 - INFO - Connection State - Connected
2021-02-10 20:00:04,975 - azure.iot.device.common.pipeline.pipeline_stages_base:1141 - INFO - ReconnectStage: completing waiting ops with error=None
2021-02-10 20:00:04,986 - azure.iot.device.iothub.sync_clients:118 - INFO - Successfully connected to Hub
2021-02-10 20:00:04,990 - /usr/bin/company/cloudcredentials/app.py:457 - INFO - sending message #1
2021-02-10 20:00:04,995 - azure.iot.device.iothub.sync_clients:166 - INFO - Sending message to Hub...
2021-02-10 20:00:05,004 - azure.iot.device.common.pipeline.pipeline_stages_base:411 - INFO - AutoConnectStage(MQTTPublishOperation): Connected.  Sending down and adding callback to check result
2021-02-10 20:00:05,009 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:211 - INFO - MQTTTransportStage(MQTTPublishOperation): publishing on devices/New-Gateway-Jack/messages/events/
2021-02-10 20:00:05,013 - azure.iot.device.common.mqtt_transport:533 - INFO - publishing on devices/New-Gateway-Jack/messages/events/
2021-02-10 20:00:05,295 - azure.iot.device.common.mqtt_transport:248 - INFO - payload published for 1
2021-02-10 20:00:05,306 - azure.iot.device.iothub.sync_clients:172 - INFO - Successfully sent message to Hub

现在,我正在尝试使用我在上面使用以下代码成功提供和连接的凭据连接(而不是提供)。

成功配置后,我保存以下数据(密钥、证书和字符串):

        # Now use the credentials to provision this device
        # NOTE: If the credentials were accepted by Azure,the message returned here is the 'device id'
        (status,message) = runAzureProvisioning(azureConfig)
        if status != 0:

            responseJson = {"response": f"error: Could not Run Azure provisioning script: {message}"}
            return make_response(jsonify(responseJson),550)

        else:

            # Write the Meta information out to a JSON file as well
            MetaData = {}
            MetaData['provisioning_host'] = f"{provisioninghost}"
            MetaData['provisioning_id_scope'] = f"{provisioningidscope}"
            MetaData['x509_registration_id'] = f"{x509registrationid}"
            MetaData['device_id'] = f"{message}"
            MetaData['key'] = f"{path.join(app.config['AZURE_CREDS_UPLOAD_PATH'],azureConfig['X509_KEY_FILE'])}"
            MetaData['cert'] = f"{path.join(app.config['AZURE_CREDS_UPLOAD_PATH'],azureConfig['X509_CERT_FILE'])}"
            with open(f"{app.config['AZURE_CREDS_UPLOAD_PATH']}/Meta.json",'w') as outfile:
                json.dump(MetaData,outfile)

            responseJson = {"response": f"success"}
            return make_response(jsonify(responseJson),200)

然后,稍后我阅读了保存的信息,并尝试连接:

            # Ensure we have everything we need to connect
            if not MetaData.get("provisioning_host") or not MetaData.get("provisioning_id_scope") \
                    or not MetaData.get("x509_registration_id") or not MetaData.get("key") or not MetaData.get("cert") \
                    or not MetaData.get("device_id"):
                responseJson = {"response": f"error: Could not find all required Meta data in JSON store: {MetaData}"}
                return make_response(jsonify(responseJson),550)

            # Define the required credentials to establish a connection
            # Get the x.509 certificate path from the Meta information
            x509 = X509(
                cert_file=MetaData.get("cert"),key_file=MetaData.get("key"),pass_phrase=None
            )

            # Todo: Get a proper hostname here
            client = IoTHubDeviceClient.create_from_x509_certificate(hostname=MetaData.get("provisioning_host"),device_id=MetaData.get("device_id"),x509=x509)

            # Try to connect
            try:

                # Attempt to connect
                app.config['LOGGER'].info(
                    f"Connecting with: {MetaData.get('x509_registration_id')} | {MetaData.get('key')} | {MetaData.get('cert')}")
                client.connect()
                client.disconnect()

                responseJson = {"response": f"success"}
                return make_response(jsonify(responseJson),200)

            except Exception as err:

                responseJson = {"response": f"error: Could not connect to AWS: {err}"}
                return make_response(jsonify(responseJson),550)

但我收到“未经授权”和“拒绝连接”错误,如下所示:

2021-02-10 20:00:13,073 - azure.iot.device.common.mqtt_transport:137 - INFO - creating mqtt client
2021-02-10 20:00:13,078 - azure.iot.device.common.mqtt_transport:150 - INFO - Creating client for connecting using MQTT over TCP
2021-02-10 20:00:13,109 - /usr/bin/company/cloudcredentials/app.py:1190 - INFO - Connecting with: New-Gateway-Jack | /persistent-storage/azure-creds/device.key | /persistent-storage/azure-creds/device.crt
2021-02-10 20:00:13,114 - azure.iot.device.iothub.sync_clients:112 - INFO - Connecting to Hub...
2021-02-10 20:00:13,122 - azure.iot.device.common.pipeline.pipeline_stages_base:955 - INFO - ReconnectStage(ConnectOperation): State changes LOGICALLY_disCONNECTED->LOGICALLY_CONNECTED.  Adding to wait list and sending new connect op down
2021-02-10 20:00:13,128 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:171 - INFO - MQTTTransportStage(ConnectOperation): connecting
2021-02-10 20:00:13,139 - azure.iot.device.common.mqtt_transport:374 - INFO - connecting to mqtt broker
2021-02-10 20:00:13,143 - azure.iot.device.common.mqtt_transport:385 - INFO - Connect using port 8883 (TCP)
2021-02-10 20:00:16,240 - azure.iot.device.common.mqtt_transport:180 - INFO - connected with result code: 5
2021-02-10 20:00:16,248 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:300 - INFO - MQTTTransportStage: _on_mqtt_connection_failure called: UnauthorizedError('Connection Refused: not authorised.')
2021-02-10 20:00:16,254 - azure.iot.device.common.pipeline.pipeline_ops_base:107 - ERROR - ConnectOperation: completing with error UnauthorizedError('Connection Refused: not authorised.')
2021-02-10 20:00:16,258 - azure.iot.device.common.mqtt_transport:206 - INFO - disconnected with result code: 5
2021-02-10 20:00:16,262 - azure.iot.device.common.pipeline.pipeline_stages_base:518 - ERROR - ConnectionLockStage(ConnectOperation): op Failed.  Unblocking queue with error: UnauthorizedError('Connection Refused: not authorised.')
2021-02-10 20:00:16,274 - azure.iot.device.common.pipeline.pipeline_stages_base:552 - INFO - ConnectionLockStage(ConnectOperation): processing 0 items in queue
2021-02-10 20:00:16,279 - azure.iot.device.common.pipeline.pipeline_stages_base:1141 - INFO - ReconnectStage: completing waiting ops with error=UnauthorizedError('Connection Refused: not authorised.')
2021-02-10 20:00:16,283 - azure.iot.device.common.pipeline.pipeline_ops_base:107 - ERROR - ConnectOperation: completing with error UnauthorizedError('Connection Refused: not authorised.')
2021-02-10 20:00:16,290 - azure.iot.device.common.evented_callback:48 - ERROR - Callback completed with error UnauthorizedError('Connection Refused: not authorised.')
2021-02-10 20:00:16,295 - azure.iot.device.common.evented_callback:49 - ERROR - nonetype: None

2021-02-10 20:00:16,383 - azure.iot.device.common.mqtt_transport:297 - INFO - Forcing paho disconnect to prevent it from automatically reconnecting
2021-02-10 20:00:16,390 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:322 - INFO - MQTTTransportStage: _on_mqtt_disconnect called: ConnectionFailedError('The connection was refused.')
2021-02-10 20:00:16,398 - azure.iot.device.common.pipeline.pipeline_stages_mqtt:360 - INFO - MQTTTransportStage: disconnection was unexpected
2021-02-10 20:00:16,400 - azure.iot.device.iothub.sync_clients:90 - INFO - Connection State - disconnected
2021-02-10 20:00:16,409 - azure.iot.device.iothub.sync_clients:92 - INFO - Cleared all pending method requests due to disconnect
2021-02-10 20:00:16,404 - azure.iot.device.common.handle_exceptions:52 - INFO - Unexpected disconnection.  Safe to ignore since other stages will reconnect.
2021-02-10 20:00:16,422 - azure.iot.device.common.handle_exceptions:53 - INFO - azure.iot.device.common.transport_exceptions.ConnectionFailedError: ConnectionFailedError('The connection was refused.')

那么,为什么我可以成功配置,但以后无法使用相同的凭据进行连接?谢谢。

解决方法

答案是 MS 不知道如何解决这个问题。有两张票与您在 githubmicrosoft docs 上的问题相同。

首先重要的是要知道您的确切版本 azure-iot-sdk-python。记者有这些:

软件版本:Python==3.7.8 azure-iot-device==2.3.0

我认为 azure-iot-sdk-python 中存在回归。目前微软知道问题的原因。

怎么办?

我会向微软报告:

你好@VarunVenkatesh-7647,你能给我们发一封电子邮件吗 附上您的python应用程序代码。请删除您的 IoT Central 的 ID 附加前 .py 文件中的范围、设备 ID 和主键 它发送到电子邮件。

请将以下内容发送至 azcommunity@microsoft.com 详细信息,以便我们处理此事。

主题网址:此主题的链接。主题 : Attn Satish Boddu 附件:您的environment_sensor.py 文件。

接下来要尝试的是逐渐降级您的 azure-iot-sdk-python,看看问题是否得到解决。然后,您可以进行 diff 次更改并将其发送给 Microsoft。