はじめに
NRI OpenStandia Advent Calendar 2022の4日目は、Quarkus版Keycloakを使用してユーザ認証するローカル環境を作成します。
Quarkus版Keycloakとは
従来、KeycloakはWildFlyで動作していましたが、こちらは2022年6月で開発終了して、Keycloak18からQuarkus版へ移行しました。
Quarkusとは、Java仮想マシン(JVM)およびネイティブコンパイルのために作成されたフルスタックのJavaフレームワークです。
Javaをコンテナに最適化し、サーバーレス、クラウド、Kubernetesの各環境で効果的なプラットフォームとして使用できるようにします。
Quarkus版Keycloakでは以下が変更されています。
- Keycloakの構成の大幅な変更
- デフォルトのコンテキストパスから/authを削除
- カスタムプロバイダーのパッケージ化とデプロイ方法の変更
- KubernetesとOpenShift用に新しいオペレーターとCRDsを導入
詳細は以下Keycloak公式サイトに記述がありますので、興味のある方はご確認ください。
https://www.keycloak.org/migration/migrating-to-quarkus
今回実施すること
- Docker環境でOAuth2 ProxyをクライアントとしてKeycloakの動作を確認するための環境をDocker Composeで構築します。
- OAuth2 ProxyをクライアントとするためのKeycloak, OAuth2 Proxyの設定を行います。
- リクエストヘッダを表示するためのHTTPサーバ(以降echoアプリ)を配置して認証時に連携されるリクエストヘッダーを確認します。
動作環境
Dockerホストサーバの環境
項目 | バージョン |
---|---|
OS | Amazon Linux 2 |
Docker | 20.10.13 |
Docker Compose | 2.4.1 |
ブラウザ操作する環境
項目 | バージョン |
---|---|
OS | Windows 10 Pro |
ブラウザ | Google Chrome 102.0.5005.63 |
準備
Dockerホスト予定のサーバにdockerとDocker Composeをインストールしておきます。
手順
Docker環境作成
- Keycloakが動作するDocker環境を作成します。
Keycloak、OAuth2 Proxy、echoアプリ、Nginx、その他必要部品が揃った環境を作成します。
サーバー構成図
※本環境は動作確認目的としているため、https接続を無効化します。
項目 | バージョン | アクター |
---|---|---|
Keycloak | 20.0.1 | OP(OpenID Provider) |
OAuth2 Proxy | v7.2.0-amd64 | RP(Relying Party) |
Nginx | 1.22.1-alpine | リバースプロキシ |
PostgreSQL | 13-alpine | RDBMS(Keycloak用) |
http-https-echo | v27 | バックエンドアプリケーション |
ディレクトリ構成
Keycloak-quarkus
├ oauth2-proxy
| └ oauth2-proxy.cfg
| └ Dockerfile
├ nginx
| └ proxy.conf
| └ Dockerfile
└ docker-compose.yml
ファイル名 | 用途 |
---|---|
docker-compose.yml | Keycloak, PostgreSQL, OAuth2 Proxy, echo, NginxのDockerコンテナを定義。 |
oauth2-proxy.cfg | OAuth2 Proxyの設定ファイル。許可するドメイン、クライアントID、クライアントのリダイレクトURLを設定。 |
(oauth2-proxyディレクトリの)Dockerfile | OAuth2 Proxyのイメージを指定。 |
proxy.conf | Nginxの設定ファイル。listenするアドレス/ポートとサーバネームを設定。 |
(nginxディレクトリの)Dockerfile | Nginxのイメージを指定。 |
各ファイルの内容
docker-compose.yml
version: "3"
services:
keycloak:
image: quay.io/keycloak/keycloak:20.0.1
entrypoint: ["/opt/keycloak/bin/kc.sh","start-dev"]
environment:
KC_DB: "postgres"
KC_DB_URL: "jdbc:postgresql://postgres:5432/keycloak"
KC_DB_USERNAME: "keycloak"
KC_DB_PASSWORD: "password"
KC_DB_SCHEMA: "public"
KC_PROXY: "edge"
KC_HEALTH_ENABLED: "true"
KEYCLOAK_ADMIN: "admin"
KEYCLOAK_ADMIN_PASSWORD: "password"
healthcheck: test: curl -f http://keycloak:8080/health
interval: 10s
timeout: 120s
retries: 10
start_period: 60s
depends_on:
- postgres
postgres:
image: postgres:13-alpine
environment:
POSTGRES_DB: "keycloak"
POSTGRES_USER: "keycloak"
POSTGRES_PASSWORD: "password"
volumes:
- postgres_data:/var/lib/postgresql/data
oauth2-proxy:
build:
context: ./oauth2-proxy
command: ["--config=/etc/oauth2-proxy.cfg"]
environment:
OAUTH2_PROXY_PROVIDER: "oidc"
OAUTH2_PROXY_UPSTREAMS: "http://echo:80"
OAUTH2_PROXY_OIDC_ISSUER_URL: "http://test.keycloak.local/realms/example"
OAUTH2_PROXY_CLIENT_SECRET: "4BYHejmGCso9Jxxr6KpjxnGdaZSABmQL"
OAUTH2_PROXY_COOKIE_SECRET: "SECRET_VALUE!!!!"
OAUTH2_PROXY_COOKIE_DOMAINS: "test.echo.local"
depends_on:
keycloak:
condition: service_healthy
nginx:
condition: service_started
restart: on-failure:10
echo:
image: mendhak/http-https-echo:latest
nginx:
build:
context: ./nginx
ports:
- "80:80"
depends_on:
keycloak:
condition: service_healthy
restart: on-failure:10
networks:
default:
aliases:
- test.keycloak.local
volumes:
postgres_data:
driver: local
Keycloakコンテナの設定値の説明
キー | 設定値 | 説明 |
---|---|---|
image | quay.io/keycloak/keycloak:20.0.1 | Keycloakバージョン20.0.1をpull |
entrypoint | ["/opt/keycloak/bin/kc.sh","start-dev"] | コンテナ実行時に、引数start-devをつけてkc.sh実行。このコマンドはKeycloakを開発者モードで起動するもので、「HTTPが有効」「テーマ・テンプレートのキャッシュが無効化され、テーマ開発がしやすい」などの特徴がある。 |
environment | ||
KC_DB: "postgres" | DBをPostgreSQLに設定 | |
KC_DB_URL: "jdbc:postgresql://postgres:5432/keycloak" | DBのJDBC URLを設定 | |
KC_DB_USERNAME: "keycloak" | DBユーザを設定 | |
KC_DB_PASSWORD: "password" | DBユーザのパスワードを設定 | |
KC_DB_SCHEMA: "public" | 使用するスキーマを設定 | |
KC_PROXY: "edge" | Keycloakがリバースプロキシの後ろにある場合にプロキシモードを設定。edgeはプロキシーと Keycloak の間で HTTP を介した通信を有効にする。 | |
KC_HEALTH_ENABLED: "true" | ヘルスチェックエンドポイントを使用するか設定 | |
KEYCLOAK_ADMIN: "admin" | マスターレルムのユーザを設定 | |
KEYCLOAK_ADMIN_PASSWORD: "password" | マスターレルムのユーザのパスワードを設定 | |
healthcheck | ||
test: curl -f http://keycloak:8080/health | ヘルスチェック時に実行するコマンドを設定 | |
interval: 10s | ヘルスチェックを行う時間間隔を設定 | |
timeout: 120s | ヘルスチェックコマンドが終わらない場合いつまで待つかを設定 | |
retries: 10 | 何回連続すれば状態をhealthy / unhealthyに戻せるかを設定 | |
start_period: 60s | コンテナ起動してから失敗しても失敗とカウントしない時間を設定 | |
depends_on | ||
- postgres | サービス間の依存関係を設定。PostgreSQLコンテナが起動した後にKeycloakコンテナが起動するように設定。 |
PostgreSQLコンテナの設定値の説明
キー | 設定値 | 説明 |
---|---|---|
image | postgres:13-alpine | PostgreSQLバージョン13をpull |
environment | ||
POSTGRES_DB: "keycloak" | 使用するDBを設定 | |
POSTGRES_USER: "keycloak" | アクセスするユーザを設定 | |
POSTGRES_PASSWORD: "password" | アクセスするユーザのパスワードを設定 | |
volumes | ||
- postgres_data:/var/lib/postgresql/data | postgres_dataのマウント先を設定 |
oauth2-proxyコンテナの設定値の説明
キー | 設定値 | 説明 |
---|---|---|
build | ||
context: ./oauth2-proxy | ./oauth2-proxyのDockerfileでビルド | |
command | command: ["--config=/etc/oauth2-proxy.cfg"] | /etc/oauth2-proxy.cfgの設定ファイルを読み込む |
environment | ||
OAUTH2_PROXY_PROVIDER: "oidc" | oidcを設定 | |
OAUTH2_PROXY_UPSTREAMS: "http://echo:80" | OAuth2 Proxyのアップストリームを設定 | |
OAUTH2_PROXY_OIDC_ISSUER_URL: "http://test.keycloak.local/realms/example" | issuer(Keycloakのexampleレルム)のURLを設定。 設定する値の確認方法は以下の通り。 ・Keycloakにexampleレルムを作成後にRealm settings画面を開く。 ・Endpointsの OpenID Endpoint Configuration のリンクをクリックする。・表示されたJSONのissuerの値を設定する。 ※OpenID Connectに必要な各種設定値が記載されたJSONは OpenID Connect設定値エンドポイント([ベースURL]/.well-known/openid-configuration) から取得できます。このエンドポイントはOpenID Connectの仕様に定められており、OpenID Connectに準拠してる認証サービスには必ず存在します。 |
|
OAUTH2_PROXY_CLIENT_SECRET: "4BYHejmGCso9Jxxr6KpjxnGdaZSABmQL" | Keycloakで発行したクライアントシークレットを設定 | |
OAUTH2_PROXY_COOKIE_SECRET: "SECRET_VALUE!!!!" | OAuth2 Proxyで発行するクッキーのシークレットを設定 | |
OAUTH2_PROXY_COOKIE_DOMAINS: "test.echo.local" | クッキーのドメインを設定 | |
depends_on | ||
keycloak: condition: service_healthy | サービス間の依存関係を設定。Keycloakコンテナのヘルスチェックが通ったらコンテナが起動するように設定。 | |
nginx: condition: service_started | サービス間の依存関係を設定。Nginxコンテナが起動したらコンテナが起動するように設定。 | |
restart | on-failure:10 | コンテナ再起動する時間を設定 |
echoコンテナの設定値の説明
キー | 設定値 | 説明 |
---|---|---|
image | mendhak/http-https-echo:latest | echo用のアプリをpull |
Nginxコンテナの設定値の説明
キー | 設定値 | 説明 |
---|---|---|
build | ||
context: ./nginx | ./nginxのDockerfileでビルド | |
ports | ||
- "80:80" | ホストPCへポートフォワードを設定 | |
deponds_on | ||
keycloak: condition: service_healthy | サービス間の依存関係を設定 | |
restart | ||
on-failure:10 | コンテナ再起動する時間を設定 | |
networks | ||
default: aliases: - test.keycloak.local | 他コンテナがホスト名test.keycloak.localでNginxコンテナを発見できるように設定 |
OAuth2 Proxyの設定ファイル
oauth2-proxy.cfg
## OAuth2 Proxy Config File
## https://github.com/oauth2-proxy/oauth2-proxy
## <addr>:<port> to listen on for HTTP/HTTPS clients
http_address = "0.0.0.0:3000"
reverse_proxy = true
pass_user_headers = true
email_domains = [
"*"
]
skip_provider_button = true
client_id = "echo"
scope = "openid"
cookie_expire = "12h"
cookie_refresh = "30m"
redirect_url = "http://test.echo.local/oauth2/callback"
cookie_secure = false
insecure_oidc_allow_unverified_email = true
banner = "-"
footer = "-"
設定値の説明
設定値 | 説明 |
---|---|
http_address = "0.0.0.0:3000" | クライアントを受け付けるアドレス/ポートを設定 |
reverse_proxy = true | リバースプロキシの後ろで動いている場合に設定 |
pass_user_headers = true | X-Forwarded-User、X-Forwarded-Groups、X-Forwarded-Email、および X-Forwarded-Preferred-Username の情報をアップストリームに渡すように設定 |
email_domains = ["*"] | 認証を許可するメールのドメインを設定。「*」を設定した場合、ユーザのメールのドメインがいかなるものでも認証(ログイン)可能だが、ユーザにメールアドレスを設定しておくことが必須になる。 |
skip_provider_button = true | ログインボタンの表示/非表示を設定。今回は表示しないため、即座にKeycloakのログイン画面へリダイレクトする。 |
scope = "openid" | OpenID Connectを指定 |
cookie_expire = "12h" | クッキーの有効期限を設定 |
cookie_refresh = "30m" | クッキーが最初に設定されてからリフレッシュするまでの時間を設定 |
redirect_url = "http://test.echo.local/oauth2/callback" | OAuth2 ProxyのリダイレクトURLを設定 |
cookie_secure = false | Secure Cookieを使用するか否かを設定。今回はhttp接続で動作確認を行うため、falseとする。 |
insecure_oidc_allow_unverified_email = true | 未認証のメールアドレスを許可するかを設定 |
banner = "-" | バナーを設定 |
footer = "-" | フッターを設定 |
Dockerfile
FROM quay.io/oauth2-proxy/oauth2-proxy:v7.2.0-amd64
ADD oauth2-proxy.cfg /etc/
設定値の説明
設定値 | 説明 |
---|---|
FROM quay.io/oauth2-proxy/oauth2-proxy:v7.2.0-amd64 | OAuth2 Proxyバージョン7.2.0をpull |
ADD oauth2-proxy.cfg /etc/ | コンテナの/etc/にoauth2-proxy.cfgを追加 |
Nginxの設定ファイル
proxy.conf
server {
listen 80;
server_name test.keycloak.local;
proxy_buffers 4 16k;
proxy_buffer_size 16k;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://keycloak:8080;
}
}
server {
listen 80;
server_name test.echo.local;
proxy_buffers 4 16k;
proxy_buffer_size 16k;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://oauth2-proxy:3000;
}
}
設定値の説明
- 仮想サーバtest.keycloak.local について
- ポート:80で待ち受けます。
- http://keycloak:8080 で待ち受けているKeycloakサーバに渡されます。
- 仮想サーバtest.echo.local について
- ポート:80で待ち受けます。
- http://oauth2-proxy:3000 で待ち受けているOAuth2 Proxyサーバに渡されます。(認証後はOAuth2 Proxyがバックエンドのechoアプリに渡します。)
Dockerfile
FROM nginx:1.22.1-alpine
ADD proxy.conf /etc/nginx/conf.d/
設定値の説明
設定値 | 説明 |
---|---|
FROM nginx:1.22.1-alpine | Nginxバージョン1.22.1をpull |
ADD proxy.conf /etc/nginx/conf.d/ | コンテナの/etc/nginx/conf.d/にproxy.confを追加 |
Docker環境作成後
ブラウザ操作を行うPCの設定
-
ブラウザを操作するPCのhostsに以下を追加します。
[DockerホストサーバのIPアドレス] test.keycloak.local test.echo.local
-
プロキシを使用している場合、ブラウザでtest.keycloak.localとtest.echo.localをプロキシ通信対象外にします。
※Chromeで確認する場合、ネットワークとインターネット>プロキシの手動プロキシ セットアップから行います。
Dockerでビルド
- 以下コマンドで起動します。
docker compose up -d --force-recreate --build
masterレルムに対して管理ユーザのパスワード設定・httpsの無効化
- 以下コマンドでKeycloakコンテナに入り、Admin CLIを利用してマスターレルムに対して管理ユーザのパスワード設定・https無効化を行います。
※password
の部分はadminユーザのパスワード設定を求められるため、任意の値を設定しています。
docker exec -it keycloak-quarkus-keycloak-1 /bin/bash
cd /opt/keycloak/bin
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
password
./kcadm.sh update realms/master -s sslRequired=NONE
Keycloak管理コンソールからexampleレルムを設定
-
Keycloakの管理コンソールにアクセスします。
http://test.keycloak.local/admin
httpsの無効化
echoクライアントの設定
Confidentialクライアントの設定
リダイレクトURIを設定
OAuth2 Proxyにechoクライアントのシークレットを設定
- echoクライアントのClient secretをdocker-compose.ymlのOAUTH2_PROXY_CLIENT_SECRETに設定します。
※設定後はdocker compose up -d --force-recreate --build
コマンドでDockerを再起動します。
ユーザ作成
- exampleレルムにユーザを作成します。
oauth2-proxy.cfgにメールアドレスが必須になる設定を加えているため、Emailも設定します。
※Emailを設定していないユーザでログインしようとすると、OAuth2 Proxyのエラー画面が表示されてしまいます。
結果
ここまでの手順でechoアプリへアクセスするとKeycloakによる認証が行われるようになったので、こちらの動作確認を行います。
echoアプリにログイン
-
以下のechoアプリにアクセスします。
http://test.echo.local -
OAuth2 ProxyによりKeycloakのログイン画面に飛ばされることを確認します。
さいごに
Quarkus版Keycloakでユーザ認証する環境を作成しました。
Keycloak以外にもDocker、OAuth2 Proxy、Nginxなどの構築が必要なため、折々他メンバーに手助けいただきながら執筆終えられました。
本記事が環境構築などの参考になれば幸いです。