はじめに
Spring Boot で OpenID Connect (以下、OIDC) によるソーシャルログイン機能を実装する場合、OIDC プロバイダーの適切な設定は不可欠です。正しく構成されていないと、アプリケーションを正常に起動することができなくなってしまいます。
たとえば、GitHub からプロジェクトをクローンしてローカル環境で動作させる場合、クライアントシークレットなどの機密情報を共有するのはセキュリティ上のリスクが高く、現実的ではありません。一方で、各開発者が個別に OIDC プロバイダーにアプリケーションを登録するのも手間もかかります。そもそも、柔軟性やコスト面から本番用の OIDC プロバイダーを利用するのが好ましくない場合もあります。
Keycloak を開発環境用の OIDC プロバイダーとして代用する方法を試したところ、比較的簡単に実装できたので、本記事ではその具体的な手順を紹介します。
環境
- Docker: 24.0.5
- Docker Desktop: 4.33.1
- Docker Compose: 2.20.2-desktop.1
- Keycloak: 25.0.1(Docker コンテナとして実行)
- Spring Boot: 3.3.3
- Java: OpenJDK 17
- Gradle: 8.8
- Windows 11 Pro
Keycloak ついて
Keycloak は、ユーザーの認証やアクセス管理を行うオープンソースのツールです。
シングルサインオン(SSO)、ID ブローカー、ソーシャルログイン、ユーザーフェデレーションなどの多くの機能を提供し、管理コンソールを通じてこれらの設定を直感的に行えるのが大きな特徴です。
構築する開発環境について
多様な機能を持つ Keycloak ですが、今回は開発環境用の OIDC プロバイダーとして利用します。
また、Keycloak はローカルに直接インストールすることも可能ですが、今回は移植性を高めるために Docker コンテナで稼働させます。ただし、Keycloak の設定情報はコンテナを削除するときに失われてしまうため、事前にエクスポートしてプロジェクトに含めておきます。
これにより、GitHub からプロジェクトをクローンしたあとに、即座にアプリケーションの立ち上げが可能な状態を実現します。
環境構築
Keycloak の設定情報エクスポートから実際の開発環境でのセットアップまでを段階的に解説し、最後に Spring Boot アプリケーションと Keycloak の連携方法について簡単に紹介します。
なお、以下の手順は Spring Boot アプリケーションのプロジェクトルートで行うことを想定しています。ディレクトリの指定は、適宜プロジェクト構成に合わせて変更してください。
1. 設定情報エクスポート専用の Keycloak コンテナ起動
はじめに、Keycloak 設定情報をエクスポートするために使うコンテナを起動します。
Spring Boot アプリケーションのプロジェクトルートで以下のコマンドを実行してください。
docker run -dit \
--name keycloak-export \
--mount type=bind,src="$(pwd)"/docker/keycloak/data/import,target=/opt/keycloak/data/export \
-p 18080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:25.0.1 start-dev
オプション説明
-
--mount type=bind,src="$(pwd)"/docker/keycloak/data/import,target=/opt/keycloak/data/export
コンテナ内にエクスポートされた設定ファイルをホストマシン上に保存します。どちらのディレクトリも必要に応じて変更可能です。
※"$(pwd)"
は、現在の作業ディレクトリ(つまり、Spring Boot アプリケーションのプロジェクトルート)を表します。 -
-p 18080:8080
ホストの 18080 ポートをコンテナの 8080 ポートにマッピングします。
8080 ポートは、Spring Boot アプリケーションのポートと重複する可能性があるため、必要に応じてポート番号を変更します。 -
-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin
管理者ユーザーのユーザー名とパスワードを設定します。管理コンソールにログインする際に使用します。 -
start-dev
Keycloak を開発モードで起動します。
2. Keycloak における認証環境の設定
つぎは、Keycloak 管理コンソールで OIDC を利用した認証に必要な設定を行っていきます。
まず、ブラウザを開いて http://localhost:18080 にアクセスしてください。
Keycloak のログイン画面が表示されたら、先ほど設定した管理者ユーザー名(admin)とパスワード(admin)でログインします。
ログインすると、Keycloak 管理コンソールが表示されます。初期設定では、デフォルトの master レルムが選択されています。
レルム (Realm) とは、Keycloak においてユーザー、認証、セッション管理、アクセスコントロールなど、セキュリティ関連の情報を管理する単位です。
今回の場合、単一の OIDC プロバイダーの設定が適用される範囲と考えると理解しやすいでしょう。
デフォルトで存在する master レルムは、Keycloak 全体を管理するための特別なレルムです。通常、アプリケーションを管理するレルムとしては使用しないため、新しくレルムを作成する必要があります。
2.1. レルム作成
以下の手順に従って、新しいレルムを作成しましょう。
1. 画面左上部のドロップダウンメニューから、[Create realm] ボタンを選択します。
2. Realm name フィールドに mykeycloak
と入力し、[Create] ボタンをクリックします。
新しく作成されたレルムの画面が表示されたら作成完了です。
以降の操作は、この mykeycloak レルム内で行っていきます。
2.2. ユーザー作成
つぎは、mykeycloak レルムにユーザーを追加します。
以下の手順に従ってください。
1. 左側のメニューから [Users] を選択します。
2. [Create new user] ボタンをクリックします。
3. フォームに以下の情報を入力し、[Create] ボタンをクリックします。
-
Username:
user
- Email: 任意のメールアドレス
- First name: 任意の名前
- Last name: 任意の姓
ユーザーが作成されると、そのユーザーの詳細情報ページに移動します。
このユーザーを使ってログインできるようにするために、パスワードの設定も行います。
1. 上部の [Credentials] タブを選択します。
2. [Set Password] ボタンをクリックします。
3. パスワードを入力し、Temporary フィールドを Off に切り替えます。
4. [Save] ボタンをクリックします。
※ Temporary フィールドは、ユーザーが最初のログイン時にこのパスワードを更新する必要がないようにオフに切り替えます。
2.3. クライアント作成
つぎは、Spring Boot アプリケーションをクライアントとして登録します。
以下の手順に従って設定を行ってください。
1. 左側のメニューから [Clients] を選択します。
2. [Create client] ボタンをクリックします。
3. フォームに以下の情報を入力し、[Next] ボタンをクリックします。
-
Client type:
OpenID Connect
-
Client ID:
myclient
4. Client authentication を On に切り替え、[Next] ボタンをクリックします。
5. Valid redirect RUIs フィールドに http://localhost:8080/*
と入力し、[Save] ボタンをクリックします。
リダイレクト URI には、Spring Boot アプリケーションが 8080 ポートで実行される想定で、http://localhost:8080/*
を指定しています。
レルムやユーザーの設定が Keycloak 固有であるのに対し、クライアントの作成 (アプリケーションの登録) は、一般的な OIDC プロバイダーでも必要となる標準的な設定です。
これで、Spring Boot アプリケーションにおいて、Keycloak を OIDC プロバイダーとして利用できるようになりました。
3. Keycloak の設定情報エクスポート
設定が完了したので、つぎはこの情報を JSON ファイルとしてエクスポートします。
エクスポートは Keycloak 管理コンソールからも可能ですが、ユーザー情報も含めてエクスポートするためにコマンドラインを使用します。
まず、以下のコマンドを実行して、実行中の Keycloak コンテナに接続してください。
docker exec -it keycloak-export /bin/bash
コンテナ内のシェルに入ったら、以下のコマンドを実行します。
/opt/keycloak/bin/kc.sh export --dir /opt/keycloak/data/export --users realm_file
オプション説明
-
--dir /opt/keycloak/data/export
設定ファイルのエクスポート先ディレクトリを指定します。このディレクトリはコンテナの起動時にマウントしたコンテナ側のディレクトリと一致させる必要があります。 -
--users realm_file
ユーザー情報をエクスポートする方法を指定します。今回は、ユーザー情報をレルム設定と同じファイルに含めます。
エクスポートが正常に終了すると、Spring Boot アプリケーションプロジェクトの /docker/keycloak/data/import
ディレクトリには、以下のようなファイルが作成されています。
このファイルは、後ほど説明する開発環境向けの Keycloak コンテナで使用します。
コンテナ内でエクスポートが完了したら、以下のコマンドを実行して、コンテナのシェルから抜けます。
exit
その後、ホスト環境に戻ったら以下のコマンドでコンテナを停止します。
docker stop keycloak-export
これで設定ファイルの作成は完了です。
4. 開発環境向け Keycloak コンテナの構築
つぎは、エクスポートした設定情報が反映された Keycloak コンテナを起動する例を示します。
Spring Boot アプリケーションのプロジェクトルートで以下のコマンドを実行してください。
docker run -d \
--name keycloak-dev \
--mount type=bind,src="$(pwd)"/docker/keycloak/data/import,target=/opt/keycloak/data/import \
-p 18080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:25.0.1 start-dev --import-realm
コマンドが長いため、以下のような compose.yml
ファイルを用意してもいいかもしれません。
services:
keycloak:
image: quay.io/keycloak/keycloak:25.0.1
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
ports:
- '18080:8080'
volumes:
- ./docker/keycloak/data/import:/opt/keycloak/data/import
command: start-dev --import-realm
このファイルを使用する場合、以下のコマンドで Keycloak コンテナを起動します。
docker-compose up -d
オプション説明
-
--mount type=bind,src="$(pwd)"/docker/keycloak/data/import,target=/opt/keycloak/data/import
先ほどエクスポートした設定ファイルを含むディレクトリをコンテナ内のディレクトリにマウントします。 -
start-dev --import-realm
Keycloak を開発モードで起動し、マウントした/opt/keycloak/data/import
ディレクトリから設定ファイルを自動インポートします。
これで、設定情報が反映された状態で Keycloak コンテナが立ち上がります。
設定情報が正常にインポートされているか確認してみましょう。
コンテナが正常に起動したら、ブラウザで http://localhost:18080 にアクセスして、Keycloak 管理コンソールにログインします。
設定したレルム、ユーザー、およびクライアントが存在し、各値が適切に設定されていることを確認してください。
アプリケーションの開発やテストは、この開発環境向けの Keycloak を稼働させた状態で進めていくことになります。
5. Spring Boot と Keycloak の連携
さいごに、Spring Boot アプリケーションで OIDC を利用した認証を実装し、Keycloak と連携させる方法について説明します。
ここでは、Keycloak の設定に関連する部分に焦点を当てます。Spring Security の設定や依存関係の追加については、Spring Boot の公式ドキュメントを参照してください。
ソースコードは、以下のリポジトリから参照できます。
以下は、開発環境用プロパティファイルの設定例です。
spring:
security:
oauth2:
client: # Yahoo! JAPAN の代替として Keycloak を使用
provider:
yahoo:
issuer-uri: http://localhost:18080/realms/mykeycloak
registration:
yahoo:
client-id: myclient
client-secret: <KeyCloak のクライアントシークレット>
provider: yahoo
scope: openid
authorization-grant-type: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
プロパティ説明
-
client-id
Keycloak で設定したクライアント ID(myclient)を指定します。 -
client-secret
Keycloak で生成されたクライアントシークレットを指定します。この値は、Keycloak 管理コンソールの [Clients] の [Credentials] タブで確認できます。
-
redirect-uri
認証後のリダイレクト先 URI を指定します。{baseUrl}
はアプリケーションのベース URL、{registrationId}
は登録 ID(この場合は "yahoo")に置き換えられます。
この値は Keycloak 管理コンソールの [Clients] の [Valid Redirect URIs] に設定した値と一致させます。 -
issuer-uri
Keycloak サーバーの OIDC 設定情報を提供するエンドポイントを指定します。
このプロパティファイルでは、プロバイダー名は "yahoo" となっていますが、実際には Keycloak が OIDC プロバイダーとして機能します。これにより、ローカル環境で動作する Keycloak サーバーを使って認証を行うことができます。
プロファイル機能について
Spring Boot では、プロファイル機能を使うことで、アプリケーションの設定や動作を条件に応じて切り替えることができます。
たとえば、開発環境用の application-dev.yml と本番環境用の application-prod.yml を用意することで、環境変数やコマンドラインオプションを通じて適用するファイルを切り替えることが可能です。
この機能により、開発時にはローカルの Keycloak を使用し、本番環境では Yahoo! ID 連携 を利用するなど、環境に応じた柔軟な運用が実現できます。
※ 注意
Keycloak では多くの標準的な OIDC の動作をシミュレートできますが、各プロバイダー固有の認証フローやエラーハンドリングの挙動を完全に再現できない場合があります。
そのため、開発中は Keycloak を使用し、統合テストや最終的な本番環境への移行前には、実際に使用する OIDC プロバイダーでのテストを行うことが推奨されます。
さいごに
本記事では、Keycloak を使用して開発環境用の OIDC プロバイダーを構築する方法を説明しました。この方法により、実際の OIDC プロバイダーの認証情報を使用せずに開発を進められ、効率的な開発環境の構築できます。
また、Keycloak は豊富な設定オプションを提供しており、OIDC プロバイダー固有の実装や要件を再現することも可能です。セキュリティや認証に関する機能を本番環境に近い形で検証しながら開発を進めることができるので、ぜひ試してみてください。
参考
▼ Docker - Keycloak
▼ Importing and Exporting Realms - Keycloak
▼ Spring Boot と OAuth2 - 公式サンプルコード (pleiades.io)
▼ コア構成 :: Spring Security - リファレンスドキュメント (pleiades.io)
▼ v2 - Yahoo!デベロッパーネットワーク