events
チュートリアル - イベント ハンドラーを使用し、クライアント証明書に基づいて MQTT クライアントの認証と認可を行う
このチュートリアルでは、MQTT クライアントの認証と認可を行う .NET Web サーバーを作成する方法について説明します。
- アクティブなサブスクリプションが含まれる Azure アカウント。 Azure アカウントをお持ちでない場合は、無料でアカウントを作成することができます。
- Azure Web PubSub サービス (Standard レベル以上である必要があります)。
- PEM 形式のクライアント証明書。
- .NET ランタイムがインストールされている。
- Node.js
ここでは、クライアント証明書認証が有効でイベント ハンドラーが構成された Azure Web PubSub サービスをデプロイするための Bicep と Azure Resource Manager のテンプレートを示します。
connect
イベント ハンドラーを構成して、クライアントの認証と認可のための Webhook エンドポイントをサービスに通知します。 それを tunnel:///MqttConnect
に設定します。
tunnel://
は、awps-tunnel ツールを利用してローカル認証サーバーをパブリック ネットワークに公開する特別な構文です。
/MqttConnect
は、ローカル認証サーバーによって公開されるエンドポイントです。
クライアント証明書が connect
イベントでサーバーに送信されるように、プロパティ tls.clientCertEnabled
を使ってクライアント証明書認証を有効にします。
また、クライアントがアクセス トークンを送信する必要がなくなるように、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
このツールは、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}
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 クライアントのイベント ハンドラー プロトコルを調べることができます。
その他のリソース
トレーニング
認定資格
Microsoft Certified: Identity and Access Administrator Associate - Certifications
ID ソリューションの現代化、ハイブリッド ソリューションの実装、ID ガバナンスの実装を行う Microsoft Entra ID の機能を実証します。