OpenID Connect (OIDC)のDev ServicesとDev UI
Dev Services for Keycloak と OpenID Connect (OIDC) Keycloak プロバイダー用の Dev UI を使用して、これらのサービスを他の OpenID Connect プロバイダーに適応させることができます。 Quarkus を開発モードで実行する前に、すでに起動している OpenID Connect プロバイダーで Dev UI を使用することもできます。
はじめに
Quarkus には、Dev Services for Keycloak 機能があります。この機能は、quarkus-oidc
エクステンションが開発モードで起動され、結合テストがテストモードで実行され、 quarkus.oidc.auth-server-url
プロパティーが設定されていない場合にデフォルトで有効になります。
Dev Services for Keycloak 機能は、開発モードとテストモードの両方で Keycloak コンテナーを起動します。
Keycloak で保護された Quarkus アプリケーションの開発をすぐに開始するために必要なクライアントとユーザーを含む既存の Keycloak レルムを登録するか、新しいレルムを作成することで、コンテナーを初期化します。
application.properties
またはレルムファイルの変更が検出されると、コンテナーが再起動します。
さらに、http://localhost:8080/q/dev[/q/dev] で入手可能な Dev UI は、Dev UI ページでこの機能を補完します。これは、Keycloak からトークンを取得して Quarkus アプリケーションをテストする際に役立ちます。
quarkus.oidc.auth-server-url
がすでに設定されている場合、すべての OpenID Connect プロバイダーで使用できる汎用の OpenID Connect Dev Console がアクティブになります。
詳細は、Dev UI for all OpenID Connect providers を参照してください。
Dev Services for Keycloak
application.properties
ファイルで quarkus.oidc
プロパティーを設定せずにアプリケーションを起動します。
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
コンソールに次のような出力が表示されます。
KeyCloak Dev Services Starting:
2021-11-02 17:14:24,864 INFO [org.tes.con.wai.str.HttpWaitStrategy] (build-10) /unruffled_agnesi: Waiting for 60 seconds for URL: http://localhost:32781 (where port 32781 maps to container port 8080)
2021-11-02 17:14:44,170 INFO [io.qua.oid.dep.dev.key.KeycloakDevServicesProcessor] (build-10) Dev Services for Keycloak started.
Keycloak 管理コンソールにログインする場合、ユーザー名は |
Dev Services for Keycloak は、quarkus-dev-service-keycloak
というラベルの付いた既存のコンテナーを検出した場合、デフォルトで新しいコンテナーを起動しないことに注意してください。
quarkus.keycloak.devservices.service-name
プロパティーの値がラベルの値 (デフォルトは quarkus
) と一致する場合、このコンテナーに接続します。
このような場合、以下を実行すると出力が若干変更されることがあります。
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
2021-08-27 18:42:43,530 INFO [io.qua.dev.com.ContainerLocator] (build-15) Dev Services container found: 48fee151a31ddfe32c39965be8f61108587b25ed2f66cdc18bb926d9e2e570c5 (quay.io/keycloak/keycloak:21.0.2). Connecting to: 0.0.0.0:32797.
2021-08-27 18:42:43,600 INFO [io.qua.oid.dep.dev.key.KeycloakDevServicesProcessor] (build-15) Dev Services for Keycloak started.
...
Keycloak コンテナーがデフォルトの 60 秒のタイムアウト内に準備できない場合は、タイムアウト期間を延長することで解決できます。
たとえば、 |
quarkus.keycloak.devservices.shared=false
を指定すると、コンテナーの共有をオフにすることができます。
次に、メインの Dev UI ページ を開き、Keycloak ページにリンクしている OpenID Connect カードを確認します。 次に例を示します。
Keycloak provider リンクをクリックします。 このアクションにより、Dev Services for Keycloak 機能の設定に応じて外観が異なる Keycloak ページが開きます。
サービスアプリケーションの開発
デフォルトでは、Keycloak ページを使用して、Quarkus OIDC サービスアプリケーション の開発をサポートできます。
認可コードグラント
application.properties
ファイルで quarkus.oidc.devui.grant.type=code
を設定すると (これがデフォルト値です)、アクセストークンと ID トークンの両方を取得するために authorization_code
グラントが使用されます。
シングルページアプリケーション (SPA) でトークンを取得し、それを使用して Quarkus サービスにアクセスする一般的なフローをエミュレートするには、このグラントを使用することを推奨します。
まず、Log into Single Page Application オプションが表示されます。 次に例を示します。
認証プロセス中に使用する Keycloak レルムとクライアント ID を選択します。
この SPA は、OpenId Connect の public クライアントを表します。したがって、入力するクライアント ID は、シークレットのない Keycloak の public クライアントを指す必要があります。 これは、SPA が Web アプリケーションではないため、クライアントシークレットも認可コードフローを完了することが予想される場合、認可コードフローを完了するために必要なクライアントシークレットを安全に扱うことができないためです。 シークレットが必要なクライアントは、デフォルトのレルムが作成されている場合、または |
次に、Log into Single Page Application を選択すると、Keycloak にリダイレクトされ、たとえば alice:alice
として認証されます。
次に、SPA を表すページに戻ります。
取得したアクセストークンやIDトークンなどを確認することができます。
このビューでは、エンコードされた JSON Web Token (JWT) トークンが左側に表示され、ヘッダーが赤で、ペイロードまたはクレームが緑で、署名が青で強調表示されます。 また、右側にはデコードされた JWT トークンが表示され、ヘッダー、クレーム名、およびそれらの値を確認できます。
次に、相対サービスパスを入力し、トークンを送信してサービスをテストします。 SPAは通常、アプリケーションのエンドポイントにアクセストークンを送信するので、たとえば With Access Token オプションを選択します。
テスト結果領域を消去するには、右下隅にある消しゴムアイコンを使用します。
場合によっては、ID トークンがベアラートークンとしてアプリケーションフロントエンドに転送されることがあります。 これにより、エンドポイントが SPA にログインしているユーザーを識別したり、帯域外のトークン検証を実行したりできるようになります。 このような場合は、With ID Token オプションを選択してください。
サービスパスを手動で入力するのは理想的ではありません。 OIDC Dev UI ですでに取得済みのアクセストークンを使用してサービスをテストするために Swagger または GraphQL UI を有効にする方法については、Test with Swagger UI or GraphQL UI セクションを参照してください。
最後に、Log Out image::dev-ui-keycloak-logout.png[alt=Dev UI Keycloak - Log Out,role="center"] をクリックすると、別のユーザーとして Keycloak に認証できるようになります。
Log into Single Page Application を選択しすると、Keycloak からエラーが返される場合があります。
たとえば、quarkus.oidc.client-id
が Keycloak にインポートされたレルム内のクライアント ID と一致しない可能性があります。または、このレルム内のクライアントが認可コードフローをサポートするように正しく設定されていない可能性があります。
このような場合、Keycloak は error_description
クエリーパラメーターを返し、Dev UI にもこのエラーの説明が表示されます。
次に例を示します。
エラーが発生した場合は、Keycloak Admin オプションを使用して Keycloak にログインし、必要に応じてレルム設定を更新し、application.properties
を確認してください。
Swagger UI または GraphQL UI を使用したテスト
プロジェクトで quarkus-smallrye-openapi
または quarkus-smallrye-graphql
が使用されている場合は、サービスパスを手動で入力する必要がなくなり、Swagger UI または GraphQL UI を使用してサービスをテストできます。
たとえば、quarkus-smallrye-openapi
と quarkus-smallrye-graphql
の両方の依存関係を使用して Quarkus を開発モードで起動します。
Keycloak にログインすると、次のオプションが表示されます。
たとえば、Swagger UI をクリックすると、新しいブラウザータブで Swagger UI が開き、Keycloak 用の Dev UI によって取得されたトークンを使用してサービスをテストできます。
Swagger UI は再度認証を試行しません。
Swagger UI で、Swagger UI の Authorize
オプションを選択しないでください。OIDC Dev UI が Swagger UI を認可し、テストに使用するアクセストークンを提供しているためです。
GraphQL UI
とのインテグレーションも同様に機能し、Keycloak 用の Dev UI によって取得されたアクセストークンが使用されます。
Keycloak 用の Dev UI によって開始される認可コードフローを機能させるには、リダイレクト URI を登録する必要がある場合があります。
Keycloak は、認証されたユーザーが設定されたリダイレクト URI にのみリダイレクトされるように強制する場合があるためです。
認証リクエスト内の正しい Keycloak がそれを強制する場合、 この場合、右上隅の Keycloak Admin オプションを選択し、 異なるポートで実行されている複数のアプリケーション間でコンテナーを共有する場合は、アプリケーションごとに 特にコンテナーが複数のアプリケーション間で共有されている場合は、テスト目的でのみ カスタムレルムがインポートされていない場合、Dev Services for Keycloak はデフォルトのレルムを作成するときに |
インプリシット・グラント
application.properties
ファイルで quarkus.oidc.devui.grant.type=implicit
を設定すると、アクセストークンと ID トークンの両方を取得するために implicit
グラントが使用されます。
認可コードグラントが機能しない場合 (インプリシットグラントをサポートするためにクライントが Keycloak に設定されている場合) に限り、このグラントを使用してシングルページアプリケーションをエミュレートします。
パスワード・グラント
application.properties
ファイルで quarkus.oidc.devui.grant.type=password
を設定すると、次のような画面が表示されます。
レルムを選択し、クライアント ID とシークレット、ユーザー名とパスワード、相対サービスエンドポイントパスを入力して、Test service をクリックします。
200
、403
、401
、404
などのステータスコードが返されます。
ユーザー名とパスワードを含む quarkus.keycloak.devservices.users
マッププロパティーにもユーザー名が設定されている場合は、サービスをテストするときにパスワードを設定する必要はありません。
password
グラントを使用してサービスをテストするために、quarkus.keycloak.devservices.users
を初期化する必要はないことに注意してください。
Dev UI コンソールでは、次のような出力も表示されます。
2021-07-19 17:58:11,407 INFO [io.qua.oid.dep.dev.key.KeycloakDevConsolePostHandler] (security-openid-connect-quickstart-dev.jar) (DEV Console action) Using password grant to get a token from 'http://localhost:32818/realms/quarkus/protocol/openid-connect/token' for user 'alice' in realm 'quarkus' with client id 'quarkus-app'
2021-07-19 17:58:11,533 INFO [io.qua.oid.dep.dev.key.KeycloakDevConsolePostHandler] (security-openid-connect-quickstart-dev.jar) (DEV Console action) Test token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ6Z2tDazJQZ1JaYnVlVG5kcTFKSW1sVnNoZ2hhbWhtbnBNcXU0QUt5MnJBIn0.ey...
2021-07-19 17:58:11,536 INFO [io.qua.oid.dep.dev.key.KeycloakDevConsolePostHandler] (security-openid-connect-quickstart-dev.jar) (DEV Console action) Sending token to 'http://localhost:8080/api/admin'
2021-07-19 17:58:11,674 INFO [io.qua.oid.dep.dev.key.KeycloakDevConsolePostHandler] (security-openid-connect-quickstart-dev.jar) (DEV Console action) Result: 200
トークンは password
グラントを使用して Keycloak から取得され、サービスエンドポイントに送信されます。
OpenID Connectウェブアプリケーション開発
Quarkus OIDCウェブアプリケーション を開発するには、アプリケーションを開始する前に、 application.properties
ファイルで quarkus.oidc.application-type=web-app
を設定します。
アプリケーションを起動すると、このような画面が表示されます:
相対的なサービスエンドポイントパスを設定し、Log in to your web application をクリックします。 Quarkus アプリケーションからのレスポンスを受け取る前に、新しいブラウザータブでユーザー名とパスワードを入力するために Keycloak にリダイレクトされます。
この場合、Quarkus OIDC web-app
アプリケーションが認可コードフローを制御し、トークンを取得するため、Dev UI はあまり役に立ちません。
Dev UI を OIDC web-app
アプリケーションの開発のサポートにさらに役立てるために、quarkus.oidc.application-type
にプロファイル固有の値を設定することを検討してください。
%prod.quarkus.oidc.application-type=web-app
%test.quarkus.oidc.application-type=web-app
%dev.quarkus.oidc.application-type=service
このプロファイルによって、Developing service applications で説明されているすべての Dev UI オプションが、web-app
アプリケーションが開発モードで実行されているときに利用可能になります。
このアプローチの制限は、コードフローで返され、Dev UI で取得されたアクセストークンと ID トークンの両方が HTTP Bearer
トークンとしてエンドポイントに送信されることです。これは、エンドポイントで IdToken
の注入が必要な場合はうまく機能しません。
ただし、web-app
アプリケーションがアクセストークンを、たとえばロールのソースとして、または UserInfo
を取得するためにのみ使用する場合は、開発モードの service
アプリケーションであると想定される場合でも、期待どおりに機能します。
開発モードの場合、さらに良い選択肢は、application-type
プロパティーを hybrid
に設定することです。
%prod.quarkus.oidc.application-type=web-app
%test.quarkus.oidc.application-type=web-app
%dev.quarkus.oidc.application-type=hybrid
このタイプを設定すると、OIDC Dev UI を使用せずに開発モードでブラウザーからアプリケーションにアクセスした場合に、Quarkus OIDC が本番モードと同様に認可コードフローを実行するようになります。 また、ハイブリッドアプリケーションもベアラーアクセストークンを受け入れることができるため、OIDC Dev UI がより便利になります。
テストの実行
テストモードで起動した Keycloak コンテナーに対して、継続的テスト モードでテストを実行できます。
It is also recommended to run the integration tests against Keycloak by using Dev Services for Keycloak. For more information, see Testing OpenID Connect Service Applications with Dev Services and Testing OpenID Connect WebApp Applications with Dev Services.
Keycloak 初期化
The quay.io/keycloak/keycloak:25.0.6
image which contains a Keycloak distribution powered by Quarkus is used to start a container by default.
quarkus.keycloak.devservices.image-name
can be used to change the Keycloak image name.
For example, set it to quay.io/keycloak/keycloak:19.0.3-legacy
to use a Keycloak distribution powered by WildFly.
Be aware that a Quarkus-based Keycloak distribution is only available starting from Keycloak 20.0.0
.
Dev Services for Keycloakは、起動したKeycloakサーバーを次に初期化します。
デフォルトでは、パスワードが secret
の quarkus
および quarkus-app
クライアント、alice
および bob
ユーザー (パスワードは名前と同じ)、user
および admin
ロールが作成されます。このとき、alice
には admin
と user
の両方のロールが与えられ、bob
には user
ロールが与えられます。
ユーザー名、シークレット、およびそれらのロールは、quarkus.keycloak.devservices.users
(ユーザー名とシークレットを含むマップ) および quarkus.keycloak.devservices.roles
(ユーザー名とコンマ区切りのロール値を含むマップ) でカスタマイズできます。
例:
%dev.quarkus.keycloak.devservices.users.duke=dukePassword
%dev.quarkus.keycloak.devservices.roles.duke=reader
%dev.quarkus.keycloak.devservices.users.john=johnPassword
%dev.quarkus.keycloak.devservices.roles.john=reader,writer
この設定により、2人のユーザーが作成されます:
* dukePassword
パスワードと reader
ロールを持つ duke
* johnPassword
パスワードと reader
および writer
ロールを持つ john
クライアント ID とシークレットをカスタマイズするには、quarkus.oidc.client-id
プロパティーと quarkus.oidc.credentials.secret
プロパティーを使用できます。
ただし、Keycloak の設定がより複雑になり、より多くのプロパティーの設定が必要になる可能性があります。
このため、Keycloak をデフォルトまたは設定されたレルム、クライアント、ユーザー、およびロールのプロパティーで初期化する前に、常に quarkus.keycloak.devservices.realm-path
がチェックされます。
realm ファイルがファイルシステムまたはクラスパス上に存在する場合、この realm だけが Keycloak を初期化するために使用されます。次に例を示します。
quarkus.keycloak.devservices.realm-path=quarkus-realm.json
quarkus.keycloak.devservices.realm-path
を使って、カンマで区切られたファイルのリストを提供することで、複数のレルムファイルでKeycloakを初期化することができます:
quarkus.keycloak.devservices.realm-path=quarkus-realm1.json,quarkus-realm2.json
また、Keycloak ページには、右上隅にある Keycloak Admin オプションを使用して、Keycloak にサインインしてレルムを設定するオプション (Sign In To Keycloak To Configure Realms
) があります。
レルムのプロパティーのカスタマイズ、新規レルムの作成またはインポート、レルムのエクスポートを実行するには、Keycloak に admin:admin
としてサインインします。
クラスパスとファイルシステムリソースをコンテナーにコピーすることもできます。
たとえば、jar ファイルで Keycloak にデプロイされる JavaScript ポリシー を使用してアプリケーションが Keycloak 認証を設定する場合、次のようにしてこの jar を Keycloak コンテナーにコピーするように Dev Services for Keycloak
を設定できます。
quarkus.keycloak.devservices.resource-aliases.policies=/policies.jar (1)
quarkus.keycloak.devservices.resource-mappings.policies=/opt/keycloak/providers/policies.jar (2)
1 | クラスパス /policies.jar リソースに対して policies エイリアスが作成されます。 |
ポリシー jar はファイルシステム内に配置することもできます。
<2> ポリシー jar は、/opt/keycloak/providers/policies.jar
コンテナーの場所にマップされます。
Dev Services for Keycloak を無効にする
quarkus.oidc.auth-server-url
がすでに初期化されているか、デフォルトの OIDC テナントが quarkus.oidc.tenant.enabled=false
で無効になっている場合、Keycloak を使用するかどうかにかかわらず、Dev Services For Keycloak
はアクティブ化されません。
Dev Services for Keycloak コンテナーを起動させない、または使用しない場合も、quarkus.keycloak.devservices.enabled=false
を使用してこの機能を無効化できます。これは、quarkus.oidc.auth-server-url
なしで quarkus:dev
を起動する予定がある場合にのみ必要です。
Dev Services for Keycloak が無効になっていて、quarkus.oidc.auth-server-url
プロパティーが初期化されていない場合、メインの Dev UI ページに空の OpenID Connect カードが表示されます。
quarkus.oidc.auth-server-url
がすでに設定されている場合は、すべての OpenID Connect プロバイダーで使用できる汎用の OpenID Connect Dev Console をアクティブ化できます。詳細は、Dev UI for all OpenID Connect providers セクションを参照してください。
すべてのOpenID ConnectプロバイダーのためのDev UI
以下の条件を満たす場合、すべての OpenID Connect プロバイダーの Dev UI が有効になります:
-
quarkus.oidc.auth-server-url
が、すでに起動している OpenID Connect プロバイダー (Keycloak またはその他のプロバイダー) を指している。 -
quarkus.oidc.application-type
が、デフォルト値のservice
またはhybrid
に設定されている。 -
quarkus.oidc.client-id
が設定されている。
quarkus.oidc.client-id
で識別されるクライアントが OpenID Connect プロバイダーの管理コンソールで public クライアントとして設定されていない限り、Dev UI から開始された認可コードフローを完了するには、おそらく Keycloak やその他のプロバイダーで quarkus.oidc.credentials.secret
を設定する必要があります。
たとえば、Dev UI を使用して、次の設定で Google 認証をテストできます。
quarkus.oidc.provider=google
quarkus.oidc.application-type=hybrid
quarkus.oidc.client-id=${google-client-id}
quarkus.oidc.credentials.secret=${google-client-secret}
以下を実行します。
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
このコマンドは、次の例のようなメッセージを出力します。
...
2021-09-07 15:53:42,697 INFO [io.qua.oid.dep.dev.OidcDevConsoleProcessor] (build-41) OIDC Dev Console: discovering the provider metadata at https://accounts.google.com/.well-known/openid-configuration
...
プロバイダーメタデータの検出が成功した場合、メインの Dev UI ページ を開くと、Google
プロバイダーを参照する次の OpenID Connect カードが表示されます。
リンクをたどってプロバイダーにログインし、トークンを取得して、アプリケーションをテストします。
特に Keycloakを使用している場合、これは Dev Services for Keycloak
コンテナーを起動した Authorization code grant for Keycloak セクションの説明のとおりです。
多くの場合、Dev Console
へのリダイレクトをサポートするように OpenID Connect プロバイダーを設定する必要があります。
http://localhost:8080/q/dev-ui/io.quarkus.quarkus-oidc/<providerName>-provider
を、サポートされているリダイレクトおよびログアウト URL の 1 つとして追加します。<providerName> ` は、Dev UI に表示されるプロバイダーの名前 (例: `auth0
) に置き換える必要があります。
他のプロバイダーを使用している場合、Authorization code grant for Keycloak で説明されている Dev UI のエクスペリエンスが若干異なる場合があります。 たとえば、アクセストークンが JWT 形式でない場合、その内部コンテンツを表示できません。 ただし、すべてのプロバイダーが JWT 形式で ID トークンを返すはずです。
現在のアクセストークンは、Swagger UI または GrapghQL UI でサービスをテストするためにデフォルトで使用されます。
プロバイダー (Keycloak 以外) がバイナリーアクセストークンを返す場合、このプロバイダーにトークンイントロスペクションエンドポイントがある場合にのみ、Swagger UI または GrapghQL UI で使用されます。それ以外の場合は、常に JWT 形式の |
Auth0
などの一部のプロバイダーは、標準の RP 起点のログアウトをサポートしていないため、ログアウトオプションを表示するには、プロバイダー固有のログアウトプロパティーを設定する必要があります。
詳細は、「Web アプリケーションを保護するための OpenID Connect 認可コードフローメカニズム」ガイドの ユーザー起点のログアウト セクションを参照してください。
同様に、Dev UI に password
または client_credentials
グラントを使用してトークンを取得する場合は、プロバイダー固有の追加のプロパティーを設定する必要がある場合があります。次に例を示します。
quarkus.oidc.devui.grant.type=password
quarkus.oidc.devui.grant-options.password.audience=http://localhost:8080
アプリケーション以外のルートパスに関する考慮事項
このドキュメントでは、いくつかの場所で Dev UI URL を http://localhost:8080/q/dev-ui
と表記しています。q
は、デフォルトのアプリケーション以外のルートパスです。
quarkus.http.root-path
または quarkus.http.non-application-root-path
プロパティーをカスタマイズする場合は、それに応じて q
を置き換えてください。
詳細は、ブログ記事の Path resolution in Quarkus を参照してください。