はじめに
Keycloak には拡張機能を配置することで独自の REST API を追加できる仕組みがあります。
公式リポジトリにあるサンプルで拡張機能のビルド・デプロイの一連の流れを試したので、その手順を紹介します。
環境
Keycloak 15.0.2
% mvn --version
Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)
Maven home: /usr/local/Cellar/maven/3.8.4/libexec
Java version: 17.0.1, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk/17.0.1_1/libexec/openjdk.jdk/Contents/Home
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "11.2.3", arch: "x86_64", family: "mac"
使用するサンプル
使用するサンプルは Example Realm REST Resource provider です。
このサンプルは Keycloak に REST エンドポイント GET /auth/realms/{realm}/hello
を追加する拡張機能を作成するものです。
言語は Java によって書かれており、Maven を使用してビルドします。
追加されたエンドポイントにリクエストを送信すると Hello Keycloak
というレスポンスを返します。
手順
1. Keycloak を起動する
拡張機能のデプロイ先とする Keycloak を Docker で起動しておく。
% docker run -d --name keycloak -p 8180:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin quay.io/keycloak/keycloak:15.0.2
追加する予定のエンドポイントにリクエストを送信してみて、レスポンスが "HTTP 404 Not Found"
になることを確認する。
% curl -X GET "http://localhost:8180/auth/realms/master/hello"
{"error":"HTTP 404 Not Found"}
2. 拡張機能のソースを用意する
Keycloak のリポジトリをクローンする。
% git clone https://github.com/keycloak/keycloak.git
最新リリース (執筆時点) のタグをチェックアウトする。
% cd keycloak
% git checkout -b v15.0.2 refs/tags/15.0.2
拡張機能のサンプルのディレクトリに移動する。
% cd examples/providers/rest
3. 拡張機能をビルドする
ソースをビルドしてプロバイダー JAR ファイルを作成します。
2 通りの方法があるので好きな方を選んでください。
3.a mvn
コマンドを使用する (おすすめ)
mvn
コマンドで JAR ファイルをビルドする。
% mvn clean install
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
...
target
ディレクトリに hello-rest-example.jar
ファイルが作成されたことを確認する。
% ls target
hello-rest-example.jar
3.b InteliJ IDEA を使用する
InteliJ IDEA でプロジェクトを開く
~/keycloak/examples/providers/rest% idea .
まず、メニューバーの File > Project Structure...
をクリックする。
Project Structure ウィンドウが表示されたら、サイドバーの Project Setting > Artifacts
を選択する。
+ ボタンをクリックして JAR > From modules with dependencies...
を選択する。
Create JAR from Modules ウィンドウが表示されたら extract to target JAR のラジオボタンが選択されていることを確認する。
OK をクリックする。
次に、メニューバーの Build > Build Artifacts...
をクリックする。
Action リストの Build を選択する。
すると、out
ディレクトリ以下に hello-rest-example.jar
ファイルが作成される。
% ls out/artifacts/rest_jar
hello-rest-example.jar
4. 拡張機能をデプロイする
プロバイダー JAR ファイルを Keycloak にデプロイします。
デプロイも 2 通りの方法があるので好きな方を選んでください。
ホットデプロイができるので Keycloak Deployer を使用するのがおすすめです。
4.a Keycloak Deployer を使用する (おすすめ)
プロバイダー JAR ファイルを /opt/jboss/keycloak/standalone/deployments
ディレクトリにコピーする。
% docker cp target/hello-rest-example.jar keycloak:/opt/jboss/keycloak/standalone/deployments/.
拡張機能のデプロイが成功したか否かを確認する。
Keycloak のログを表示して Deployed "hello-rest-example.jar"
と出力されていたら成功。
% docker logs -f keycloak
...
XX:XX:XX,XXX INFO [org.jboss.as.repository] (DeploymentScanner-threads - 2) WFLYDR0001: Content added at location /opt/jboss/keycloak/standalone/data/content/e6/fe4edb414c9c15d4da06474575dbe8974803ab/content
XX:XX:XX,XXX INFO [org.jboss.as.server.deployment] (MSC service thread 1-7) WFLYSRV0027: Starting deployment of "hello-rest-example.jar" (runtime-name: "hello-rest-example.jar")
XX:XX:XX,XXX INFO [org.keycloak.subsystem.server.extension.KeycloakProviderDeploymentProcessor] (MSC service thread 1-5) Deploying Keycloak provider: hello-rest-example.jar
XX:XX:XX,XXX WARN [org.keycloak.services] (MSC service thread 1-5) KC-SERVICES0047: hello (org.keycloak.examples.rest.HelloResourceProviderFactory) is implementing the internal SPI realm-restapi-extension. This SPI is internal and may change without notice
XX:XX:XX,XXX INFO [org.jboss.as.server] (DeploymentScanner-threads - 2) WFLYSRV0010: Deployed "hello-rest-example.jar" (runtime-name : "hello-rest-example.jar")
また、デプロイが成功した場合は /opt/jboss/keycloak/standalone/deployments
ディレクトリに .deployed
という拡張子のファイルが作成される。
失敗した場合は .failed
という拡張子のファイルが作成される。
% docker exec -it -w /opt/jboss/keycloak keycloak ls standalone/deployments
hello-rest-example.jar hello-rest-example.jar.deployed README.txt
4.b Modules を使用する
プロバイダー JAR ファイルを Keycloak コンテナの適当な場所にコピーする。
% docker cp target/hello-rest-example.jar keycloak:/tmp/.
Keycloak コンテナの中で jboss-cli.sh
を実行する。
--resources
オプションには先ほどコピーしたプロバイダー JAR ファイルを指定すること。
% docker exec -it -w /opt/jboss/keycloak keycloak /bin/bash
$ ./bin/jboss-cli.sh --command="module add --name=org.keycloak.examples.hello-rest-example --resources=/tmp/hello-rest-example.jar --dependencies=org.keycloak.keycloak-core,org.keycloak.keycloak-server-spi,org.keycloak.keycloak-server-spi-private,javax.ws.rs.api"
/opt/jboss/keycloak/standalone/configuration
ディレクトリの standalone.xml
ファイルと standalone-ha.xml
ファイルに provider タグを追加する。
$ sed -ie '432i <provider>module:org.keycloak.examples.hello-rest-example</provider>' standalone/configuration/standalone.xml
$ sed -ie '490i <provider>module:org.keycloak.examples.hello-rest-example</provider>' standalone/configuration/standalone-ha.xml
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<web-context>auth</web-context>
<providers>
<provider>
classpath:${jboss.home.dir}/providers/*
</provider>
+ <provider>module:org.keycloak.examples.hello-rest-example</provider>
</providers>
<master-realm-name>master</master-realm-name>
<scheduled-task-interval>900</scheduled-task-interval>
<theme>
<staticMaxAge>2592000</staticMaxAge>
<cacheThemes>true</cacheThemes>
Keycloak を再起動する。
$ exit
% docker restart keycloak
5. 動作を確認する
追加されたエンドポイントにリクエストを送信する。
% curl -X GET "http://localhost:8180/auth/realms/master/hello"
Hello Keycloak
Hello Keycloak
と出力されたら成功です。
おわりに
Keycloak に独自の REST API を追加できることが確認できました。
参考文献
- Example Realm REST Resource provider - keycloak/keycloak
- カスタムRESTエンドポイントを追加 - Server Developer Guide
- プロバイダー実装の登録 - Server Developer Guide
- 独自カスタマイズ - Keycloakのカスタマイズポイントを整理してみる
- Keycloak Custom Rest Api (Search by user attribute - Keycloak)
- Keycloak : How to create custom rest api
- アプリケーションを JAR にパッケージ化する - IntelliJ IDEA を使用してアプリケーションをコンパイルおよびビルドする