Skip to content

HTTP サービスの利用

EMQX は、パスワード認証に外部の HTTP サービスを利用することをサポートしています。有効化すると、クライアントが接続要求を開始した際に、EMQX は受け取った情報をもとに HTTP リクエストを構築し、クエリ結果に基づいて要求を受け入れるかどうかを判断し、複雑な認証ロジックを実現します。

前提条件

EMQX 認証の基本概念の知識が必要です。

HTTP リクエストとレスポンス

認証プロセスは HTTP API コールに似ており、EMQX はリクエストクライアントとして「API」が要求する形式で HTTP サービスへリクエストを構築・送信し、HTTP サービスは「クライアント」が要求する形式で結果を返します。

  • レスポンスのエンコード形式 content-typeapplication/json である必要があります。
  • 認証結果はボディの result で示し、値は allowdenyignore のいずれかです。
  • スーパーユーザーはボディの is_superuser で示し、値は true または false です。
  • EMQX v5.7.0 以降、オプションの client_attrs フィールドでクライアント属性を設定可能です。キーと値はどちらも文字列である必要があります。
  • EMQX v5.8.0 以降、レスポンスボディにオプションの acl フィールドを設定してクライアントの権限を指定できます。詳細はアクセスコントロールリスト(ACL)を参照してください。
  • EMQX v5.8.0 以降、レスポンスボディにオプションの expire_at フィールドを設定してクライアントの認証有効期限を指定できます。これによりクライアントは切断され、再接続時に再認証が強制されます。値は秒単位の Unix タイムスタンプです。
  • HTTP レスポンスのステータスコードは 200 または 204 であるべきです。4xx または 5xx のステータスコードが返された場合はボディを無視し、結果を ignore と判断して認証チェーンを継続します。

レスポンス例:

js
HTTP/1.1 200 OK
Headers: Content-Type: application/json
...
Body:
{
    "result": "allow", // "allow" | "deny" | "ignore"
    "is_superuser": false, // オプション値: true | false、デフォルトは false
    "client_attrs": { // オプション(v5.7.0以降)
        "role": "admin",
        "sn": "10c61f1a1f47"
    }
    "expire_at": 1654254601, // オプション(v5.8.0以降)
    "acl": // オプション(v5.8.0以降)
    [
        {
            "permission": "allow",
            "action": "subscribe",
            "topic": "eq t/1/#",
            "qos": [1]
        },
        {
            "permission": "deny",
            "action": "all",
            "topic": "t/3"
        }
    ]
}

EMQX 4.x 互換性について

EMQX 4.x では HTTP ステータスコードのみを利用し、ボディは破棄されます。例えば 200allow403deny を意味します。 表現力不足のため、HTTP ボディを利用する形に再設計されており、EMQX 5.0 とは互換性がありません。

動的ホスト名解決の設定

デフォルトでは、HTTP 認証機構は認証機構作成時に url のホスト名を解決し、永続的なコネクションプールを使用します。認証リクエストごとにホスト名を解決したい場合は、hostname_resolutiondynamic に設定します。

動的ホスト名解決では、url のホスト部分にプレースホルダーを使用できます。例えば、以下の設定はクライアントの tenant 属性に応じて認証リクエストを異なるエンドポイントにルーティングします。

hocon
{
    mechanism = password_based
    backend = http
    method = post
    url = "https://${client_attrs.tenant}.auth.example.com/authn"
    hostname_resolution = dynamic
    allowed_hosts = ["*.auth.example.com"]
    pool_size = 8
    headers {
        "Content-Type" = "application/json"
    }
    body {
        username = "${username}"
        password = "${password}"
    }
    ssl {
        enable = true
    }
}

動的ホスト名解決を設定する際は以下に注意してください:

  • hostname_resolutionstatic または dynamic を受け付け、デフォルトは static です。リテラルホスト名に対しても dynamic を指定すると、リクエストごとにそのホスト名を解決します。
  • URL ホストにプレースホルダーが含まれる場合、hostname_resolution は必ず dynamic であり、allowed_hosts に少なくとも1つのエントリが必要です。
  • allowed_hosts の各エントリは正確なホスト名(例:auth.example.com)またはワイルドカードパターン(例:*.auth.example.com)である必要があります。ワイルドカードは指定されたサフィックス以下のホスト名にマッチしますが、サフィックス自体にはマッチしません。URL がリテラルホスト名の場合、allowed_hosts は無効です。
  • URL の権限部(authority)内でプレースホルダーを含められるのはホストのみです。スキームは http または https でなければならず、ポートが指定されている場合はリテラルの整数でなければなりません。URL のユーザー情報やフラグメントはサポートされません。URL パスやクエリのプレースホルダーは引き続きサポートされます。
  • EMQX が有効なホスト名をレンダリングできないか、レンダリングされたホスト名が allowed_hosts にマッチしない場合、HTTP リクエストは送信されず認証は失敗します。
  • dynamic モードでは、レンダリングされたすべてのホストへのリクエストが同じコネクションプールを共有します。pool_size はプールが保持できるアイドル接続数の上限を指定し、0 に設定すると接続再利用を無効化します。enable_pipeliningmax_inactive はこのモードでは無効です。
  • dynamic モードの HTTPS リクエストでは、EMQX は設定された TLS オプションをレンダリングされたホストに適用します。SNI(Server Name Indication)が明示的に設定されていない場合、EMQX はレンダリングされたホスト名から自動的に派生します。
  • hostname_resolutiondynamic の場合、OAuth2 はサポートされません。

ダッシュボードでの設定

EMQX ダッシュボードを使って関連設定を完了できます。

  1. EMQX ダッシュボードの左側ナビゲーションメニューから アクセス制御 -> 認証 をクリックします。

  2. 認証 ページの右上にある 作成 をクリックします。

  3. メカニズムパスワードベースバックエンドHTTP サーバー を選択し、設定 ステップに進みます。

    HTTP
  4. 以下の指示に従って認証バックエンドを設定してください:

    • メソッド:HTTP リクエストメソッドを選択します。選択肢は getpost です。

      TIP

      POST メソッドの使用を推奨します。GET メソッドを使用すると、HTTP サーバーログに平文パスワードなどの機密情報が露出する可能性があります。また、信頼できない環境では HTTPS を使用してください。

    • URL:HTTP サービスの URL アドレスを入力します。ホスト部分には ホスト名解決Dynamic の場合、認証プレースホルダーを含めることができます。

    • ホスト名解決:認証機構作成時に固定ホスト名を解決する場合は Static、リクエストごとにホスト名を解決する場合は Dynamic を選択します。デフォルトは Static です。詳細は動的ホスト名解決の設定を参照してください。

    • 許可ホスト:URL ホストにプレースホルダーが含まれる場合、レンダリングされたホスト名がマッチ可能な正確なホスト名またはワイルドカードパターンを入力します。

    • 前提条件Variform 式で、HTTP サーバー認証機構をクライアント接続に適用するか制御します。式はクライアントの属性(usernameclientidlistener など)に対して評価され、文字列 "true" の場合のみ認証機構が呼び出されます。そうでなければスキップされます。詳細は認証機構の前提条件を参照してください。

    • ヘッダー(オプション):HTTP リクエストヘッダー。複数のヘッダーを追加可能です。キーと値はプレースホルダーを使用できます。

    • OAuth2 クライアント認証情報:トグルをオンにすると、EMQX がアクセストークンを取得し、外部 HTTP 認証サービスへ送信するリクエストに追加します。詳細はOAuth2 クライアント認証情報の設定を参照してください。

    • TLS を有効化:トグルをオンにすると、外部 HTTP 認証サービスへの接続に TLS を有効化します。この設定は OAuth2 トークンエンドポイントの TLS 設定とは独立しています。TLS 有効化の詳細はネットワークと TLSを参照してください。

    • ボディ:リクエストテンプレート。POST リクエストの場合は JSON ボディとして送信され、GET リクエストの場合は URL のクエリ文字列にエンコードされます。マッピングのキーと値はプレースホルダーを使用できます。

    • 詳細設定

      • プールサイズ(オプション):Static モードでは永続的コネクションプールのサイズを指定します。値は最低 1 である必要があります。Dynamic モードではリクエスト間で再利用可能な接続数を指定し、0 に設定すると接続再利用を無効化します。デフォルトは 8 です。

      • 接続タイムアウト(オプション):EMQX が接続タイムアウトと判断するまでの待機時間を指定します。単位はミリ秒、秒、分、時間が利用可能です。

      • HTTP パイプライニング(オプション):レスポンスを待たずに送信可能な最大 HTTP リクエスト数を正の整数で指定します。デフォルトは 100 です。ホスト名解決Dynamic の場合は適用されません。

      • リクエストタイムアウト(オプション):EMQX がリクエストタイムアウトと判断するまでの待機時間を指定します。単位はミリ秒、秒、分、時間が利用可能です。

  5. 設定が完了したら、作成 をクリックします。

OAuth2 クライアント認証情報の設定

EMQX 6.0.4 以降、HTTP 認証機構は OAuth 2.0 クライアントクレデンシャルズグラントをサポートします。OAuth2 を有効化すると、EMQX は設定されたトークンエンドポイントからアクセストークンを取得・キャッシュ・自動更新します。EMQX が外部 HTTP 認証サービスを呼び出す際、Authorization: Bearer <access_token> ヘッダーにトークンを付加し、外部サービスはこれを使って EMQX を認証します。

OAuth2 クライアント認証情報をオンにし、以下の設定を行います:

ダッシュボード設定項目説明
トークンエンドポイント必須。アクセストークンをリクエストする OAuth2 認可サーバーのエンドポイント。URL は HTTP または HTTPS を使用し、ユーザー情報を含んではいけません。
クライアント ID必須。アクセストークン取得に使用する OAuth2 クライアント ID。
クライアントシークレット必須。アクセストークン取得に使用する OAuth2 クライアントシークレット。
スコープオプション。アクセストークンに要求する OAuth2 スコープ。
トークンリクエストタイムアウトトークンエンドポイントへの HTTP リクエストのタイムアウト。デフォルトは 5 秒。
TLS を有効化トークンエンドポイントへの接続に TLS を有効化します。この設定は外部 HTTP 認証サービスの TLS 設定とは独立しています。

EMQX は application/x-www-form-urlencoded コンテンツタイプで POST リクエストをトークンエンドポイントに送信します。リクエストボディには grant_typeclient_idclient_secret、およびオプションの scope が含まれます。トークンエンドポイントは 200 レスポンスで JSON ボディに access_token を返す必要があります。token_typeexpires_in も返すことができます。存在する場合、token_typeBearerexpires_in は正の整数でなければなりません。例:

json
{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 3600
}

重要なお知らせ

  • OAuth2 を有効にしている場合、HTTP 認証機構の設定で Authorization ヘッダーを設定しないでください。EMQX は自動生成される Bearer 認証ヘッダーと競合するため設定を拒否します。
  • トークンエンドポイントはクライアント ID とクライアントシークレットをリクエストボディのフォームフィールドとして受け入れる必要があります。HTTP Basic 認証ヘッダーによるトークンエンドポイント認証はサポートされていません。

設定項目による設定

EMQX の設定項目で HTTP 認証機構を設定できます。

以下は HTTP の POST および GET リクエストの例です:

OAuth2 クライアント認証情報の設定

EMQX 6.0.4 以降、HTTP 認証機構の設定に oauth2 ブロックを追加して OAuth2 クライアント認証情報を有効化できます。methodurlbodyheaders と同じ階層に配置してください:

hocon
oauth2 {
    enable = true
    grant_type = client_credentials
    token_endpoint = "https://auth.example.com/oauth/token"
    client_id = "emqx-client"
    client_secret = "emqx-client-secret"
    scope = "device.read device.write"
    timeout = 5s
    ssl {
        enable = true
    }
}

認可サーバーがスコープを要求しない場合は scope を省略してください。リクエスト形式と制約についてはOAuth2 クライアント認証情報の設定を参照してください。