用于 OpenID Connect (OIDC) 的 Dev Services 和 Dev UI
你可以使用 Keycloak 的开发服务和 OpenID Connect (OIDC) Keycloak 提供程序的开发 UI,并将这些服务适配于其他 OpenID Connect 提供程序。你还可以将开发 UI 与在以开发模式运行 Quarkus 之前已经启动的 OpenID Connect 提供程序一起使用。
简介
Quarkus 提供了 Keycloak 的开发服务功能,当 quarkus-oidc
扩展在开发模式下启动、集成测试在测试模式下运行,并且没有配置 quarkus.oidc.auth-server-url
属性时,该功能默认启用。Keycloak 的开发服务功能会为开发和测试模式启动 Keycloak 容器。它通过注册现有的 Keycloak 域或创建一个新的域来初始化它们,其中包含你立即开始开发由 Keycloak 保护的 Quarkus 应用程序所需的客户端和用户。当检测到 application.properties
或域文件更改时,容器会重新启动。
此外,开发 UI 在 /q/dev-ui/extensions 上可用,它通过开发 UI 页面补充了此功能,该页面有助于从 Keycloak 获取令牌并测试你的 Quarkus 应用程序。
如果已经设置了 quarkus.oidc.auth-server-url
,则会激活一个通用的 OpenID Connect 开发控制台,该控制台可以与所有 OpenID Connect 提供程序一起使用。有关更多信息,请参见 所有 OpenID Connect 提供程序的开发 UI。
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: https://: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 管理控制台时,用户名是 |
请注意,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
来关闭容器的共享。
现在,打开主要的 开发 UI 页面 并观察链接到 Keycloak 页面的 OpenID Connect 卡片。例如

单击 Keycloak provider 链接。此操作会打开一个 Keycloak 页面,其外观取决于 Keycloak 的开发服务功能的配置方式。
开发服务应用程序
默认情况下,Keycloak 页面可用于支持 Quarkus OIDC 服务应用程序 的开发。
授权码授予
如果在 application.properties
文件中设置 quarkus.oidc.devui.grant.type=code
(这是默认值),则 authorization_code
授予用于获取访问令牌和 ID 令牌。建议使用此授予来模拟典型流程,其中单页应用程序 (SPA) 获取令牌并使用它们来访问 Quarkus 服务。
首先,你将看到一个选项 Log into Single Page Application。例如

选择在身份验证过程中使用的 Keycloak 域和客户端 ID。
此 SPA 代表一个公共 OpenID Connect 客户端;因此,你输入的客户端 ID 必须标识没有密钥的公共 Keycloak 客户端。这是因为 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 选项。
当你导入自定义 Keycloak 域时,你可能会发现在 Dev UI 中检查访问令牌和 ID 令牌后,只有访问令牌的 有关更多信息,请参见 Keycloak 服务器管理指南。 |
手动输入服务路径并不理想。有关启用 Swagger 或 GraphQL UI 以使用 OIDC Dev UI 已经获取的访问令牌测试服务的信息,请参见 使用 Swagger UI 或 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,你可以在其中使用 Dev UI for Keycloak 获取的令牌测试服务。Swagger UI 不会尝试再次重新身份验证。在 Swagger UI 中,不要选择 Swagger UI Authorize
选项;OIDC Dev UI 已经授权并提供了访问令牌供 Swagger UI 用于测试。
与 GraphQL UI 的集成类似地工作;使用 Dev UI for Keycloak 获取的访问令牌。
你可能需要为 Dev UI for Keycloak 发起的授权码流程注册重定向 URI。这是因为 Keycloak 可能会强制要求经过身份验证的用户只能重定向到配置的重定向 URI。建议在生产环境中执行此操作,以避免用户被重定向到错误的端点,如果身份验证请求 URI 中的正确 如果 Keycloak 强制执行此操作,你将看到一个身份验证错误,通知你 在这种情况下,选择右上角的 Keycloak Admin 选项,以 如果容器在运行在不同端口上的多个应用程序之间共享,则必须为每个应用程序注册 你只能出于测试目的将 如果没有导入自定义域,Dev Services for Keycloak 会在创建默认域时将 |
隐式授予
如果在 application.properties
文件中设置 quarkus.oidc.devui.grant.type=implicit
,则 implicit
授予用于获取访问令牌和 ID 令牌。仅当授权码授予不起作用时,才使用此授予来模拟单页应用程序;例如,当客户端在 Keycloak 中配置为支持隐式授予时。
密码授予
如果在 application.properties
文件中设置 quarkus.oidc.devui.grant.type=password
,则会看到类似于此屏幕的屏幕

选择一个域,输入客户端 ID 和密码,用户名和密码,相对服务端点路径,然后单击 Test service。它返回一个状态代码,例如 200
、403
、401
或 404
。如果用户名也设置在包含用户名和密码的 quarkus.keycloak.devservices.users
映射属性中,则在测试服务时不必设置密码。请注意,你不必初始化 quarkus.keycloak.devservices.users
以使用 password
授予测试服务。
在 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 'https://: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 'https://: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 应用程序
要开发 Quarkus OIDC Web 应用程序,请在启动应用程序之前在 application.properties
文件中设置 quarkus.oidc.application-type=web-app
。
启动应用程序会显示类似于此屏幕的屏幕

设置一个相对服务端点路径,然后单击 Log in to your web application。你将被重定向到 Keycloak 以在新浏览器选项卡中输入用户名和密码,然后才能从 Quarkus 应用程序获得响应。
运行测试
你可以在 持续测试 模式下针对在测试模式下启动的 Keycloak 容器运行测试。
还建议使用 Keycloak 的开发服务针对 Keycloak 运行集成测试。有关更多信息,请参见 使用开发服务测试 OpenID Connect 服务应用程序 和 使用开发服务测试 OpenID Connect WebApp 应用程序。
Keycloak 初始化
默认情况下,包含由 Quarkus 提供支持的 Keycloak 发行版的 quay.io/keycloak/keycloak:26.2.4
映像用于启动容器。quarkus.keycloak.devservices.image-name
可用于更改 Keycloak 映像名称。例如,将其设置为 quay.io/keycloak/keycloak:19.0.3-legacy
以使用由 WildFly 提供支持的 Keycloak 发行版。请注意,基于 Quarkus 的 Keycloak 发行版仅从 Keycloak 20.0.0
开始提供。
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
此配置创建两个用户:* 具有 dukePassword
密码和 reader
角色的 duke
* 具有 johnPassword
密码以及 reader
和 writer
角色的 john
要自定义客户端 ID 和密码,你可以使用 quarkus.oidc.client-id
和 quarkus.oidc.credentials.secret
属性。
但是,你的 Keycloak 配置可能更复杂,需要设置更多属性。
这就是为什么在用默认或配置的域、客户端、用户和角色属性初始化 Keycloak 之前,始终检查 quarkus.keycloak.devservices.realm-path
的原因。如果域文件存在于文件系统或类路径上,则仅使用此域来初始化 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 选项 Sign In To Keycloak To Configure Realms

以 admin:admin
身份登录到 Keycloak 以进一步自定义域属性,创建或导入新域,或导出域。
你还可以将类路径和文件系统资源复制到容器。例如,如果你的应用程序使用 JavaScript 策略 配置 Keycloak 授权,这些策略部署到 jar 文件中的 Keycloak,那么你可以配置 Dev Services for Keycloak
将此 jar 复制到 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
容器位置。
禁用 Keycloak 的开发服务
如果 quarkus.oidc.auth-server-url
已经初始化或默认 OIDC 租户已禁用 quarkus.oidc.tenant.enabled=false
,则 Keycloak 的开发服务不会激活,无论你是否使用 Keycloak。
如果你不想启动 Keycloak 的开发服务容器,或者不使用 Keycloak,你也可以使用 quarkus.keycloak.devservices.enabled=false
禁用此功能 - 只有当你希望在没有 quarkus.oidc.auth-server-url
的情况下启动 quarkus:dev
时才需要这样做。
当禁用 Keycloak 的开发服务并且尚未初始化 quarkus.oidc.auth-server-url
属性时,主 Dev UI 页面包含一个空的 OpenID Connect 卡片

如果已经设置了 quarkus.oidc.auth-server-url
,则可以激活通用的 OpenID Connect 开发控制台,该控制台可以与所有 OpenID Connect 提供程序一起使用。有关更多信息,请参见 所有 OpenID Connect 提供程序的开发 UI 部分。
所有 OpenID Connect 提供程序的开发 UI
如果满足以下条件,则会激活所有 OpenID Connect 提供程序的开发 UI
-
quarkus.oidc.auth-server-url
指向已经启动的 OpenID Connect 提供程序,可以是 Keycloak 或其他提供程序。 -
quarkus.oidc.application-type
设置为service
(默认值)或hybrid
。 -
设置了
quarkus.oidc.client-id
。
对于 Keycloak 和其他提供程序,最有可能需要设置 quarkus.oidc.credentials.secret
,以便完成从 Dev UI 发起的授权码流程,除非使用 quarkus.oidc.client-id
标识的客户端在 OpenID Connect 提供程序的管理控制台中配置为公共客户端。
例如,你可以使用 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://#/.well-known/openid-configuration
...
如果提供程序元数据发现成功,那么在你打开主要的 Dev UI 页面 后,你可以看到引用 Google
提供程序的以下 OpenID Connect 卡片

按照链接登录到你的提供程序,获取令牌并测试应用程序。体验与 Keycloak 的授权码授予 部分中描述的相同,其中已经启动了 Keycloak 的开发服务容器,特别是如果你使用 Keycloak。
你可能需要配置你的 OpenID Connect 提供程序以支持重定向回 Dev Console
。你需要添加 https://:8080/q/dev-ui/io.quarkus.quarkus-oidc/<providerName>-provider
作为支持的重定向和注销 URL 之一,其中 <providerName>
必须替换为 Dev UI 中显示的提供程序的名称,例如,auth0
。
Keycloak 的授权码授予 部分中描述的 Dev UI 体验可能略有不同,如果你使用其他提供程序。例如,访问令牌可能不是 JWT 格式,因此无法显示其内部内容。但是,所有提供程序都应以 JWT 格式返回 ID 令牌。
默认情况下,当前访问令牌用于使用 Swagger UI 或 GrapghQL UI 测试服务。如果提供程序(Keycloak 以外)返回二进制访问令牌,则仅当此提供程序具有令牌自检端点时,才将其与 Swagger UI 或 GrapghQL UI 一起使用;否则,将 |
某些提供程序(例如 Auth0
)不支持标准的 RP 发起的注销,因此必须为提供程序特定的注销属性配置,才能使注销选项可见。有关更多信息,请参见 "保护 Web 应用程序的 OpenID Connect 授权码流程机制" 指南中的 用户发起的注销 部分。
同样,如果你想使用 password
或 client_credentials
授予 Dev UI 来获取令牌,你可能需要配置一些额外的提供程序特定属性,例如
quarkus.oidc.devui.grant.type=password
quarkus.oidc.devui.grant-options.password.audience=https://:8080
非应用程序根路径注意事项
本文档在多个位置引用了 https://:8080/q/dev-ui
Dev UI URL,其中 q
是默认的非应用程序根路径。如果你自定义 quarkus.http.root-path
或 quarkus.http.non-application-root-path
属性,请相应地替换 q
。有关更多信息,请参见 Quarkus 中的路径解析 博客文章。
OIDC 的开发服务
当你在生产中使用 Keycloak 时,Keycloak 的开发服务 提供了最佳的开发模式体验。对于其他 OpenID Connect 提供程序,建议像下面的示例中那样启用 OIDC 的开发服务
quarkus.oidc.devservices.enabled=true
如果 Docker 和 Podman 不可用,则默认启用 OIDC 的开发服务。 |
启用后,Quarkus 会启动一个新的 OIDC 服务器,该服务器支持最常见的 OpenID Connect 操作。你可以在控制台中确认 OIDC 服务器已启动,你将看到类似于以下的输出
2025-01-08 20:50:20,900 INFO [io.qua.dev.oid.OidcDevServicesProcessor] (build-16) Dev Services for OIDC started on https://:38139
如果你导航到 所有 OpenID Connect 提供程序的开发 UI,你可以作为内置用户 alice
或 bob
登录到 OIDC 服务器

如果在开发 Quarkus OIDC Web 应用程序 期间导航到经过身份验证的请求路径,也会显示此登录页面。与往常一样,alice
的默认角色是 admin
和 user
,而 bob
的角色只是 user
。如果需要,你可以配置那些内置角色
quarkus.oidc.devservices.roles.alice=root (1)
quarkus.oidc.devservices.roles.bob=guest
1 | 将 root 角色分配给用户 alice 。 |
另一种选择是以你选择的用户名和角色作为自定义用户登录

无论你选择哪个用户,都不需要密码。
配置参考
构建时固定的配置属性 - 所有其他配置属性都可以在运行时覆盖
配置属性 |
类型 |
默认 |
---|---|---|
用于启用(默认)或禁用开发服务的标志。启用后,Keycloak 的开发服务会在开发或测试模式下自动配置并启动 Keycloak,并且在 Docker 运行时。 环境变量: 显示更多 |
布尔值 |
|
开发服务提供程序的容器映像名称。默认为基于 Quarkus 的 Keycloak 映像。对于基于 WildFly 的发行版,请使用类似于 环境变量: 显示更多 |
字符串 |
|
指示是否使用 Keycloak-X 映像。默认情况下,映像由映像名称中的 环境变量: 显示更多 |
布尔值 |
|
确定是否共享 Keycloak 容器。共享后,Quarkus 使用基于标签的服务发现来查找和重用正在运行的 Keycloak 容器,因此不会启动第二个容器。否则,如果未找到匹配的容器,则会启动一个新容器。服务发现使用 环境变量: 显示更多 |
布尔值 |
|
用于标识 Keycloak 容器的 环境变量: 显示更多 |
字符串 |
|
Keycloak 域文件的类或文件系统路径的逗号分隔列表。此列表用于初始化 Keycloak。此列表中的第一个值用于初始化默认租户连接属性。 要了解有关 Keycloak 域文件的更多信息,请参阅 导入和导出 Keycloak 域文档。 环境变量: 显示更多 |
字符串列表 |
|
用于初始化 Keycloak 的其他类或文件系统资源的别名。每个映射条目表示别名与类或文件系统资源路径之间的映射。 环境变量: 显示更多 |
Map<String,String> |
|
用于初始化 Keycloak 的其他类或文件系统资源。每个映射条目表示类或文件系统资源路径别名与 Keycloak 容器位置之间的映射。 环境变量: 显示更多 |
Map<String,String> |
|
传递给 keycloak JVM 的 环境变量: 显示更多 |
字符串 |
|
显示带有 "Keycloak:" 前缀的 Keycloak 日志消息。 环境变量: 显示更多 |
布尔值 |
|
Keycloak 启动命令。使用此属性来试验 Keycloak 启动选项,请参见 环境变量: 显示更多 |
字符串 |
|
Keycloak 功能。使用此属性启用一个或多个实验性 Keycloak 功能。请注意,如果你还必须自定义 Keycloak 环境变量: 显示更多 |
字符串列表 |
|
Keycloak 域的名称。如果 环境变量: 显示更多 |
字符串 |
|
指定当在 环境变量: 显示更多 |
布尔值 |
|
指定如果 环境变量: 显示更多 |
布尔值 |
|
指定即使默认 OIDC 租户已禁用也是否启动容器。在多租户 OIDC 设置中,尤其是动态创建 OIDC 租户时,可能需要将此属性设置为 true。 环境变量: 显示更多 |
布尔值 |
|
一个 Keycloak 用户名到密码的映射。如果为空,将创建默认用户 环境变量: 显示更多 |
Map<String,String> |
|
Keycloak 用户的角色映射。如果为空,将分配默认角色: 环境变量: 显示更多 |
Map<String,List<String>> |
|
dev service 监听的特定端口。 如果未指定,将选择一个随机端口。 环境变量: 显示更多 |
整数 |
|
要传递给容器的环境变量。 环境变量: 显示更多 |
Map<String,String> |
|
Keycloak 容器的内存限制,最大可达 如果未指定,默认内存限制为 1250MiB。 环境变量: 显示更多 |
|
|
WebClient 超时。使用此属性来配置 OIDC dev service admin client 使用的 HTTP 客户端在获取管理令牌和创建 realm 时等待来自 OpenId Connect Provider 响应的时间。 环境变量: 显示更多 |
|
关于 Duration 格式
要编写持续时间值,请使用标准的 您还可以使用简化的格式,以数字开头
在其他情况下,简化格式将被转换为
|
关于 MemorySize 格式
大小配置选项识别以下格式的字符串(显示为正则表达式): 如果未给出后缀,则假定为字节。 |