6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NRI OpenStandia (IAM編)Advent Calendar 2024

Day 9

Kong Gateway の OpenID Connect プラグインを使ってみる

Last updated at Posted at 2024-12-09

はじめに

この記事では、OpenID Connect プラグインを使い Kong Gateway で OpenID Connect による認証・認可を実現するための設定例について、認可コードフロー(Authorization code flow)の使用方法のドキュメントに沿って説明します。

OpenID Connect プラグインは Kong Gateway Enterprise / Konnect で利用可能です。
Kong Gateway OSS では利用できません。

OpenID Connect とは

OpenID Connect (以後 OIDC) とはざっくり、 OAuth 2.0 での認可のフローでは十分ではなかった認証について補った仕様です。

OpenID Connect の詳細については手に余りますので Qiita 内で "OpenID Connect" または "OIDC" で検索するか、仕様書がありますのでそちらにあたってみてください。

  • 日本語訳仕様書

  • 仕様書
    以下のサイトの "OpenID Connect specifications" をクリックすると各仕様へのリンクが表示されます。

この記事でやってみること

後続の図は OpenID Connect プラグイン(以後OIDCプラグイン)を使った認可コードフローのシーケンス図です。
(https://docs.konghq.com/hub/kong-inc/openid-connect/how-to/authentication/authorization-code-flow/#authorization-code-flow より引用。リンク先ではもっときれいに表示されます)
この記事では KeyCloak を OIDC の IdP に、OpenID Connect を有効化した Kong Konnect + httpbin を RP として認可コードフローの動作を確認します。

OpenID では、認可・認証ホストを IdP (ID Provider)、サービスを提供するホストを RP (Relying Party) と呼びます。

docs.konghq.com_hub_kong-inc_openid-connect_how-to_authentication_authorization-code-flow_.png

❶ クライアントが Kong Gateway に設定したルートを通じてアップストリームの httpbin にアクセスしようとすると、
❷❸ Kong Gateway の OIDCプラグインが Keycloak の URL にリダイレクトさせます。
❹ Keycloak がログイン画面を出すので、
❺ クライアントからクレデンシャルを提示します。
❻❼ 認証できたら、Keycloak は認可コードをつけて Kong Gateway にリダイレクトさせます。
❽ Kong Gateway の OIDC プラグインは認可コードを検証し、OKだったら、
❾ Keycloak に対してIDトークン・アクセストークン・リフレッシュトークンを要求します。
❿ Keycloak は Kong Gateway が提示した認可コードを検証し、OKだったら、
⓫ IDトークン・アクセストークン・リフレッシュトークンを返却します。
⓬ Kong Gateway の OIDC プラグインは、受け取ったトークンを検証します。トークンの署名・有効期限を確認して、OKだったら、(セッション変数にKeycloakから受け取ったトークンを保存した後、)
⓭⓮ セッションID (SID) の入ったクッキーをクライアントに食わせてから、認証済みリクエストとして❶のアクセス先にリダイレクトさせます。
⓯⓰ Kong Gateway の OIDC プラグインは SID を検証し、OKだったら SID に紐づくIDトークンとアクセストークンをセッション変数から取り出しアップストリームの httpbin への要求電文に追加して呼び出します。
⓱ アップストリームの httpbin は受け取った情報を応答電文に設定して Kong Gateway に返します。
⓲ Kong Gateway は httpbin から受け取った応答電文をクライアントに返します。

httpbin は単に呼び出し内容を返すだけですが、実際のアップストリームのWebサービスでは IdP から受け取った ID トークンによりアカウントを特定し、該当アカウント向けのサービスを実行します(⓰⓱)。

実行環境の構築

Docker Compose を使って実行環境を構築します。

compose.yaml
---
services:
  kong:
    image: "kong/kong-gateway:${KONG_VERSION:-3.8.0.0}"
    environment:
      KONG_ROLE: "data_plane"
      KONG_DATABASE: "off"
      KONG_PROXY_LISTEN: "${KONG_PROXY_LISTEN:-0.0.0.0:48000}"
      KONG_VITALS: "off"
      KONG_CLUSTER_MTLS: "pki"
      KONG_CLUSTER_CONTROL_PLANE: "${CONTROL_PLANE}"
      KONG_CLUSTER_SERVER_NAME: "${SERVER_NAME}"
      KONG_CLUSTER_CERT: "${CERT}"
      KONG_CLUSTER_CERT_KEY: "${CERT_KEY}"
      KONG_LUA_SSL_TRUSTED_CERTIFICATE: "system"
      KONG_KONNECT_MODE: "on"
    ports:
      - "48000:48000"

  keycloak:
    image: "keycloak/keycloak:23.0"
    ports:
      - 48080:8080
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    command:
      - start-dev

  httpbin:
    image: kennethreitz/httpbin
    ports:
      - '40080:80'

実行ホストの都合によりポート番号はデフォルト+40000に変更しています。
バッティングがなければデフォルトのポート番号でOKです。

起動

起動
$ cd oidc-test
$ ls -la
-rw-r--r--. 1 ec2-user ec2-user     1021 Dec  4 09:27 compose.yaml
-rw-r--r--. 1 ec2-user ec2-user     1132 Nov 29 10:55 .env
$ docker compose up -d
[+] Running 3/3
 ✔ Container oidc-test-httpbin-1   Started                        0.5s 
 ✔ Container oidc-test-kong-1      Started                        0.5s 
 ✔ Container oidc-test-keycloak-1  Started                        0.5s
$ 

起動後、それぞれ以下のホスト名でアクセスできます。

各コンテナの設定内容

Kong Gateway コンテナ

Kong Konnect を Hybrid モードで起動する設定にしています。

  • compose.yaml での設定内容
キー 内容
image kong-gateway:3.8.0 Kong Gateway コンテナを使用
environment KONG_ROLE: "data_plane" Kong Konnect データプレーンとして使用
KONG_DATABASE: "off" DB-lessモードで使用
KONG_VITALS: "off" 監視機能をOFFにします
KONG_CLUSTER_CONTROL_PLANE: "${CONTROL_PLANE}" Kong Konnect コントロールプレーンのホスト名:ポート番号
KONG_CLUSTER_SERVER_NAME: "${SERVER_NAME}" Kong Konnect サーバ名
KONG_CLUSTER_CERT: "${CERT}" Kong Konnect で使用するために必要
KONG_CLUSTER_CERT_KEY: "${CERT_KEY}" Kong Konnect で使用するために必要
KONG_LUA_SSL_TRUSTED_CERTIFICATE: "system" Kong (Lua) ではOSのルート証明書を使用
KONG_KONNECT_MODE: "on" Kong Konnect で使用するために必要
ports "48000:8000" Kong の API Gateway のポート 8000 を 48000 で公開

${CERT_KEY} のような部分には環境変数が展開されます(この例では CERT_KEY)。
docker compose up -d 実行時にそれぞれの環境変数を指定するか、または、 compose.yaml ファイルと同じフォルダに .env ファイルを以下の内容で配置すると、設定した値が展開されます。

# Kong Konnect コントロールプレーン
CONTROL_PLANE="クラスタにつけられるID.usまたはeu.cp0.konghq.com:443"
# Kong Konnect ベースホスト名 
SERVER_NAME="クラスタにつけられるID.usまたはeu.cp0.konghq.com"

# Kong Cluster で使う証明書
CERT="-----BEGIN CERTIFICATE-----
(省略)
-----END CERTIFICATE-----"

# Kong Cluster で使う秘密鍵
CERT_KEY="-----BEGIN PRIVATE KEY-----
(省略)
-----END PRIVATE KEY-----"

Kong Konnect データプレーンの実行については次の記事が参考になると思います。

Keycloack コンテナ

Keycloak を開発モードで実行します。
データストアを外部に用意せず、 Keycloak に追加したユーザでログイン動作を確認します。

  • compose.yaml での設定内容
キー 内容
image quay.io/keycloak/keycloak:23 Keycloak 23 の Docker イメージを使用
ports "48080:8080" Keycloak の実行ポート 8080 を 48080 で公開
environment KEYCLOAK_ADMIN: admin 初期管理ユーザのログインID
KEYCLOAK_ADMIN_PASSWORD: admin 初期管理者の初期パスワード
command start-dev 実行コマンド (Dockerfile での CMD 上書き)
開発モードでの実行

Keycloak も Kong Gateway も HTTP で動作させるため、 HTTP での Cookie の取り扱いで問題が出にくい Keycloak 23 を使っています。

最新のドキュメントの説明とは環境変数名が異なりますが、Keycloak 23 ではこの設定で動作します。

httpbin コンテナ

ユーザのWEBサービスに相当するモックアップです。

  • compose.yaml での設定内容
キー 内容
image kennethreitz/httpbin httpbin コンテナイメージを使用
ports "40080:80" httpbin の実行ポート 80 を 40080 で公開

実行環境から http://httpbin.konghq.com/ にアクセスできる場合は、このコンテナは実行せず、 Service として http://httpbin.konghq.com/ をアップストリームに指定することができます。

設定

Kong Konnect と OIDC プラグイン / Keycloak それぞれに対して設定をします。

Kong のサイトでは private_key_jwt によるクライアント認証で説明されていますが、ここでは client_secret_basic で動作を確認します。

Kong Konnect の設定

Konnect の管理画面から以下を設定します。

  1. httpbin をアップストリームのアプリケーションに指定して Service を追加
  2. テスト用の Route を作成し、対象の Service に割り付ける
  3. テスト用の Route に対して OpenID Connect プラグインを設定する
1. Service の追加

local-httpbin という名称で、ローカル実行の httpbin をアップストリームに指定します。

service-local-httpbin-masked.png

2. Route の作成

mock-route という名称で、 local-httpbin Service に Route を追加します。
/mock-api (http://IPアドレス/mock-api) へのアクセスを local-httpbin ( http://IPアドレス:40080/ で起動しているダミーホスト) に割り付けます。

route-mock-api-masked.png

3. OIDC プラグインの設定

左のメニューから Plugin を選択し、 OpenID Connect プラグインの Enable のリンクをクリックします。

choose-plugin-masked.png

設定画面が現れます。最初に現れた画面で基本項目と共通 (Common) 項目を設定します。

  • プラグインを特定の Route にのみ割り付けるため、Scoped を選択します。
  • Route は直近で追加した mock-api を使用します。
  • OIDCプラグインは同一サービスでもそれぞれ別の設定で使われがちなため、必須ではありませんが、名前を付けます (oidc-test)。
  • Client ID をここでは kong にします。Keycloak で設定するクライアント名がこれになります。
  • Authorization Code Flow にチェックを入れ、Enable Session Management を ON にします。

oidc-plugin-common-masked.png

クライアントシークレットは Keycloak で発行したものを設定します。

Keycloak の設定

Keycloak のバージョン/方式が異なるため、公式サイトでの説明とは見た目や画面遷移が少々異なります。

1. Client ID の追加

Keycloak に Client ID として kong を追加します。

Clients メニューより Create client ボタンを押して新規にクライアントを追加します。
keycloak-01.png
Client ID として kong を設定します。
keycloak-02.png

以下の項目を ON にします。
Client authentication: on
Authorizaton: on
Authentication flow: ✓
Direct access grants: ✓

keycloak-03.png

有効なリダイレクトURIを設定します。
(Kong の Route (mock-api) に対応する URL です)
keycloak-04.png

ここで保存(Save)します。

2. シークレットの確認と設定

Credentials タブを開いて、シークレットを取得し、Kong Konnect の OIDC プラグインに設定します。

  • KeyCloack からシークレットを取得
    Client Authentication が Client Secret でなければ Client Secret に変更してください。
    画面から取得できます。Client Secret が📋ボタンでコピーできない場合は、👁をクリックすると表示することができます(範囲選択でテキストをコピーできます)。
    client-secret-1.png

  • Kong へのクライアントシークレットの設定
    Kong Konnect の管理画面でシークレットを設定します。
    シークレットは Common タブで設定できます。
    client-secret-2.png

3. ログインユーザの追加

Users メニューからテスト用のユーザを追加(Add user)します。
keycloak-11.png

ログイン名は oidc-user と設定しています。ログインテスト用なので、 email によるユーザ確認はスキップします (Email verified を ON に設定)。
keycloak-12.png

Save ボタンで保存したら、 Credentials タブに移動します。
keycloak-14.png

Set Password ボタンからパスワードを設定してください。
Temporary のスイッチは切っておいてください(初回ログインにパスワードの変更を求められません)。

keycloak-15.png

これで、Keycloak に oidc-user というアカウントが作成されました。
以後、KeyCloak を OIDC の IdP として使用できます。

ここでは master レルムにユーザを追加していますが、開発・テストなどある程度の期間使う場合はレルムを追加し、そのレルムに対してクライアントおよびユーザを追加するようにしてください。

Keycloak の起動直後は localhost 以外から http で接続できません。
管理画面表示には https が必要ですが、証明書のエラーを無視できない場合には CLI で http でアクセスできるように設定することができます。

http でも管理画面を出すようにする手順

Keycloak の Docker コンテナが起動したら、Keycloak の管理用シェルスクリプトを使って設定を変更します。

1. 実行中のコンテナから Keycloak を探す

$ docker ps
CONTAINER ID   IMAGE                              COMMAND                  CREATED              STATUS              PORTS                                                                                                NAMES
7ed1039dc8c3   quay.io/keycloak/keycloak:26.0.6   "/opt/keycloak/bin/k…"   About a minute ago   Up About a minute   0.0.0.0:8080->48080/tcp, [::]:48080->8080/tcp, 9000/tcp, 0.0.0.0:48443->8443/tcp, [::]:48443->8443/tcp   oidc-test-keycloak-1
$ 

2. 見つけたコンテナで shell を実行する

docker exec -it 7ed1039dc8c3 /bin/bash

3. CLIツールにより管理ユーザーでログインし、realm (master) の設定を変更する

bash-5.1$ cd /opt/keycloak/
bash-5.1$ ./bin/kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
Logging into http://localhost:8080 as user admin of realm master
Enter password:
bash-5.1$ ./bin/kcadm.sh update realms/master -s sslRequired=NONE
bash-5.1$ 

admin でログインできれば、管理画面からも設定できます。
デフォルト値は All requests (常に HTTPS 必要)です。

keycloak-require-ssl-none.png

参考記事: https://www.mtioutput.com/entry/keycloak-admin-httpserror

http での管理画面表示は開発時・動作確認時のみにとどめてください。

実行確認

実行確認はあっさりしたものです。

http://データプレーンの動作しているホストのIPアドレス:48000/mock-api/anything

に対してアクセスすると Keycloak のログイン画面が出ます。
最初に提示したシーケンス図の❶~❹にあたります。

login.png

ID/パスワードを入力した後は、通常通りの応答電文が得られます。
最初に提示したシーケンス図の❺~⓲にあたります。

mock-api-anything.png

要求ヘッダには、ブラウザからのものに加えて、Kong と OIDC プラグインが付けたトークンが追加されており、Web サービスでユーザー情報などを取得できます。

  • トークンの内容の確認
    ピリオドで区切られたトークンの1番目と2番目のJSONの内容を確認してみます。一部バイナリ値があるので jq がエラーになりますが、表示はできます。
    oidc-decode-token.png

スクリーンキャプチャには一部塗りつぶした部分があります。

おわりに

OpenID Connect ではさまざまな認証方法が選択できますが、その分設定項目が多く煩雑になりがちで、 Web サービス自体に組み込むとテスト・保守がしにくくなります。Webサービス側で本来の目的に直接関係しない設定項目の面倒もみなければなりません。

Kong Gateway に OpenID Connect プラグインを追加することで、Web サービスへのログインを Web サービスから切り離しやすくなり、テスト計画や保守をしやすくすることができます。

Kong Gateway をうまく使って、実装・運用・保守の負荷を下げて行きましょう。

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?