28
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NRI OpenStandia Advent Calendar 2022

Day 4

Quarkus版KeycloakとOAuth2 Proxy、Docker Composeを使用したローカル環境構築と動作確認

Last updated at Posted at 2022-12-03

はじめに

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、その他必要部品が揃った環境を作成します。

サーバー構成図

image.png
※本環境は動作確認目的としているため、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レルムを設定

httpsの無効化

  • Require SSLをNONEに設定します。
    image.png

echoクライアントの設定

  • echoクライアントを作成します。
    image.png
Confidentialクライアントの設定
  • ConfidentialクライアントにするためにClient authenticationをOnにします。
    image.png
リダイレクトURIを設定
  • Valid redirect URIs(リダイレクトURI)にhttp://test.echo.local/oauth2/callbackを設定します。
    image.png
OAuth2 Proxyにechoクライアントのシークレットを設定
  • echoクライアントのClient secretをdocker-compose.ymlのOAUTH2_PROXY_CLIENT_SECRETに設定します。
    ※設定後はdocker compose up -d --force-recreate --buildコマンドでDockerを再起動します。
    image.png

ユーザ作成

  • exampleレルムにユーザを作成します。
    oauth2-proxy.cfgにメールアドレスが必須になる設定を加えているため、Emailも設定します。
    ※Emailを設定していないユーザでログインしようとすると、OAuth2 Proxyのエラー画面が表示されてしまいます。
    image.png

結果

ここまでの手順でechoアプリへアクセスするとKeycloakによる認証が行われるようになったので、こちらの動作確認を行います。

echoアプリにログイン

  • 以下のechoアプリにアクセスします。
    http://test.echo.local

  • OAuth2 ProxyによりKeycloakのログイン画面に飛ばされることを確認します。

  • 作成したユーザでログインします。
    image.png

  • ログインするとechoアプリへアクセスして、リクエストヘッダーが表示されます。
    image.png

さいごに

Quarkus版Keycloakでユーザ認証する環境を作成しました。
Keycloak以外にもDocker、OAuth2 Proxy、Nginxなどの構築が必要なため、折々他メンバーに手助けいただきながら執筆終えられました。
本記事が環境構築などの参考になれば幸いです。

参考サイト

Keycloak GitHub
OAuth2 Proxy GitHub

28
4
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
28
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?