Skip to content

JWT認証

JWT認証は、クライアントの認証情報やセッション情報をサーバー側で保持しないトークンベースの認可機構です。鍵を所有していれば認証情報を一括発行できるため、最もシンプルな認証方法となります。

注意

JWT認証はEMQX Serverlessのデプロイメントではサポートされていません。

JWT認証の仕組み

クライアントは接続開始時に、JWTをユーザー名またはパスワードフィールド(モジュール設定に依存)に保持します。EMQXプラットフォームは設定された鍵または証明書を用いてJWTを復号します。復号が成功すれば認証成功とみなされ、失敗すれば認証失敗となります。

署名検証が成功すると、JWT認証器はクレームの検証に進みます。JWT認証器はiat(発行時刻)、nbf(有効開始時刻)、exp(有効期限)などのクレームに基づきJWTの有効性を積極的にチェックします。さらにカスタムクレームの検証も指定可能です。署名とクレームの両方の検証が成功した場合にのみ、クライアントにアクセスが許可されます。

デフォルト設定では、JWT認証を有効にすると任意のユーザー名と以下のパスワードで接続可能です。パスワードはデフォルトの鍵フィールドemqxsecretに対して検証されます。

bash
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJFTVFYIENsb3VkIiwiaWF0IjoxNTE2MjM5MDIyfQ.-k9Ggc6L_Jxq4uUf9xwdJpwRrS3PquL-JZKtAJoOvBo

上記のJWTトークンはテスト用です。ビジネス要件に合わせたJWTトークンは適切なツールで生成してください。詳細はJWTの生成方法をご参照ください。

JWTの生成方法

本節では、EMQXでクライアント認証に使用する有効なJWTを生成する手順を説明します。

前提条件

  • 秘密鍵(HMACアルゴリズムの場合)または秘密鍵ペア(RSA/ECDSAの場合)
  • JWT生成ツールまたはライブラリ(例:jwt.iojjwtmkjwk、Python、Node.js)
  • EMQXが期待するアルゴリズム(HS256RS256など)を把握していること

JWTの構造

JWTは以下の3つの部分で構成されます。

JWT = base64UrlEncode(Header) + "." + base64UrlEncode(Payload) + "." + Signature
  • Headerはトークンのメタデータ(アルゴリズムやトークンタイプなど)を指定します。例:

    json
    {
      "alg": "HS256",
      "typ": "JWT"
    }
  • Payloadusernameexpclient_attrsなどのクレーム(ユーザー情報)を含みます。例:

    json
    {
      "username": "emqx_user",
      "exp": 1719830400,
      "client_attrs": {
        "role": "admin",
        "sn": "device-001"
      }
    }
  • Signatureはトークンの改ざんを防止するため、HeaderとPayloadを秘密鍵や秘密鍵ペアで署名して生成されます。

手順

  1. JWTのHeaderを定義します。例(HMAC SHA-256の場合):

    json
    {
      "alg": "HS256",
      "typ": "JWT"
    }

    RSA/ECDSAの場合は、鍵の種類に応じて"alg"RS256ES256などに置き換えます。

  2. JWTのPayloadを定義します。PayloadにはEMQXで利用するクレームを含めます。主なフィールド例:

    json
    {
      "sub": "mqtt_client",       // サブジェクト:任意、識別用
      "username": "emqx_user",    // 任意:EMQX設定でバインドされている場合に使用
      "clientid": "client_123",   // 任意:クライアント制限用
      "exp": 1719830400           // 必須:有効期限(Unixタイムスタンプ)
    }

    重要事項

    • expは必須です。設定しないとEMQXでトークンが拒否される可能性があります。
    • usernameclientidは、EMQXがトークン内で検証する設定の場合に追加します。
    • aclclient_attrsなどのカスタムクレームも含められます。
  3. HeaderとPayloadをBase64Urlエンコードします。手動でもJWTライブラリを使っても構いません。

  4. JWTに署名します。秘密鍵や秘密鍵ペアを使って署名を生成します。

    • HMAC(例:HS256)の場合:HMACSHA256(base64Url(header) + "." + base64Url(payload), secret)
    • RSA/ECDSA(例:RS256)の場合:適切な署名アルゴリズムで秘密鍵を使用します。
  5. JWTを組み立てます。エンコード済みHeader、Payload、Signatureをピリオドで連結します。

    <header>.<payload>.<signature>
  6. JWTの検証(任意ですが推奨)を行います。jwt.ioなどのツールでデコード・検証してください。

Python(pyjwt)の例

import jwt
import datetime

secret = "your_shared_secret"

payload = {
    "username": "emqx_user",
    "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}

token = jwt.encode(payload, secret, algorithm="HS256")
print(token)

RS256の場合はsecretを秘密鍵に置き換え、アルゴリズムをRS256に指定してください。

結果

これでEMQXのMQTT CONNECTパケットのユーザー名またはパスワードフィールドに使用可能な署名済みJWTトークンが生成されました。

複雑なビジネス用途向けのJWT生成手順は、ブログ記事JWT Authentication and JWKS Endpoint in MQTT: Principle and a Hands-on Guideをご参照ください。

アクセスコントロールリスト(任意)

アクセスコントロールリスト(ACL)は、認証結果の拡張機能で、ログイン後のクライアントの権限を制御します。JWTにaclフィールドを含めてクライアントの権限を指定可能です。

詳細はアクセスコントロールリスト(ACL)をご覧ください。

クライアント属性

EMQX v5.7.0以降、JWT Payloadの任意フィールドclient_attrsを使ってクライアント属性を設定できます。キーと値はどちらも文字列型である必要があります。

例:

json
{
  "exp": 1654254601,
  "username": "emqx_u",
  "client_attrs": {
      "role": "admin",
      "sn": "10c61f1a1f47"
  }
}

JWT認証の設定

デプロイメント画面で、アクセス制御 - 拡張認証をクリックし、JWT認証設定をクリックして新しい認証を作成します。

以下のように関連設定を完了できます。

認証方式JWTを選択した場合:

  • JWT From:クライアント接続リクエスト内のJWTの位置を指定します。選択肢はpasswordまたはusername(それぞれMQTTクライアントのCONNECTパケットのPasswordUsernameフィールドに対応)
  • Algorithm:JWTの暗号化方式を指定します。選択肢はhmac-basedpublic-keyです。
    • hmac-basedを選択した場合(JWTが対称鍵で署名・検証される、HS256、HS384、HS512をサポート)、以下も設定します。
      • Secret:署名検証に使う鍵。署名生成時と同じ鍵を指定します。
      • Secret Base64 Encode:EMQXが署名検証前にSecretをBase64デコードするかどうか。選択肢はTrue、False(デフォルトはFalse)。
    • public-keyを選択した場合(JWTが秘密鍵で署名され、公開鍵で検証される。RS256、RS384、RS512、ES256、ES384、ES512をサポート)、以下も設定します。
      • Public Key:署名検証に使うPEM形式の公開鍵を指定します。
  • Disconnect After Expiration:JWTの有効期限切れ後にクライアントを切断するかどうか。デフォルトで有効。
  • Payload:カスタムクレームの検証を追加します。ユーザーはクレームのキーと期待値をそれぞれ指定可能で、${clientid}${username}のプレースホルダーが使えます。キーはJWT内のクレームを特定し、値は実際のクレーム値と比較されます。

JWTSを認証方式に選択した場合:

上記に加え、以下も設定します。

  • JWKS Endpoint:EMQXがJWKSを問い合わせるサーバーのエンドポイントアドレスを指定します。GETリクエストをサポートし、標準に準拠したJWKSを返す必要があります。
  • JWKS Refresh Interval:JWKSの更新間隔(EMQXがJWKSを問い合わせる頻度)を秒単位で指定します。デフォルトは300秒。設定後、作成をクリックして設定を完了します。
  • Headers:JWKSサーバーへのリクエストに含める追加のHTTPヘッダーを指定します。サーバーの要件に合わせてリクエストを適切にフォーマットするために使用します。キーと値のペアを追加可能です。例:
    • Key: Accept
    • Value: application/json

TIP

  • 専用版のデプロイメントの場合は、VPCピアリング接続を作成し、サーバーアドレスに内部ネットワークアドレスを使用してください。
  • BYOC版のデプロイメントの場合は、パブリッククラウドコンソールでVPCピアリング接続を作成する必要があります。詳細はBYOCデプロイメント作成 - VPCピアリング接続設定をご参照ください。サーバーアドレスには内部ネットワークアドレスを使用してください。
  • 「Init resource failure!」というメッセージが表示された場合は、サーバーアドレスの正確性とセキュリティグループの開放状況を確認してください。