在本教學課程中,您將瞭解如何撰寫 .NET 網頁伺服器來驗證和授權 MQTT 用戶端。
必要條件
- 具有有效訂用帳戶的 Azure 帳戶。 如果您沒有 Azure 帳戶,可以免費建立帳戶。
- Azure Web PubSub 服務 (必須是標準層以上)。
- PEM 格式的客戶端憑證。
- 已安裝 .NET 執行階段。
- Node.js
部署 Azure Web PubSub 服務
以下是 Bicep/Azure Resource Manager 範本,可部署已啟用用戶端憑證驗證並設定事件處理程式的 Azure Web PubSub 服務。
我們會設定 connect
事件處理程式,告知服務 Webhook 端點進行驗證和授權。 我們將設定為 tunnel:///MqttConnect
。
tunnel://
是利用 awps 通道工具將本機驗證伺服器公開至公用網路的特殊語法。
/MqttConnect
是將由本機驗證伺服器公開的端點。
我們會透過 屬性 tls.clientCertEnabled
啟用用戶端憑證驗證,以便在事件中 connect
將客戶端憑證傳送至您的伺服器。
另外請注意,anonymousConnectPolicy
必須設定為 allow
,用戶端才不必再傳送存取權杖。
param name string
param hubName string = 'hub1'
param eventHandlerUrl string = 'tunnel:///MqttConnect'
param location string = resourceGroup().location
resource awps 'Microsoft.SignalRService/WebPubSub@2023-03-01-preview' = {
name: name
location: location
sku: {
name: 'Standard_S1'
tier: 'Standard'
size: 'S1'
capacity: 1
}
properties: {
tls: {
clientCertEnabled: true
}
}
}
resource hub 'Microsoft.SignalRService/WebPubSub/hubs@2023-03-01-preview' = {
parent: awps
name: '${hubName}'
properties: {
eventHandlers: [
{
urlTemplate: eventHandlerUrl
userEventPattern: '*'
systemEvents: [
'connect'
]
}
]
anonymousConnectPolicy: 'allow'
}
}
設定驗證伺服器
我們在這裡提供了驗證伺服器範例。 請下載專案。
讓我們看看項目結構:
- mqttAuthServer
- Models
- MqttConnectEventRequest.cs
- ...
- MqttAuthServer.csproj
- Program.cs
目錄 Models
包含所有模型檔案,以描述 MQTT connect
事件的要求和回應本文。
Program.cs
包含處理 MQTT connect
事件的邏輯,包括從要求剖析用戶端憑證內容、驗證憑證,以及授權用戶端。
下列代碼段是處理 connect
事件要求的主要邏輯:
var request = await httpContext.Request.ReadFromJsonAsync<MqttConnectEventRequest>();
var certificates = request.ClientCertificates.Select(cert => GetCertificateFromPemString(cert.Content));
// Simulate Logic to validate client certificate
if (!request.Query.TryGetValue("failure", out _))
{
// As a demo, we just accept all client certificates and grant the clients with permissions to publish and subscribe to all the topics when the query parameter "success" is present.
await httpContext.Response.WriteAsJsonAsync(new MqttConnectEventSuccessResponse()
{
Roles = ["webpubsub.joinLeaveGroup", "webpubsub.sendToGroup"]
});
}
else
{
// If you want to reject the connection, you can return a MqttConnectEventFailureResponse
var mqttCodeForUnauthorized = request.Mqtt.ProtocolVersion switch
{
4 => 5, // UnAuthorized Return Code in Mqtt 3.1.1
5 => 0x87, // UnAuthorized Reason Code in Mqtt 5.0
_ => throw new NotSupportedException($"{request.Mqtt.ProtocolVersion} is not supported.")
};
httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
await httpContext.Response.WriteAsJsonAsync(new MqttConnectEventFailureResponse(new MqttConnectEventFailureResponseProperties()
{
Code = mqttCodeForUnauthorized,
Reason = "Invalid Certificate"
}
));
}
若要執行專案,請在根目錄中執行下列命令。
dotnet run
將伺服器端點公開至公用網路
下載並安裝 awps-tunnel
此工具執行於 Node.js 16 版或更新版本上。
npm install -g @azure/web-pubsub-tunnel-tool
使用服務連接字串並執行
export WebPubSubConnectionString="<your connection string>"
awps-tunnel run --hub {hubName} --upstream http://localhost:{portExposedByYourAuthServer}
實作 MQTT 用戶端
我們將在 Node.js 中實作用戶端。
使用下列命令初始化Node.js專案。
npm init
安裝模組 mqtt
。
npm install mqtt
建立名為 index.js
的新檔案,並將下列程式代碼新增至 檔案。
const mqtt = require('mqtt');
var client = mqtt.connect(`wss://{serviceName}.webpubsub.azure.com/clients/mqtt/hubs/{hubName}`,
{
clientId: "client1",
cert: `-----BEGIN CERTIFICATE-----
{Complete the certificate here}
-----END CERTIFICATE-----`,
key: `-----BEGIN PRIVATE KEY-----
{Complete the private key here}
-----END PRIVATE KEY-----`,
protocolVersion: 5,
});
client.on("connect", (connack) => {
console.log("connack", connack);
});
client.on("error", (err) => {
console.log(err);
});
更新 :index.js
- 根據您所建立的資源更新
{serviceName}
和{hubName}
變數。 - 完成檔案中的客戶端憑證和金鑰。
然後,您可以使用 命令執行專案
node index.js
如果一切正常運作,您將能夠看到控制台中列印成功的 CONNACK 回應。
connack Packet {
cmd: 'connack',
retain: false,
qos: 0,
dup: false,
length: 2,
topic: null,
payload: null,
sessionPresent: false,
returnCode: 0
}
若要模擬憑證驗證失敗,請將失敗查詢附加至連線 URL,如下所示
var client = mqtt.connect(`wss://{serviceName}.webpubsub.azure.com/clients/mqtt/hubs/{hubName}?failure=xxx`,
然後重新執行用戶端,您將可以看到未經授權的 CONNACK 回應。
後續步驟
現在您已知道如何驗證和授權 MQTT 用戶端 e2e。 接下來,您可以檢查 MQTT 用戶端的事件處理程式通訊協定。