メインコンテンツへスキップ
MQTTは、他のシステムと通信するためのデバイスによく使用される軽量なプロトコルで、 publish/subscribe(パブリッシュ/サブスクライブ) 型のメッセージングプラットフォーム向けに設計されています。詳細については、WikipediaのMQTTをお読みください。 一般には3つのコンポーネントから成り立ちます。
  1. メッセージのpublisher(パブリッシャー)
  2. メッセージのsubscriber(サブスクライバー)
  3. メッセージを仲介するbroker(ブローカー)
メッセージが関連付けられているtopics(トピック)(チャネルまたはサブジェクトとも呼ばれる)の概念があります。トピックはパブリッシャーとサブスクライバー間のメッセージをルーティングします。 MQTTプロトコルは、usernamesおよびpasswordsに基づいて基本的な認証メカニズムをサポートします。これらの資格情報は、CONNECTメッセージとともに送信されます。 この記事では、nodejsベースのMQTTブローカー(moscaおよびAuth0)間の統合について説明します。この例では、Auth0を使ってpublishersおよびsubscribersのブローカーに対する 認証 を行い、メッセージのルーティングを 認可 します。
MQTTのデータフロー図

ソリューションのコンポーネント

ブローカー

mosca はホストにとっては簡単で、他のサーバーに埋め込むことができます。このサンプルの目的上、 mosca サーバーを自己ホストします。
これによって、ポート9999でMQTTメッセージをリッスンするサーバーが作成されます。 mosca では、操作の認証と認可に使用する3つの関数をオーバーライドすることができます。 このサンプルでは、非常に単純なモジュールauth0moscaを使ってこれらの関数を実行します。Auth0は mosca に結びついています。

Auth0Moscaモジュール

この小さなモジュールには、 mosca で使用される4つの関数(authenticateWithCredentialsauthenticateWithJWTauthorizePublishauthorizeSubscribe)があります。
authenticateWithCredentialsOAuth2リソース所有者のパスワード資格情報付与を使って、ブローカーおよびブローカーへのすべての接続を認証します。publisherまたはsubscriberCONNECT メッセージをブローカーに送信するたびに、authenticate関数が呼び出されます。この関数でAuth0エンドポイントを呼び出し、デバイスのusername/passwordを転送します。Auth0は、これをアカウントストア(コード内の最初のrequest.post)と比較して検証します。検証に成功した場合、(JWT)を検証および解析してデバイスのプロファイルを取得し、subscriberまたはpublisherを表すclientオブジェクトに追加します。これは、jwt.verify呼び出しで行われます。 慣例により、ブローカーに接続されたデバイスはすべて、Auth0にアカウントがあります。 デバイスプロファイルにもtopicsプロパティがあります。これは、この特定のデバイスが許可されたすべてのトピックを含む配列です。上のスクリーンショットでは、thermostat-1atemperatureおよびconfigトピックへのパブリッシュ(またはサブスクライブ)が許可されます。 authorizePublish関数とauthorizeSubscribe関数は、要求された特定のトピックがこのリストに載っているかどうかを確認するだけです。 authenticateWithJWTは、passwordフィールドでJWTを想定します。この場合の流れは若干異なります。
  1. パブリッシャーとサブスクライバーがトークンを取得する
  2. moscaに接続してJWTを送信する
  3. moscaがJWTを検証する
  4. メッセージが送信されサブスクライバーに再送信される
MQTTのJSON Web Tokenデータフロー図
パブリッシャーとサブスクライバーは何らかの方法でJWTを取得します。ブローカーはAuth0と通信する必要はなくなりました。JWTは自己完結型のアーティファクトであり、署名に使用するシークレットで検証することができます。

パブリッシャー

このサンプルの場合、パブリッシャーはmqttモジュールを使用する単純なnodejsプログラムであり、正しい資格情報を追加します。
もちろん、usernamepasswordは、Auth0に保存されているものに一致しなければなりません。

サブスクライバー

サブスクライバーはパブリッシャーに非常に似ています。

Summary(概要)

ご覧のように、Auth0はさまざまなシナリオで簡単に使用することができます。Auth0のユーザーストアを使ってデバイスを管理します。時間や場所、デバイスIDといった他の状況に基づいて、はるかに洗練された認証ルールを記述する​ことも当然可能です。これらはすべて、追加のプロファイル属性やルールを通じて非常に簡単に実装​することができます。柔軟なAuth0 Profileが、任意のアーティファクト(この例のtopicsなど)をサポートするためにどのように拡張できるかについても説明しています。 Rules(ルール)の詳細については、「Auth0 Rules」を確認してください。 資格情報(username/password)を安全でないネットワークを介して送信することは絶対に避けてください。メッセージ内容が公開されることを防ぐTransport Level Securityを提供する他の実装もあります。1つの例として、 mosca はTLSをサポートします。すべてのトラフィックが閉域網を通る場合を除き、運用環境への導入ではこれが優先されるでしょう。

謝辞

本記事の編集にご協力いただき、素晴らしい mosca を構築していただいたMatteo Collina氏に感謝の意を表します。