クラウドネイティブゲートウェイでは、すべてのバックエンドサービスで統一された認証を行うためのカスタム認証サービスを設定できます。これにより、各バックエンドサービスを個別に認証サービスに接続する必要がなくなります。このトピックでは、クラウドネイティブゲートウェイにカスタム認証サービスを設定する方法について説明します。
背景情報
ほとんどの場合、サーバーはクライアントリクエストからのトークンを使用して、外部に公開された API 操作の通信を保護します。トークンのフォーマットは、ビジネスシナリオによって決まります。
JSON Web トークン (JWT) を使用する場合、サーバーは統一された認証サービスにアクセスすることなく、いつでも公開鍵を使用してトークンの署名検証を実行できます。
カスタムトークンを使用する場合、サーバーはリクエストを受信した後に認証を実行するために、統一された認証サービスにアクセスする必要があります。このプロセスは、API 通信のセキュリティを保護するのに役立ちます。クラウドネイティブゲートウェイは、このタイプのカスタム認証をサポートしています。
次の図は、クラウドネイティブゲートウェイと統合された認証サービスがリクエストを処理する方法を示しています。

クライアントは、ログイン操作などの認証リクエストをゲートウェイに送信します。
ゲートウェイはリクエストを認証サービスに転送します。
認証サービスは、リクエストからユーザー名やパスワードなどの認証情報を読み取って認証します。認証が成功すると、認証サービスはトークンをゲートウェイに返します。その後、ゲートウェイはトークンを含む応答をクライアントに送信します。
クライアントは、`/order` パスへのリクエストなどのビジネスリクエストを送信します。リクエストには、前のステップで身分認証が成功した後に発行されたトークンが含まれています。
ゲートウェイは認証リクエストを構築し、カスタム認証サービスに送信します。この認証リクエストには、元のビジネスリクエストのパス (クエリパラメーターを含む)、HTTP メソッド (GET や POST など)、およびトークンが含まれています。MSE コンソールでトークンを格納する HTTP ヘッダーを設定する必要があります。必要に応じて、元のリクエストの本文を認証リクエストに含めるように設定することもできます。
認証リクエストのパスは、カスタム認証サービスの認証 API パスとビジネスリクエストのパスの組み合わせです。たとえば、認証 API パスが `/validateToken` で、ビジネスリクエストパスが `/order` の場合、最終的な認証リクエストパスは `/validateToken/order` になります。
認証サービスが認証リクエストを受信した後、トークンの有効性を確認し、元のリクエストパスに基づいてビジネスリクエストを承認できます。
認証サービスが応答の HTTP ステータスコードを変更できる場合、そのステータスコードに基づいて認証結果を判断できます。
認証サービスが HTTP ステータスコード 200 を返した場合、トークンは有効であり、要求されたバックエンドリソースへのアクセスが承認されていると見なされます。ゲートウェイは元のビジネスリクエストを保護されたバックエンドサービスに転送します。バックエンドサービスはゲートウェイに応答を返し、ゲートウェイはその応答をクライアントに転送して、注文が完了します。
認証サービスが HTTP ステータスコード 401 または 403 を返した場合、トークンは無効であるか、要求されたバックエンドリソースへのアクセスが承認されていないと見なされます。ゲートウェイは認証応答を直接クライアントに転送し、注文は失敗します。
ビジネス上の制約により、認証サービスが HTTP 200 ステータスコードのみを返す必要がある場合は、組み込みの
x-mse-external-authz-check-resultHTTP ヘッダーを使用できます。認証サービスの応答における
x-mse-external-authz-check-resultヘッダーの値がtrueの場合、トークンは有効で承認済みと見なされます。ゲートウェイは元のビジネスリクエストを保護されたバックエンドサービスに転送します。バックエンドサービスはゲートウェイに応答を返し、ゲートウェイはその応答をクライアントに転送して、注文が完了します。認証サービスの応答における
x-mse-external-authz-check-resultヘッダーの値がfalseの場合、トークンは無効または未承認と見なされます。ゲートウェイは認証応答を直接クライアントに転送し、注文は失敗します。
カスタム認証サービスの作成
MSE コンソールにログインします。
左側のナビゲーションウィンドウで、Cloud-Native Gateway > ゲートウェイリスト を選択します。上部のナビゲーションバーで、リージョンを選択します。
ゲートウェイリスト ページで、ゲートウェイの ID をクリックします。
左側のナビゲーションウィンドウで、Security Management > Global Authentication を選択します。
[グローバル認証] ページで、[認証の作成] をクリックします。開いた [認証の作成] パネルで、パラメーターを設定し、[OK] をクリックします。
設定項目
説明
認証名
カスタム認証サービスの名前。
認証タイプ
[カスタム認証サービス] を選択します。
認証サービス
トークンと権限を検証するために使用されるバックエンドサービス。このサービスはサービス管理で追加できます。詳細については、「サービスを追加する」をご参照ください。
説明HTTP プロトコルを使用するサービスのみがサポートされます。Dubbo などの他のプロトコルを使用するサービスはサポートされていません。
Kubernetes Service に複数のポートがある場合、デフォルトで最初のポートが使用されます。別のポートを使用するには、目的のポートのみを使用する追加の Kubernetes Service を Container Service for Kubernetes (ACK) で作成する必要があります。
認証 API
認証サービスによって提供される認証 API のパス。パスはプレフィックスマッチをサポートしています。
たとえば、認証サービスが Spring MVC 上に構築されており、認証 API パスが `/check` の場合、`/check/**` パスを含むリクエストを処理するには、次の設定を使用する必要があります。
@RequestMapping("/check/**") public ResponseEntity<RestResult<String>> check(){}トークンの場所
Authorization や Cookie など、トークンを含むリクエストヘッダーを指定します。[ドロップダウンリスト] または [手動入力] を選択して、トークンの場所を指定できます。
認証リクエストに含めるヘッダー
認証リクエストにクライアントリクエストからの追加ヘッダーを含める場合は、このフィールドで指定する必要があります。
説明デフォルトでは、Host、Method、Path、および Content-Length ヘッダーが追加されます。手動で追加する必要はありません。
認証応答から保持するヘッダー
認証応答からのヘッダーをクライアントリクエストに追加するには、このフィールドで指定する必要があります。
説明クライアントリクエストにすでにヘッダーが含まれている場合、その値は上書きされます。
認証リクエストに本文を含めることを許可する
[認証リクエストに本文を含めることを許可する] を選択すると、認証リクエストには元のリクエストの本文が含まれます。
[最大本文バイト数] は、認証リクエスト本文の最大サイズ (バイト単位) を指定します。
タイムアウト
認証サービスが結果を返すのを待つ最大時間 (秒単位)。デフォルトのタイムアウト期間は 10 秒です。
モード
ルーズモードとストリクトモードがサポートされています。ルーズモードを使用することをお勧めします。
ルーズモード: 認証サービスが利用できない場合 (たとえば、接続が失敗したり、5xx エラーが返されたりした場合)、ゲートウェイはクライアントからのリクエストを受け入れます。
ストリクトモード: 認証サービスが利用できない場合 (たとえば、接続が失敗したり、5xx エラーが返されたりした場合)、ゲートウェイはクライアントからのリクエストを拒否します。
単純な条件付き権限付与
[権限付与] の右側にある [単純な条件] をクリックします。単純な条件付き権限付与は、[ホワイトリストモード] と [ブラックリストモード] の 2 つのモードをサポートしています。
ホワイトリストモード: ホワイトリストで指定したホストとパスを持つリクエストは認証を必要としません。他のすべてのリクエストは認証を必要とします。
ブラックリストモード: ブラックリストで指定したホストとパスを持つリクエストのみが認証を必要とします。他のすべてのリクエストは認証を必要としません。
[+ ルール条件] をクリックして、ドメイン名、パス、およびリクエストヘッダーを設定します。
ドメイン名: アクセスするドメイン名 (ホスト)。
パス: アクセスする API 操作パス。
パスマッチ条件: パスは、完全に一致、プレフィックスマッチ、および正規表現マッチをサポートしています。
完全に一致: `/app/v1/order` などの完全なパスを入力します。
プレフィックスマッチ: アスタリスク (*) で終わるパスプレフィックスを入力します。たとえば、`/app` で始まるすべてのリクエストに一致させるには、値を `/app/*` に設定します。
正規表現マッチ: 正規表現の構文は、Google RE2 仕様に従う必要があります。詳細については、「RE2 構文」をご参照ください。
大文字と小文字を区別: このチェックボックスを選択すると、パスの値で大文字と小文字が区別されます。
リクエストヘッダー: リクエストヘッダー。[+ リクエストヘッダー] をクリックして、複数のヘッダーを設定します。ヘッダーは AND ロジックを使用して評価されます。
ヘッダーキー: ヘッダーフィールドの名前。
条件: ヘッダーでサポートされているマッチ条件。
等しい: リクエストヘッダーコレクション内の指定されたキーの値が、入力された値と等しい。
等しくない: リクエストヘッダーコレクション内の指定されたキーの値が、入力された値と等しくない。
存在する: 入力されたキーがリクエストヘッダーコレクションに存在する。
存在しない: 入力されたキーがリクエストヘッダーコレクションに存在しない。
含む: リクエストヘッダーコレクション内の指定されたキーの値に、入力された値が含まれる。
含まない: リクエストヘッダーコレクション内の指定されたキーの値に、入力された値が含まれない。
プレフィックス: リクエストヘッダーコレクション内の指定されたキーの値が、入力された値で始まる。
サフィックス: リクエストヘッダーコレクション内の指定されたキーの値が、入力された値で終わる。
正規表現: リクエストヘッダーコレクション内の指定されたキーの値が、入力された正規表現に一致する。正規表現の構文は、Google RE2 仕様に従う必要があります。詳細については、「RE2 構文」をご参照ください。
値: ヘッダーフィールドの値。
複雑な条件付き権限付与
[権限付与] の右側にある [複雑な条件] をクリックします。
複雑な条件付き権限付与では、Envoy の権限データ構造を YAML フォーマットで設定できます。これにより、AND、OR、NOT の条件ロジックを組み合わせて権限付与ルールを設定できます。設定された条件を満たすリクエストに対してのみ認証が実行されます。条件を満たさないリクエストは、認証なしで要求されたバックエンドリソースにアクセスできます。
説明権限データ構造のフィールドの詳細については、「Envoy の公式ドキュメント」をご参照ください。
設定例については、「複雑なルールベースの権限付与の例」をご参照ください。
[グローバル認証] ページに戻り、認証情報を表示します。ゲートウェイの認証情報が表示されている場合、カスタムゲートウェイ認証ルールは正常に作成されています。
カスタム認証サービスの表示と管理
MSE コンソールにログインします。
左側のナビゲーションウィンドウで、Cloud-Native Gateway > ゲートウェイリスト を選択します。上部のナビゲーションバーで、リージョンを選択します。
ゲートウェイリスト ページで、ゲートウェイの ID をクリックします。
左側のナビゲーションウィンドウで、Security Management > Global Authentication を選択します。
[グローバル認証] ページで、対象の認証ルールを見つけ、[アクション] 列の [詳細] をクリックします。サービスの [基本情報] と [認証設定] を表示できます。また、[権限付与情報] を表示および管理することもできます。

権限付与ルールを追加するには、[権限付与情報] エリアに移動し、[権限付与情報の作成] をクリックします。ダイアログボックスで、[リクエストドメイン名] と [リクエストパス] を入力し、[マッチモード] を選択して、[OK] をクリックします。
次のステップ
クラウドネイティブゲートウェイの認証ルールに対して、次の操作を実行できます。
認証ルールを有効にする: Global Authentication ページで、管理する認証ルールを見つけ、Actions 列の [有効化] をクリックします。
認証ルールを無効にする: Global Authentication ページで、管理する認証ルールを見つけ、Actions 列の [無効化] をクリックします。
認証ルールを変更する: Global Authentication ページで、管理する認証ルールを見つけ、Actions 列の [編集] をクリックします。
認証ルールを削除する: Global Authentication ページで、管理する認証ルールを見つけ、Actions 列の [削除] をクリックします。
認証ルールは、無効になっている場合にのみ削除できます。
複雑なルールベースの権限付与の例
正規表現を使用したドメイン名の一致
この例では、`exampleA.com` および `exampleB.com` ドメイン名のパスプレフィックスルールに一致するリクエストに対してのみ認証が実行されます。`regex` フィールドで指定された正規表現は、部分一致ではなく、完全一致に使用されます。
`test.exampleA.com` ドメイン名へのリクエストは認証ルールを満たさないため、認証なしでアクセスが許可されます。
正規表現は Google RE2 構文に準拠しています。詳細については、「RE2 構文」をご参照ください。
権限データ構造のフィールドの詳細については、「Envoy の公式ドキュメント」をご参照ください。
permissions:
# and_rules は、以下のすべてのルールが同時に満たされた場合に認証が実行されることを示します。
- and_rules:
rules:
- url_path:
# パスプレフィックス。
path:
prefix: /
- header:
# 正規表現。
safe_regex_match:
regex: "(exampleA\\.com|exampleB\\.com)"
# HTTP Pseudo-Header 仕様がサポートされています。「:authority」ヘッダーを使用してドメイン名を取得できます。
name: ":authority"AND、OR、および NOT 条件の組み合わせの使用
この例では、次の条件をカバーしています。
`exampleA.com/api` プレフィックスを持つパスのリクエストは、以下の例外を除き、認証が必要です。
`exampleA.com/api/appa/bbb` は認証を必要としません。
`exampleA.com/api/appb/ccc` は認証を必要としません。
`exampleB.com` 配下のすべてのリクエストは、以下の例外を除き、認証が必要です。
`exampleB.com/api/appa/bbb` は認証を必要としません。
`exampleB.com/api/appb/ccc` は認証を必要としません。
`exampleB.com/api/appc` プレフィックスを持つパスのリクエストは、以下の例外を除き、認証を必要としません。
`exampleB.com/api/appc/bbb/ccc` は認証が必要です。
`exampleB.com/api/appc/ccc/ddd` は認証が必要です。
ロジックは次の図のように構成されています。

次のコードは、YAML フォーマットでの設定を示しています。
permissions:
# or_rules は、以下のいずれかのルールが満たされた場合に認証が実行されることを示します。
- or_rules:
rules:
# and_rules は、以下のすべてのルールが満たされた場合にのみ、このルールが満たされることを示します。
# ルール 1
- and_rules:
rules:
- url_path:
path:
exact: /api/appc/bbb/ccc
- header:
exact_match: "exampleB.com"
name: ":authority"
# ルール 2
- and_rules:
rules:
- url_path:
path:
exact: /api/appc/ccc/ddd
- header:
exact_match: "exampleB.com"
name: ":authority"
- and_rules:
rules:
# ルール 3
- url_path:
path:
prefix: /api/
# not_rule は、以下の設定が満たされない場合にのみ、このルールが満たされることを示します。
# ルール 4
- not_rule:
url_path:
path:
exact: /api/appa/bbb
# ルール 5
- not_rule:
url_path:
path:
exact: /api/appb/ccc
- header:
exact_match: "exampleA.com"
name: ":authority"
- and_rules:
rules:
# ルール 6
- url_path:
path:
prefix: /
# not_rule は、以下の設定が満たされない場合にのみ、このルールが満たされることを示します。
# ルール 7
- not_rule:
url_path:
path:
exact: /api/appa/bbb
# ルール 8
- not_rule:
url_path:
path:
exact: /api/appb/ccc
# ルール 9
- not_rule:
url_path:
path:
prefix: /api/appc/
- header:
exact_match: "exampleB.com"
name: ":authority"