This article covers how you can set up Best MQTT to connect to an Azure IoT Hub using SharedAccesKeys. In this case the username field has to contain the host name and device id with the following format: {iotHub-hostname}/{device-id}/?api-version=2021-04-12, while the password is a Shared Access Signature (SAS) token. The link above contains the code too to help generate the SAS token.
First of all, if not already, create a new device with setting/leaving Authentication type as Symmetric key. When done, or want to connect to an already set up device, open its settings and copy one of its connection strings, they look something like this: HostName=iothub-hostname.azure-devices.net;DeviceId=device_name_with_sak;SharedAccessKey=cCWVddDpee7c+U5/qJWaX5N8VU0XYZFSIrsdBhU8Gs1=. The connection string contains everything that required to connect to the hub. The TLS addon isn't required, however, it adviced to use it for its added security.
Have to create an MQTT connection that connects with TCP to port 8883, uses TLS for security and must use the 3.1.1 version of the MQTT protocol. Translating to code:
When the transport is connected we have to send an MQTT connect packet too. In this packet we have to send the username and password and the device id as the Client ID:
usingSystem;usingSystem.Globalization;usingSystem.Net;usingSystem.Security.Cryptography;usingSystem.Text;usingBest.MQTT;usingBest.MQTT.Packets.Builders;usingUnityEngine;publicsealedclassAzureIoT_SharedAccessKey:MonoBehaviour{// Using a connection string that formatted like this:// HostName=iothub-hostname.azure-devices.net;DeviceId=device_name_with_sak;SharedAccessKey=cCWVddDpee7c+U5/qJWaX5N8VU0XYZFSIrsdBhU8Gs1=// from HostNamestringhost="iothub-hostname.azure-devices.net";// from DeviceId:stringdeviceId="device_name_with_sak";// from SharedAccessKeystringsharedAccessKey="cCWVddDpee7c+U5/qJWaX5N8VU0XYZFSIrsdBhU8Gs1=";voidStart(){varoptions=newConnectionOptionsBuilder().WithTCP(host,8883).WithTLS().WithProtocolVersion(SupportedProtocolVersions.MQTT_3_1_1).Build();varclient=newMQTTClient(options);client.OnStateChanged+=(c,oldState,newState)=>Debug.Log($"[{c.Options.Host}]: {oldState} => {newState}");client.OnConnected+=OnClientConnected;client.BeginConnect(OnConnectPacketBuilder);}privateConnectPacketBuilderOnConnectPacketBuilder(MQTTClientclient,ConnectPacketBuilderbuilder){returnbuilder.WithClientID(deviceId).WithUserName($"{client.Options.Host}/{deviceId}/?api-version=2021-04-12").WithPassword(GenerateSasToken(client.Options.Host,sharedAccessKey,null,3600));}privatevoidOnClientConnected(MQTTClientclient){client.CreateSubscriptionBuilder($"devices/{deviceId}/messages/devicebound/#").WithMessageCallback(OnDeviceMessage).BeginSubscribe();}privatevoidOnDeviceMessage(MQTTClientclient,SubscriptionTopictopic,stringtopicName,ApplicationMessagemessage){Debug.Log($"{topic}({topicName}): {System.Text.Encoding.UTF8.GetString(message.Payload.Data, message.Payload.Offset, message.Payload.Count)}");}/// <summary>/// From "SAS Token Structure" topic: https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-dev-guide-sas?tabs=csharp#sas-token-structure/// </summary>publicstaticstringGenerateSasToken(stringresourceUri,stringkey,stringpolicyName,intexpiryInSeconds=3600){TimeSpanfromEpochStart=DateTime.UtcNow-newDateTime(1970,1,1);stringexpiry=Convert.ToString((int)fromEpochStart.TotalSeconds+expiryInSeconds);stringstringToSign=WebUtility.UrlEncode(resourceUri)+"\n"+expiry;HMACSHA256hmac=newHMACSHA256(Convert.FromBase64String(key));stringsignature=Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));stringtoken=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;}returntoken;}}