OpenID Connect (OIDC) の開発サービスおよび UI
このガイドでは、OpenID Connect(OIDC)のKeycloakプロバイダのDev ServicesとUIを取り上げ、他のOpenID ConnectプロバイダのDevサービスとUIをサポートする方法について説明します。また、Quarkusを開発モードで起動する前にすでに開始されているすべてのOpenID ConnectプロバイダのDev UIについても説明しています。
はじめに
Quarkus provides Dev Services For Keycloak
feature which is enabled by default when the quarkus-oidc
extension is started in dev mode and when the integration tests are running in test mode, but only when no quarkus.oidc.auth-server-url
property is configured. It starts a Keycloak container for both the dev and/or test modes and initializes them by registering the existing Keycloak realm or creating a new realm with the client and users for you to start developing your Quarkus application secured by Keycloak immediately. It will restart the container when the application.properties
or the realm file changes have been detected.
さらに、 /q/dev で入手可能な Dev UI は、Dev UI ページでこの機能を補完します。これは、Keycloak からトークンを取得して Quarkus アプリケーションをテストする際に役立ちます。
quarkus.oidc.auth-server-url
が設定されている場合、すべての OpenID Connect プロバイダーで使用できる一般的な OpenID Connect Dev Console が有効になります。詳細は、 すべての OpenID Connect プロバイダーの Dev UI を参照してください。
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.
...
It is possible that the Keycloak container does not become ready before the default timeout of 60 seconds. A simple way to overcome the issue is to increase the time out - for example to 2 minutes - using |
quarkus.keycloak.devservices.shared=false
でコンテナーの共有を無効にできることに注意してください。
次に、メインの Dev UI ページ を開くと、OpenID Connect Card
が Keycloak のページにリンクしているのが確認できます。

Provider: Keycloak
リンクをクリックすると、Keycloak ページが表示されます。このページは、Dev ServicesforKeycloak
機能がどのように設定されているかによって少し異なります。
サービスアプリケーションの開発
By default, the Keycloak page can be used to support the development of a Quarkus OIDC service application.
認可コード グラント
application.properties
で quarkus.oidc.devui.grant.type=code
(デフォルト値) を設定すると、authorization_code
グラントを使用してアクセストークンと ID トークンの両方が取得されます。 Single Page Application
がトークンを取得し、Quarkusサービスにアクセスする典型的なフローをエミュレートするために、このグラントを使用することが推奨されます。
まず、Log into Single Page Application
オプションが表示されます。

認証プロセスで使用されるKeycloakレルムとクライアントIDを選択します。
このSPAは、OpenId Connectのpublicクライアントを表しています。したがって、入力するクライアントIDは、シークレットのないKeycloakのpublicクライアントを指す必要があります。これは、SPAがウェブアプリケーションではないため、認可コードフローを完了するために必要なクライアントシークレットを安全に扱うことができないためです。 シークレットが必要なクライアントは、デフォルトのレルムが作成されている場合、または |
次に、 Log into Single Page Application
を選択すると、Keycloakにリダイレクトされ、例えば、 alice:alice
として認証され、SPAを表すページに戻ります:

取得したアクセストークンやIDトークンなどを確認することができます。

このビューでは、左側にエンコードされた JWT トークンが表示され、ヘッダー (赤色)、ペイロード/クレーム (緑色)、および署名 (青色) が強調表示されます。また、右側にデコードされた JWT トークンが表示され、ヘッダーとクレームの名前とその値を確認できます。
次に、相対サービスパスを入力し、トークンを送信してサービスをテストします。SPAは通常、アプリケーションのエンドポイントにアクセストークンを送信するので、例えば、 Test with Access Token
のオプションを選択します:

右下の eraser
のマークで、テスト結果エリアをクリアすることができます。
エンドポイントがSPAに現在ログインしているユーザーを認識するため、または帯域外のトークン検証を実行するために、IDトークンがベアラートークンとしてアプリケーションフロントエンドに転送されることがあります。このような場合は、 Test with ID Token
オプションを選択してください。
手動でサービスパスを入力するのは理想的ではありませんので、OIDC Dev UIですでに取得したアクセストークンを使ってサービスをテストするためのSwaggerまたはGraphQL UIの有効化については Swagger UIまたはGraphQL UIによるテスト の項をご覧ください。
最後に、ログアウトして別のユーザーとして Keycloak で認証する場合は、Log Out
image::dev-ui-keycloak-logout.png オプションを選択できます。
シングルページアプリケーションにログインしようとすると、Keycloak がエラーを返す場合があることに注意してください。たとえば、quarkus.oidc.client-id
が Keycloak にインポートされたレルムのクライアント ID と一致しない場合や、このレルムのクライアントが認可コードフローをサポートするように正しく設定されていない場合などです。このような場合、Keycloak は error_description
クエリーパラメーターと DevUI
も、このエラーの説明を表示します。以下はその例です。

エラーが発生した場合は、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
が開き、Dev UI for Keycloak が取得したトークンを使用してサービスをテストできます。 Swagger UI
は再認証を試みません。OIDC Dev UIが認証を行い、Swagger UIがテストに使用するアクセストークンを提供しているため、Swagger UIに入った後は Swagger UI
Authorize
オプションを選択しないようにしてください。
GraphQL UI
との統合も同様に機能し、Keycloak 用に Dev UI によって取得されたアクセストークンが使用されます。
Keycloak は、認証されたユーザーが設定されたリダイレクト URI にのみリダイレクトされるように強制する場合があるため、Keycloak が機能するためには Dev UI によって開始される認可コードフローのリダイレクト URI を登録する必要がある場合があります。認証要求内の正しい Keycloak がそれを強制する場合は、 In this case select the コンテナーが異なるポートで実行されている複数のアプリケーション間で共有されている場合は、これらのアプリケーションごとに 特にコンテナーが複数のアプリケーション間で共有されている場合は、テスト目的でのみ カスタムレルムがインポートされていない場合、 |
インプリシット・グラント
application.properties
で quarkus.oidc.devui.grant.type=implicit
を設定すると、アクセストークンと ID トークンの両方を取得するために implicit
グラントが使用されます。認可コードグラントが機能しない場合に限り (暗示的グラントをサポートするためにクライントが Keycloak に設定されている場合など)、このグラントを使用して Single Page Application
をエミュレートします。
パスワード・グラント
application.properties
で quarkus.oidc.devui.grant.type=password
を設定すると、次のような画面が表示されます。

レルムを選択し、クライアントIDとシークレット、ユーザー名とユーザーパスワード、サービスのエンドポイントの相対パスを入力し、 Test Service
をクリックすると、 200 `, `403 `, `401
または 404
のようなステータスコードが表示されます。ユーザー名とパスワードを含む quarkus.keycloak.devservices.users
マッププロパティにユーザー名も設定されている場合は、サービスをテストする際にパスワードを設定する必要はありません。ただし、パスワードグラントを使用してサービスをテストするために、 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 Web アプリケーションの開発
If you develop a Quarkus OIDC web-app application, then you should set quarkus.oidc.application-type=web-app
in application.properties
before starting the application.
次のような画面が表示されます。

相対的なサービスエンドポイントパスを設定し、Sign In To Service
をクリックすると Keycloak にリダイレクトされます。新しいブラウザータブにユーザー名とパスワードを入力し、Quarkus アプリケーションからレスポンスを取得します。
この場合、Dev UI は認可コードフローを制御してトークンを取得する Quarkus OIDC の web-app
アプリケーションであるため、開発エクスペリエンスを充実させるものではないことに注意してください。
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
これにより、 web-app
アプリケーションを dev モードで実行したときに、 OpenID Connectサービスアプリケーション開発 で説明したすべての Dev UI オプションが利用できるようになります。このアプローチの限界は、コードフローで返却され、Dev UIで取得されたアクセストークンとIDトークンの両方がHTTP Bearer
トークンとしてエンドポイントに送信されることです。これは、エンドポイントが IdToken
の注入を必要とする場合にはうまく機能しません。しかし、 web-app
アプリケーションが、例えば、ロールソースとして、または UserInfo
を得るためにアクセストークンを使用するだけの場合は期待通りに機能します。たとえそれが開発モードの service
アプリケーションと想定されていた場合でもです。
さらに良いオプションは、devmode で「ハイブリッド」アプリケーション タイプを使用することです:
%prod.quarkus.oidc.application-type=web-app
%test.quarkus.oidc.application-type=web-app
%dev.quarkus.oidc.application-type=hybrid
これにより、OIDC DevUI を使用せずにブラウザーから開発モードでアプリケーションにアクセスすると、Quarkus OIDC もプロダクション モードと同様に認可コード フローを実行するようになります。 しかし、 hybrid
アプリケーションはベアラー アクセス トークンも受け入れることができるため、OIDC DevUI もより便利になります。
テストの実行
テストモードで起動した Keycloak コンテナーに対して、継続テスト モードでテストを実行できます。
It is also recommended to run the integration tests against Keycloak using Dev Services for Keycloak
. For more information, see Testing OpenID onnect Service Applications with Dev Services and Testing OpenID Connect WebApp Applications with Dev Services.
Keycloak 初期化
The quay.io/keycloak/keycloak:22.0.1
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. Note that only a Quarkus based Keycloak distribution is available starting from Keycloak 20.0.0
.
Dev Services for Keycloak
は、起動された Keycloak サーバーを次に初期化します。
デフォルトでは、quarkus
、secret
パスワードを持つ 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
quarkus.oidc.client-id
と quarkus.oidc.credentials.secret
を使用して、クライアント ID とシークレットをカスタマイズできます。
ただし、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 ページには、右上隅にある KeycloakAdmin
オプションを使用して、Keycloak にサインインしてレルムを設定 (SignIn To Keycloak To Configure Realms
) するオプションがあります。

レルムのプロパティーのカスタマイズ、新規レルムの作成またはインポート、レルムのエクスポートを実行するには、Keycloak に admin:admin
としてサインインします。
Keycloak の Dev サービスを無効にする
quarkus.oidc.auth-server-url
がすでに初期化されているか、デフォルトの OIDC テナントが quarkus.oidc.tenant.enabled=false
で無効になっている場合、Keycloak を使用するかどうかにかかわらず、Dev Services ForKeycloak
はアクティブ化されません。
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 ページには空の OpenIDConnectCard
が含まれます。

quarkus.oidc.auth-server-url
が設定されている場合、すべての OpenID Connect プロバイダーで使用できる一般的な OpenID Connect Dev Console が有効になります。詳細については、 すべての OpenID Connect プロバイダーの Dev UI を参照してください。
すべての OpenID Connect プロバイダーの Dev UI
If quarkus.oidc.auth-server-url
points to an already started OpenID Connect provider (which can be Keycloak or other provider), quarkus.oidc.auth-server-url
is set to service
(which is a default value) or hybrid
and at least quarkus.oidc.client-id
is set then Dev UI for all OpenID Connect Providers
will be activated.
Keycloak や その他のプロバイダーでは、quarkus.oidc.client-id
で指定されたクライアントが使用している OpenID Connect プロバイダーの管理コンソールでパブリッククライアントとして設定されていない限り、Dev UI から開始された認可コードフローを完了するには`quarkus.oidc.credentials.secret` の設定が必要です。
For example, you can use Dev UI to test Google authentication with this configuration:
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
...
If the provider metadata discovery has been successful then, after you open the main Dev UI page, you will see the following OpenID Connect Card
referencing a Google
provider:

リンクをたどると、プロバイダにログインしてトークンを取得し、アプリケーションをテストできるようになります。特にKeycloakと連携している場合は、 Dev Services for Keycloak
コンテナが開始された Keycloakの認可コードグラント のセクションで説明したような体験ができるはずです。
You will most likely need to configure your OpenId Connect provider to support redirecting back to the Dev Console
. Add http://localhost:8080/q/dev-ui/io.quarkus.quarkus-oidc/`providerName
-provider` as one of the supported redirect and logout URLs, where providerName
will need to be replaced by the name of the provider shown in DevUI, for example, auth0
.
他のプロバイダーと連携している場合、 Keycloakの認可コードグラント のセクションで説明したDev UI体験は若干異なるかもしれません。例えば、アクセストークンはJWT形式ではないため、その内部コンテンツを表示することはできませんが、すべてのプロバイダーはIDトークンをJWTとして返すはずです。
デフォルトでは、現在のアクセストークンを使用して、 |
Some providers such as Auth0
do not support a standard RP initiated logout so the provider specific logout properties will have to be configured for a logout option be visible. For more information, see OpenID Connect User-Initiated Logout.
同様に、Dev UI に password
または client_credentials
グラントを使用してトークンを取得する場合は、次のような追加のプロバイダー固有プロパティーを設定する必要があります。
quarkus.oidc.devui.grant.type=password
quarkus.oidc.devui.grant-options.password.audience=http://localhost:8080
その他の OpenID Connect プロバイダーの Dev Services と UI サポート
カスタムエクステンションは、quarkus-oidc
を拡張し、プロバイダーをサポートするために必要な依存関係をエクステンションの deployment
モジュールにのみ追加する必要があります。
Dev Services
を処理するビルドステップでは、OpenID Connect Card
をプロバイダーを示す Dev UI ページにリンクするために、2 つのランタイムプロパティーを "io.quarkus.quarkus-oidc" 名前空間に追加で登録する必要があります: oidcProviderName
(例: Google
) と oidcProviderUrlBase
(例: mycompany.devservices-google
)。
package io.quarkus.oidc.okta.runtime;
import java.util.function.Supplier;
import io.quarkus.runtime.annotations.Recorder;
// This simple recorder is the only code which will be located in the extension's `runtime` module
@Recorder
public class OktaDevServicesRecorder {
public Supplier<String> getProviderName() {
return new Supplier<String>() {
@Override
public String get() {
return "OKTA";
}
};
}
public Supplier<String> getProviderUrlBase() {
return new Supplier<String>() {
@Override
public String get() {
return "io.quarkus" + "." + "quarkus-oidc-okta";
}
};
}
}
package io.quarkus.oidc.okta.deployment.devservices;
import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT;
import java.util.Optional;
import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Consume;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem;
import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem;
import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem;
public class OktaDevConsoleProcessor {
@BuildStep(onlyIf = IsDevelopment.class)
@Record(value = RUNTIME_INIT)
public void setOidcProviderProperties(BuildProducer<DevConsoleRuntimeTemplateInfoBuildItem> provider,
OktaDevServicesRecorder recorder,
Optional<DevServicesConfigBuildItem> configProps) {
if (configProps.isPresent()) {
provider.produce(new DevConsoleRuntimeTemplateInfoBuildItem("io.quarkus", "quarkus-oidc", "oidcProviderName",
recorder.getProviderName()));
provider.produce(new DevConsoleRuntimeTemplateInfoBuildItem("io.quarkus", "quarkus-oidc", "oidcProviderUrlBase",
recorder.getProviderUrlBase()));
}
}
}
さらに、ユーザーが quarkus.keycloak.devservices.enabled=false
を入力するのではなく、エクステンションが io.quarkus.oidc.deployment.devservices.OidcProviderBuildItem
を生成してデフォルトの Dev Services for Keycloak
を無効にする必要があります。
Dev UI チュートリアルと extensions/oidc/deployment
ソースで他のアイデアも確認してください。
アプリケーション以外のルートパスに関する考慮事項
本ドキュメントでは、様々な場所でDev UI URLを以下のように表記しています: http://localhost:8080/q/dev-v1
。 q
はデフォルトの非アプリケーションルートパスです。 quarkus.http.root-path
や quarkus.http.non-application-root-path
のプロパティをカスタマイズした場合は、それに応じて q
を置き換えて下さい。詳細は Quarkusのパス解決 を参照してください。