Skip to content

HTTPサービスの利用 ​

TIP

EMQX v5.8.0以降、HTTP認証機能はレスポンスボディにACLルールを含めてクライアントの権限を事前設定できるようになりました。より高いパフォーマンスのために新しいフォーマットの使用を推奨します。詳細はHTTP認証をご参照ください。

EMQXはHTTPサービスに基づく認可をサポートしています。ユーザーは外部のHTTPアプリケーションをデータソースとして自ら構築する必要があります。EMQXはHTTPサービスにリクエストを送り、HTTP APIから返されたデータに基づいて認可結果を判定することで、複雑な認可ロジックを実現します。

ヒント

基本的なEMQX認可の概念についての知識

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

クライアントがサブスクライブやパブリッシュ操作を開始すると、HTTP認可機能は設定されたリクエストテンプレートに基づいてリクエストを構築し送信します。ユーザーは認可サービス内で認可ロジックを実装し、以下の要件に従って結果を返す必要があります。

リクエスト ​

リクエストはJSON形式を利用でき、URLやリクエストボディ内で以下のプレースホルダーが使用可能です:

  • ${clientid}:クライアントID
  • ${username}:クライアントがログイン時に使用したユーザー名
  • ${client_attrs.NAME}:クライアント属性。NAMEは実行時に事前設定された属性名に置き換えられます。クライアント属性の詳細はMQTTクライアント属性をご参照ください。
  • ${peerhost}:クライアントの送信元IPアドレス
  • ${proto_name}:クライアントが使用するプロトコル名(例:MQTT、CoAP)
  • ${mountpoint}:ゲートウェイリスナーのマウントポイント(トピックプレフィックス)
  • ${action}:要求されているアクション(例:publish、subscribe)
  • ${topic}:現在のリクエストでパブリッシュまたはサブスクライブされるトピック(またはトピックフィルター)
  • ${qos}:現在のリクエストでパブリッシュまたはサブスクライブされるメッセージのQoS(サービス品質)
  • ${retain}:現在のリクエストでパブリッシュされるメッセージがリテインドメッセージかどうか
  • ${zone}:実行時のクライアントのゾーン。ゾーンはクライアントの論理的分類(地域や環境など)で、クライアントの設定に基づき動的に適用されます。

レスポンス ​

認可サービスは以下の形式でレスポンスを返す必要があります:

  • レスポンスのcontent-typeはapplication/jsonでなければなりません。
  • HTTPステータスコードが200の場合、HTTPボディのresultフィールドの値により認可結果が決まります:
    • allow:パブリッシュまたはサブスクライブを許可
    • deny:パブリッシュまたはサブスクライブを拒否
    • ignore:このリクエストを無視し、次の認可機能に処理を委ねる
  • HTTPステータスコードが204の場合、このパブリッシュまたはサブスクライブリクエストは許可されたことを意味します。
  • 200および204以外のHTTPステータスコードは「無視」を意味します。例えば、HTTPサービスが利用不可の場合などです。

レスポンス例:

json
HTTP/1.1 200 OK
Headers: Content-Type: application/json
...
Body:
{
    "result": "allow" | "deny" | "ignore" // デフォルトは "ignore"
}

EMQX 4.xとの互換性について

4.xバージョンでは、EMQXはHTTP APIのステータスコードのみを利用し、コンテンツは破棄していました。例えば200はallow、403はdenyを意味していました。より詳細な情報提供のため、EMQX 5.0でリクエストコンテンツの返却を追加しました。

TIP

POSTメソッドの使用を推奨します。GETメソッドを使用すると、HTTPサーバーログにより一部の機密情報が露出する可能性があります。

信頼できない環境ではHTTPSの利用を推奨します。

動的ホスト名解決の設定 ​

デフォルトでは、HTTP認可機能は作成時にurl内のホスト名を解決し、永続的なコネクションプールを使用します。認可リクエストごとにホスト名を解決するには、hostname_resolutionをdynamicに設定してください。

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

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

動的ホスト名解決を設定する際の注意点:

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

ダッシュボードでの設定 ​

  1. EMQXダッシュボードの左ナビゲーションツリーでアクセス制御 -> 認可をクリックし、認可ページに入ります。

  2. 右上の作成をクリックし、バックエンドとしてHTTPサーバーを選択して、次へをクリックし設定画面に進みます。

    authz-http_ee
  3. 以下の手順に従い設定を行います。

    • メソッド:HTTPリクエストメソッドを選択します。選択肢はGET、POSTです。
    • URL:HTTPアプリケーションのURLを入力します。ホスト部分はホスト名解決がDynamicの場合、認可プレースホルダーを含めることができます。
    • ホスト名解決:認可機能作成時に固定ホスト名を解決するStaticか、リクエストごとにホスト名を解決するDynamicを選択します。デフォルトはStaticです。詳細は動的ホスト名解決の設定をご参照ください。
    • 許可ホスト:URLホストにプレースホルダーが含まれる場合、レンダリングされたホスト名がマッチを許可される正確なホスト名またはワイルドカードパターンを入力します。
    • 前提条件:省略可能なVariform式を入力します。式がtrueと評価された場合にのみこの認可機能が呼び出されます。詳細は認可機能の前提条件をご参照ください。
    • ヘッダー(省略可能):HTTPリクエストヘッダーを設定します。キーと値はプレースホルダーを使用可能です。
    • OAuth2クライアント認証:トグルをオンにすると、EMQXはアクセストークンを取得し、外部HTTP認可サービスへのリクエストに追加します。詳細はOAuth2クライアント認証の設定をご参照ください。
    • TLSを有効化:トグルをオンにすると、外部HTTP認可サービスへの接続にTLSを有効化します。この設定はOAuth2トークンエンドポイントのTLS設定とは独立しています。
    • ボディ:HTTPリクエストボディを設定します。キーと値はプレースホルダーを使用可能です。
    • 詳細設定:同時接続数、接続タイムアウト、最大HTTPリクエスト数、リクエストタイムアウトを設定します。
      • プールサイズ(省略可能):Staticモードでは永続的なコネクションプールのサイズを指定します。値は最低1以上でなければなりません。Dynamicモードではリクエスト間で再利用可能な接続数を指定し、0に設定すると接続再利用が無効になります。デフォルトは8です。
      • 接続タイムアウト(省略可能):接続タイムアウトの待機時間を単位付き(時間、分、秒、ミリ秒)で入力します。
      • HTTPパイプライニング(省略可能):正の整数で、レスポンスを待たずに送信可能な最大HTTPリクエスト数を指定します。デフォルトは100です。ホスト名解決がDynamicの場合、この設定は無効です。
      • リクエストタイムアウト(省略可能):リクエストタイムアウトの待機時間を単位付き(時間、分、秒、ミリ秒)で入力します。
  4. 作成をクリックして設定を完了します。

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_type、client_id、client_secret、および省略可能なscopeが含まれます。トークンエンドポイントは200レスポンスとともにaccess_tokenを含むJSONボディを返す必要があります。token_typeとexpires_inも返せます。存在する場合、token_typeはBearerでなければならず、expires_inは正の整数でなければなりません。

重要なお知らせ

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

設定項目による設定 ​

HTTP認可はtype=httpで設定します。

省略可能なprecondition設定項目はVariform式を受け付けます。式がtrueと評価された場合にのみこの認可機能が呼び出されます。preconditionを省略または空にした場合は前提条件は適用されません。詳細は認可機能の前提条件をご参照ください。

HTTPのPOSTおよびGETリクエストをサポートしています。それぞれ固有のオプションがあります。

POSTリクエストで設定したHTTP認可機能の例:

bash
{
    type = http

    method = post
    url = "http://127.0.0.1:32333/authz/${peercert}?clientid=${clientid}"
    body {
        username = "${username}"
        topic = "${topic}"
        action = "${action}"
    }
    headers {
        "Content-Type" = "application/json"
        "X-Request-Source" = "EMQX"
    }
}

GETリクエストで設定したHTTP認可機能の例:

bash
{
    type = http

    method = get
    url = "http://127.0.0.1:32333/authz"
    body {
        username = "${username}"
        topic = "${topic}"
        action = "${action}"
    }
    headers {
        "X-Request-Source" = "EMQX"
    }
}

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

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

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 = "authorization.check"
    timeout = 5s
    ssl {
        enable = true
    }
}

認可サーバーがスコープを要求しない場合はscopeを省略してください。リクエスト形式や制限事項の詳細はOAuth2クライアント認証の設定をご参照ください。