我目前正在研究从 Azure IoT 中心迁移到 RabbitMQ 的可能性。请保留对 C2D 和 Twins 的所有评论,因为我还在忙于身份验证,当我到达它时,我会烧毁这座桥梁。目前完全不能将我们的嵌入式系统转换为使用另一个 MQTT 客户端。
我创建了一个运行 RabbitMQ 实例并具有所有必需证书的 Docker 容器。我使用 MQTTnet 创建了一个小型控制台应用程序,并且使用 SSL 证书连接到实例时没有任何问题。当我使用 Microsoft.Azure.Devices.Client 并尝试连接时,连接失败。据我所见,身份验证用户设置为某个构建的字符串,而密码为空。当我返回工作控制台应用程序并添加相同的用户字符串和空白密码时,我遇到了完全相同的问题。
用户名字符串的格式为“DOMAINNAME/DEVICEID/?api-version=2020-09-30&DeviceClientType=.NET%2F1.41.2%20%28....”。
从我收集的帮助文件中,我应该尝试提取设备证书的通用名称,而不是使用它进行身份验证/授权,但只要添加用户名和空密码,我的配置是什么并不重要,连接失败。
RabbitMQ Docker 容器支持以下插件,我已经验证它们正在运行。
我正在使用 RabbitMQ 的自定义配置文件,配置如下(是的,令牌已替换并且正在运行)。
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/certificates/$CACertificateName$
ssl_options.certfile = /etc/rabbitmq/certificates/$ServerCertificateName$
ssl_options.keyfile = /etc/rabbitmq/certificates/$ServerKeyName$
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = true
mqtt.listeners.tcp.default = 1883
mqtt.listeners.ssl.default = 8883
mqtt.allow_anonymous = false
## Number of Erlang processes that will accept connections for the TCP
## and TLS listeners.
##
# mqtt.num_acceptors.tcp = 10
# mqtt.num_acceptors.ssl = 10
mqtt.vhost = /
mqtt.exchange = amq.topic
# 24 hours by default
mqtt.max_session_expiry_interval_seconds = 86400
mqtt.prefetch = 10
# Authentication
auth_mechanisms.1 = EXTERNAL
auth_mechanisms.2 = PLAIN
auth_mechanisms.3 = AMQPLAIN
ssl_cert_login_from = common_name
log.file.level = debug
log.console.level = info
最后,SSL 证书中的通用名称的值为“powershell-test”。这是我用来连接的设备 ID。
是否有某种方法可以强制它忽略发送的用户凭据,或者我是否必须开始寻找其他方法来实现此目的。看起来,一旦看到身份验证已填充,就会跳过 SSL 证书验证。
最后,这是 RabbitMQ 日志的屏幕截图
使用 MQTTnet,您可以使用 SSL 证书连接到实例,但在尝试使用
Microsoft.Azure.Devices.Client
连接时,由于证书/密码问题,连接失败。
下面的示例代码通过
Microsoft.Azure.Devices.Client
使用 X.509 证书身份验证将设备连接到 Azure IoT 中心。
它从文件系统加载 X.509 证书,指定设备 ID,使用证书创建设备身份验证,并使用指定的 IoT 中心主机名、身份验证方法和 MQTT 传输类型建立设备客户端。
var cert = new X509Certificate2("C:\\certificate.cer");
string deviceId = "Device ID";
// Create device authentication using X.509 certificate
var auth = new DeviceAuthenticationWithX509Certificate(deviceId, cert);
string iotHubHostname = "Hostname";
var deviceClient = DeviceClient.Create(iotHubHostname, auth, TransportType.Mqtt);
deviceClient.SetConnectionStatusChangesHandler((status, reason) =>
{
Task.Run(async () =>
{
Console.WriteLine($"Connection status changed to: {status}");
if (status == ConnectionStatus.Connected)
{
Console.WriteLine("Device connected!");
}
});
});
// Connect to the IoT hub
await deviceClient.OpenAsync();
// Define the message to be sent
var message = new Message(Encoding.ASCII.GetBytes("Test message"));
// Send the message to the IoT device
await deviceClient.SendEventAsync(message);
// Close the connection to the IoT hub
await deviceClient.CloseAsync();
输出: