OpenID Connect (OIDC)身份验证
摘要
提供有关红帽构建的 Quarkus 文档的反馈 复制链接链接已复制到粘贴板!
要报告错误或改进文档,请登录到 Red Hat JIRA 帐户并提交问题。如果您没有 Red Hat Jira 帐户,则会提示您创建一个帐户。
流程
- 单击以下链接 以创建 ticket。
- 在 Summary 中输入问题的简短描述。
- 在 Description 中提供问题或功能增强的详细描述。包括一个指向文档中问题的 URL。
- 点 Submit 创建问题,并将问题路由到适当的文档团队。
使开源包含更多 复制链接链接已复制到粘贴板!
红帽致力于替换我们的代码、文档和 Web 属性中有问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。详情请查看 CTO Chris Wright 的信息。
第 1 章 OpenID Connect (OIDC) Bearer 令牌身份验证 复制链接链接已复制到粘贴板!
通过使用 Quarkus OpenID Connect (OIDC)扩展,保护应用中对带有 Bearer 令牌身份验证的 Jakarta REST (以前称为 JAX-RS)端点的 HTTP 访问。
1.1. Quarkus 中的 Bearer 令牌身份验证机制概述 复制链接链接已复制到粘贴板!
Quarkus 通过 Quarkus OpenID Connect (OIDC)扩展支持 Bearer 令牌身份验证机制。
bearer 令牌由 OIDC 和 OAuth 2.0 兼容授权服务器发布,如 Keycloak。
bearer 令牌身份验证是根据 bearer 令牌存在和有效授权 HTTP 请求的过程。bearer 令牌提供有关调用主题的信息,用于确定是否可以访问 HTTP 资源。
下图显示了 Quarkus 中的 Bearer 令牌身份验证机制:
图 1.1. 带有单页应用程序的 Quarkus 中的 bearer 令牌身份验证机制
- Quarkus 服务从 OIDC 供应商检索验证密钥。验证密钥用于验证 bearer 访问令牌签名。
- Quarkus 用户访问单页应用程序(SPA)。
- 单页应用程序使用授权代码流来验证用户并从 OIDC 供应商检索令牌。
- 单页应用使用访问令牌从 Quarkus 服务检索服务数据。
- Quarkus 服务使用验证密钥验证 bearer 访问令牌签名,检查令牌到期日期和其他声明,允许请求在令牌有效时继续,并将服务响应返回到单页应用。
- 单页应用程序将同一数据返回到 Quarkus 用户。
图 1.2. 使用 Java 或命令行客户端的 Quarkus 中的 bearer 令牌身份验证机制
- Quarkus 服务从 OIDC 供应商检索验证密钥。验证密钥用于验证 bearer 访问令牌签名。
-
客户端使用
client_credentials,它需要客户端 ID 和 secret 或密码授权,这需要客户端 ID、secret、用户名和密码从 OIDC 供应商检索访问令牌。 - 客户端使用访问令牌从 Quarkus 服务检索服务数据。
- Quarkus 服务使用验证密钥验证 bearer 访问令牌签名,检查令牌到期日期和其他声明,允许请求在令牌有效时继续,并将服务响应返回给客户端。
如果您需要使用 OIDC 授权代码流验证和授权用户,请参阅 Quarkus OpenID Connect 授权代码流机制来保护 Web 应用程序 指南。另外,如果您使用 Keycloak 和 bearer 令牌,请参阅使用 Keycloak 的 Quarkus 来集中授权 指南。
要了解如何使用 OIDC Bearer 令牌身份验证来保护服务应用程序,请参阅以下教程:* 使用 OpenID Connect (OIDC)授权代码流保护 Web 应用程序。
有关如何支持多个租户的详情,请参考使用 OpenID Connect Multi-Tenancy 的 Quarkus。
1.1.1. 访问 JWT 声明 复制链接链接已复制到粘贴板!
如果需要访问 JWT 令牌声明,您可以注入 JsonWebToken :
@ApplicationScoped、@Singleton 和 @RequestScoped 范围支持 JsonWebToken 注入。但是,如果单个声明被注入为简单类型,则需要使用 @RequestScoped。如需更多信息,请参阅 Quarkus "Using JWT RBAC" 指南中的 支持的注入范围 部分。
1.1.2. UserInfo 复制链接链接已复制到粘贴板!
如果您必须从 OIDC UserInfo 端点请求 UserInfo JSON 对象,请设置 quarkus.oidc.authentication.user-info-required=true。请求发送到 OIDC 提供程序 UserInfo 端点,并且创建 io.quarkus.oidc.UserInfo (一个简单的 javax.json.JsonObject wrapper)对象。io.quarkus.oidc.UserInfo 可以作为 SecurityIdentity userinfo 属性注入或访问。
1.1.3. 配置元数据 复制链接链接已复制到粘贴板!
当前租户的发现的 OpenID Connect 配置元数据 由 io.quarkus.oidc.OidcConfigurationMetadata 表示,并可作为 SecurityIdentity configuration-metadata 属性注入或访问。
如果端点是 public,则默认租户的 OidcConfigurationMetadata 会被注入。
1.1.4. 令牌声明和安全身份角色 复制链接链接已复制到粘贴板!
您可以从验证的 JWT 访问令牌映射 SecurityIdentity 角色,如下所示:
-
如果设置了
quarkus.oidc.roles.role-claim-path属性,并找到匹配的数组或字符串声明,则从这些声明中提取角色。例如,Customroles,,customroles/arrayscope,"http://namespace-qualified-custom-claim"/roles,"http://namespace-qualified-roles"。 -
如果有一个
组声明可用,则使用其值。 -
如果
realm_access/roles或resource_access/client_id/roles(其中client_id是quarkus.oidc.client-id属性的值)声明可用,则使用其值。此检查支持 Keycloak 发布的令牌。
例如,以下 JWT 令牌具有一个复杂的 groups 声明,其中包含包含 角色的角色 数组:
您必须将 microprofile_jwt_user 角色映射到 SecurityIdentity 角色,并且您可以使用此配置: quarkus.oidc.roles.role-claim-path=groups/roles。
如果令牌不透明(二进制),则使用来自远程令牌内省响应的 scope 属性。
如果 UserInfo 是角色的来源,则设置 quarkus.oidc.authentication.user-info-required=true 和 quarkus.oidc.roles.source=userinfo,如需要设置 quarkus.oidc.roles.role-claim-path。
此外,也可以使用自定义 SecurityIdentityAugmentor 来添加角色。如需更多信息,请参阅 Quarkus " Security tips and tricks" 指南中的 安全身份自定义 部分。
您还可以使用 HTTP 安全策略 将创建从令牌声明创建的 SecurityIdentity 角色映射到特定于部署的角色。
1.1.5. 令牌范围和 SecurityIdentity 权限 复制链接链接已复制到粘贴板!
SecurityIdentity 权限以 io.quarkus.security.StringPermission 的形式映射,来自 角色源的 scope 参数,并使用相同的声明分隔符。
有关 io.quarkus.security.PermissionsAllowed 注解的更多信息,请参阅"Authorization of web endpoint"指南中的 Permission 注解 部分。
1.1.6. 令牌验证和内省 复制链接链接已复制到粘贴板!
如果令牌是 JWT 令牌,默认情况下,它通过来自本地 JsonWebKeySet 中的 JsonWebKey (JWK)密钥进行验证,从 OIDC 提供程序的 JWK 端点检索。令牌的密钥标识符(kid)标头值用于查找匹配的 JWK 键。如果本地没有匹配的 JWK 可用,则通过从 JWK 端点获取当前密钥集来刷新 JsonWebKeySet。JsonWebKeySet 刷新只能在 quarkus.oidc.token.forced-jwk-refresh-interval 过期后重复。默认到期时间为 10 分钟。如果在刷新后没有匹配的 JWK,则 JWT 令牌将发送到 OIDC 提供程序的令牌内省端点。
如果令牌不透明,这意味着可以是二进制令牌或加密的 JWT 令牌,则始终发送到 OIDC 提供程序的令牌内省端点。
如果您仅使用 JWT 令牌,并且希望始终可用的 JsonWebKey,例如在刷新密钥集后,您必须禁用令牌内省,如以下示例所示:
quarkus.oidc.token.allow-jwt-introspection=false quarkus.oidc.token.allow-opaque-token-introspection=false
quarkus.oidc.token.allow-jwt-introspection=false
quarkus.oidc.token.allow-opaque-token-introspection=false
在某些情况下,只有通过内省验证 JWT 令牌时,可以通过仅配置内省端点地址来强制进行。以下属性配置演示了如何使用 Keycloak 实现它的示例:
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus quarkus.oidc.discovery-enabled=false # Token Introspection endpoint: http://localhost:8180/realms/quarkus/protocol/openid-connect/tokens/introspect quarkus.oidc.introspection-path=/protocol/openid-connect/tokens/introspect
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.oidc.discovery-enabled=false
# Token Introspection endpoint: http://localhost:8180/realms/quarkus/protocol/openid-connect/tokens/introspect
quarkus.oidc.introspection-path=/protocol/openid-connect/tokens/introspect
远程强制 JWT 令牌内省有优缺点。优点是,您可以消除两个远程调用的需要:远程 OIDC 元数据发现调用,以及另一个远程调用来获取不使用的验证密钥。缺点是,您需要知道内省端点地址并手动配置。
另一种方法是允许 OIDC 元数据发现的默认选项,还需要只执行远程 JWT 内省,如下例所示:
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus quarkus.oidc.token.require-jwt-introspection-only=true
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.oidc.token.require-jwt-introspection-only=true
这种方法的一个优点是配置更简单且更易于理解。缺点是,远程 OIDC 元数据发现调用需要发现内省端点地址,即使不会获取验证密钥。
将创建 io.quarkus.oidc.TokenIntrospection,它是一个简单的 jakarta.json.JsonObject wrapper 对象。它可以作为 SecurityIdentity introspection 属性注入或访问,提供 JWT 或不透明令牌已成功内省。
1.1.7. 令牌内省和 UserInfo 缓存 复制链接链接已复制到粘贴板!
所有不透明访问令牌都必须远程内省。有时,还必须内省 JWT 访问令牌。如果同时需要 UserInfo,则会在对 OIDC 提供程序的后续远程调用中使用相同的访问令牌。因此,如果需要 UserInfo,并且当前访问令牌不透明,会为每个此类令牌进行两个远程调用;一个远程调用来内省令牌,另一个用于获取 UserInfo。如果令牌是 JWT,则只需要对 get UserInfo 的单一远程调用,除非也必须内省。
对每个传入 bearer 或代码流访问令牌最多进行两个远程调用的成本有时可能会造成问题。
如果这是生产环境中的,请考虑在短时间内缓存令牌内省和 UserInfo 数据,例如 3 或 5 分钟。
quarkus-oidc 提供 quarkus.oidc.TokenIntrospectionCache 和 quarkus.oidc.UserInfoCache 接口,可用于 @ApplicationScoped 缓存实现。使用 @ApplicationScoped 缓存实现存储和检索 quarkus.oidc.TokenIntrospection 和/或 quarkus.oidc.UserInfo 对象,如下例所示:
每个 OIDC 租户都可以允许或拒绝其 quarkus.oidc.TokenIntrospection 数据、quarkus.oidc.UserInfo 数据,或使用布尔值 quarkus.oidc."tenant".allow-token-introspection-cache 和 quarkus.oidc."tenant".allow-user-info-cache 属性的存储。
另外,quarkus-oidc 提供了一个基于内存的简单令牌缓存,它实现了 quarkus.oidc.TokenIntrospectionCache 和 quarkus.oidc.UserInfoCache 接口。
您可以配置并激活默认的 OIDC 令牌缓存,如下所示:
默认缓存使用令牌作为密钥,每个条目都可以具有 TokenIntrospection、UserInfo 或两者。它只会保留最大大小的条目数。如果在添加新条目时缓存已满,则会尝试通过删除单个过期条目来查找空格。另外,如果激活,清理计时器会定期检查过期的条目并删除它们。
您可以使用默认缓存实现试验或注册自定义缓存。
1.1.8. JSON Web 令牌声明验证 复制链接链接已复制到粘贴板!
在验证 bearer JWT 令牌签名 并在 (exp)声明被检查后,将验证 iss (issuer)声明值。
默认情况下,iss claim 值与 issuer 属性进行比较,该属性可能已在已知的提供程序配置中发现。但是,如果设置了 quarkus.oidc.token.issuer 属性,则 iss claim 值会被与它进行比较。
在某些情况下,这是声明 验证可能无法正常工作。例如,如果发现的 issuer 属性包含内部 HTTP/IP 地址,而 令牌是 声明值包含外部 HTTP/IP 地址。或者,当发现的 issuer 属性包含模板租户变量时,但 令牌是 声明值具有完整的特定于租户的签发者值。
在这种情况下,请考虑通过设置 quarkus.oidc.token.issuer=any 来跳过签发者验证。只有没有其他选项时才跳过签发者验证:
-
如果您使用 Keycloak,并观察由不同主机地址导致的签发者验证错误,请使用
KEYCLOAK_FRONTEND_URL属性配置 Keycloak 以确保使用相同的主机地址。 -
如果
iss属性在多租户部署中特定于租户,请使用SecurityIdentitytenant-id属性来检查签发者在端点或自定义 Jakarta 过滤器中是否正确。例如:
考虑使用 quarkus.oidc.token.audience 属性来验证令牌 aud (audience)声明值。
1.1.9. 单页应用程序 复制链接链接已复制到粘贴板!
单页应用(SPA)通常使用 XMLHttpRequest(XHR)和 OIDC 提供程序提供的 JavaScript 实用程序代码,以获取 bearer 令牌来访问 Quarkus 服务 应用程序。
例如,如果使用 Keycloak,您可以使用 keycloak.js 验证用户并从 SPA 刷新过期的令牌:
1.1.10. 跨原始资源共享 复制链接链接已复制到粘贴板!
如果您计划从在不同域上运行的单页应用中使用 OIDC 服务 应用程序,您必须配置跨原始资源共享(CORS)。如需更多信息,请参阅"Cross-origin 资源共享"指南中的 CORS 过滤器 部分。
1.1.11. 供应商端点配置 复制链接链接已复制到粘贴板!
OIDC 服务 应用需要知道 OIDC 供应商的令牌、JsonWebKey (JWK)设置,以及可能的 UserInfo 和内省端点地址。
默认情况下,通过将 /.well-known/openid-configuration 路径添加到配置的 quarkus.oidc.auth-server-url 来发现它们。
或者,如果发现端点不可用,或者要在发现端点往返中保存,您可以禁用发现并使用相对路径值进行配置。例如:
1.1.12. 令牌传播 复制链接链接已复制到粘贴板!
有关 bearer 访问令牌传播到下游服务的详情,请参考 Quarkus "OpenID Connect (OIDC)和 OAuth2 客户端和过滤器参考" 指南中的 Token propagation 部分。
1.1.13. OIDC 供应商客户端身份验证 复制链接链接已复制到粘贴板!
当需要对 OIDC 供应商的远程请求时,使用 quarkus.oidc.runtime.OidcProviderClient。如果需要内省 Bearer 令牌,则 OidcProviderClient 必须向 OIDC 提供程序进行身份验证。有关支持的验证选项的更多信息,请参阅 Quarkus "OpenID Connect authorization code flow mechanism for protect web application" 指南中的 OIDC provider client authentication 部分。
1.1.14. 测试 复制链接链接已复制到粘贴板!
如果需要测试需要 Keycloak 授权的 Quarkus OIDC 服务端点,请按照 Test Keycloak 授权 部分操作。
您可以通过在测试项目中添加以下依赖项开始测试:
使用 Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
testImplementation("io.rest-assured:rest-assured") testImplementation("io.quarkus:quarkus-junit5")testImplementation("io.rest-assured:rest-assured") testImplementation("io.quarkus:quarkus-junit5")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.1.14.1. WireMock 复制链接链接已复制到粘贴板!
在您的测试项目中添加以下依赖项:
使用 Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-oidc-server</artifactId> <scope>test</scope> </dependency><dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-oidc-server</artifactId> <scope>test</scope> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
testImplementation("io.quarkus:quarkus-test-oidc-server")testImplementation("io.quarkus:quarkus-test-oidc-server")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
准备 REST 测试端点并设置 application.properties。例如:
keycloak.url is set by OidcWiremockTestResource
quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus/
quarkus.oidc.client-id=quarkus-service-app
quarkus.oidc.application-type=service
# keycloak.url is set by OidcWiremockTestResource
quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus/
quarkus.oidc.client-id=quarkus-service-app
quarkus.oidc.application-type=service
最后,编写测试代码。例如:
quarkus-test-oidc-server 扩展包含 JSON Web 密钥(JWK)格式的签名 RSA 私钥文件,并使用 smallrye.jwt.sign.key.location 配置属性指向它。它允许您使用 no-argument sign () 操作为令牌签名。
使用 OidcWiremockTestResource 测试 quarkus-oidc 服务 应用程序提供了最佳覆盖,因为即使通信通道针对 WireMock HTTP stub 进行了测试。如果您需要使用 WireMock stubs 运行测试,它还没有被 OidcWiremockTestResource 支持,您可以将 WireMockServer 实例注入测试类,如下例所示:
OidcWiremockTestResource 无法针对 Docker 容器使用 @QuarkusIntegrationTest,因为运行测试的 JVM 中运行 WireMock 服务器,这无法从运行 Quarkus 应用的 Docker 容器访问。
1.1.15. OidcTestClient 复制链接链接已复制到粘贴板!
如果您使用 SaaS OIDC 供应商,如 Auth0,并希望针对测试(开发)域运行测试,或者针对远程 Keycloak 测试域运行测试,如果您已经配置了 quarkus.oidc.auth-server-url,您可以使用 OidcTestClient。
例如,您有以下配置:
%test.quarkus.oidc.auth-server-url=https://dev-123456.eu.auth0.com/ %test.quarkus.oidc.client-id=test-auth0-client %test.quarkus.oidc.credentials.secret=secret
%test.quarkus.oidc.auth-server-url=https://dev-123456.eu.auth0.com/
%test.quarkus.oidc.client-id=test-auth0-client
%test.quarkus.oidc.credentials.secret=secret
要启动,请添加相同的依赖项 quarkus-test-oidc-server,如 WireMock 部分所述。
接下来,按如下方式编写测试代码:
此测试代码使用来自 test Auth0 域的 密码 授权获取令牌,该密码使用客户端 id test-auth0-client 注册了应用,并使用密码 alice 创建用户 alice。要使测试正常工作,test Auth0 应用必须启用 密码 授权。这个示例代码还演示了如何传递额外的参数。对于 Auth0,它们是 audience 和 scope 参数。
1.1.15.1. Keycloak 的 dev Services 复制链接链接已复制到粘贴板!
针对 Keycloak 进行集成测试的首选方法是 Keycloak 的 Dev Services。用于 Keycloak 的 dev Services 将启动并初始化测试容器。然后,它将创建一个 quarkus realm 和 quarkus-app 客户端(secret secret),并添加 alice (admin 和 roles)和 user bob (用户角色)用户,其中所有这些属性都可以自定义。
首先,添加以下依赖项,它提供实用程序类 io.quarkus.test.keycloak.client.KeycloakTestClient,您可以用于测试获取访问令牌:
使用 Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-keycloak-server</artifactId> <scope>test</scope> </dependency><dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-keycloak-server</artifactId> <scope>test</scope> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
testImplementation("io.quarkus:quarkus-test-keycloak-server")testImplementation("io.quarkus:quarkus-test-keycloak-server")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
接下来,准备 application.properties 配置文件。您可以从一个空的 application.properties 文件开始,因为 Keycloak 的 Dev Services 注册 quarkus.oidc.auth-server-url,并将它指向正在运行的测试容器,quarkus.oidc.client-id=quarkus-app, 和 quarkus.oidc.credentials.secret=secret。
但是,如果您已配置了所需的 quarkus-oidc 属性,则您只需要将 quarkus.oidc.auth-server-url 与 'Dev Services for Keycloak' 的 prod 配置集关联,如下例所示:
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
如果在运行测试前必须将自定义域文件导入到 Keycloak 中,请为 Keycloak 配置 Dev Services,如下所示:
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus quarkus.keycloak.devservices.realm-path=quarkus-realm.json
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.keycloak.devservices.realm-path=quarkus-realm.json
最后,编写您的测试,它将在 JVM 模式中执行,如下例所示:
以 JVM 模式执行的测试示例:
以原生模式执行的测试示例:
有关为 Keycloak 初始化和配置 Dev Services 的更多信息,请参阅 Keycloak 的 Dev Services 指南。
1.1.15.2. 本地公钥 复制链接链接已复制到粘贴板!
您可以使用本地内联公钥来测试 quarkus-oidc 服务 应用程序,如下例所示:
quarkus.oidc.client-id=test quarkus.oidc.public-key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9xnQIDAQAB smallrye.jwt.sign.key.location=/privateKey.pem
quarkus.oidc.client-id=test
quarkus.oidc.public-key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEqFyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwRTYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5eUF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYnsIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9xnQIDAQAB
smallrye.jwt.sign.key.location=/privateKey.pem
要生成 JWT 令牌,请从 主 Quarkus 存储库中的 integration-tests/oidc-tenancy 复制 privateKey.pem,并使用与上一 WireMock 部分中类似的测试代码。如果需要,您可以使用自己的测试密钥。
与 WireMock 方法相比,这种方法提供有限的覆盖范围。例如,不包括远程通信代码。
1.1.15.3. TestSecurity 注解 复制链接链接已复制到粘贴板!
您可以使用 @TestSecurity 和 @OidcSecurity 注释来测试 服务 应用程序端点代码(取决于以下注入之一或全部三个):
-
JsonWebToken -
UserInfo -
OidcConfigurationMetadata
首先,添加以下依赖项:
使用 Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-security-oidc</artifactId> <scope>test</scope> </dependency><dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-security-oidc</artifactId> <scope>test</scope> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
testImplementation("io.quarkus:quarkus-test-security-oidc")testImplementation("io.quarkus:quarkus-test-security-oidc")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
按照以下示例中所述编写测试代码:
在这个代码示例中使用的 ProtectedResource 类可能类似如下:
您必须始终使用 @TestSecurity 注释。其 user 属性返回为 JsonWebToken.getName (),其 roles 属性返回为 JsonWebToken.getGroups ()。@OidcSecurity 注释是可选的,您可以使用它来设置额外的令牌声明和 UserInfo 和 OidcConfigurationMetadata 属性。另外,如果配置了 quarkus.oidc.token.issuer 属性,它将用作 OidcConfigurationMetadata issuer 属性值。
如果使用不透明令牌,您可以测试它们,如下例所示:
在这个代码示例中使用的 ProtectedResource 类可能类似如下:
@TestSecurity、user 和 roles 属性作为 TokenIntrospection、username 和 scope 属性提供。使用 io.quarkus.test.security.oidc.TokenIntrospection 来添加额外的内省响应属性,如电子邮件 等等。
@TestSecurity 和 @OidcSecurity 可以合并到 meta-annotation 中,如下例所示:
如果多个测试方法必须使用同一组安全设置,这特别有用。
1.1.16. 检查日志中的错误 复制链接链接已复制到粘贴板!
要查看有关令牌验证错误的更多详细信息,请启用 io.quarkus.oidc.runtime.OidcProvider 和 TRACE 级别日志记录:
quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".level=TRACE quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".min-level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".min-level=TRACE
要查看有关 OidcProvider 客户端初始化错误的更多详细信息,请启用 io.quarkus.oidc.runtime.OidcRecorder 和 TRACE 级别日志记录,如下所示:
quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".level=TRACE quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".min-level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".min-level=TRACE
1.1.17. 对 OIDC 供应商的外部和内部访问 复制链接链接已复制到粘贴板!
与自动发现或配置了 quarkus.oidc.auth-server-url 内部 URL 的 URL 相比,OIDC 供应商和其他端点可能具有不同的 HTTP (S) URL。例如,假设您的 SPA 从外部令牌端点地址获取令牌,并将其发送到 Quarkus 作为 bearer 令牌。在这种情况下,端点可能会报告签发者验证失败。
在这种情况下,如果您使用 Keycloak,使用 KEYCLOAK_FRONTEND_URL 系统属性将其设置为外部可访问的基本 URL。如果使用其他 OIDC 供应商,请参阅您的供应商文档。
1.1.18. 使用 client-id 属性 复制链接链接已复制到粘贴板!
quarkus.oidc.client-id 属性标识请求当前 bearer 令牌的 OIDC 客户端。OIDC 客户端可以是在浏览器中运行的 SPA 应用程序,也可以是 Quarkus Web-app 机密客户端应用程序将访问令牌传播到 Quarkus 服务 应用程序。
如果服务 应用预期远程内省令牌,则需要此属性,这始终是不透明令牌的情况。此属性是可选的,用于本地 JSON Web Token (JWT)验证。
即使端点不需要访问远程内省端点,也鼓励设置 quarkus.oidc.client-id 属性。这是因为当设置了 client-id 时,它可用于验证令牌受众。当令牌验证失败时,它也将包含在日志中,从而提高了签发给特定客户端的令牌的可追溯性,并在较长时间内进行分析。
例如,如果您的 OIDC 供应商设置了令牌受众,请考虑以下配置模式:
# Set client-id
quarkus.oidc.client-id=quarkus-app
# Token audience claim must contain 'quarkus-app'
quarkus.oidc.token.audience=${quarkus.oidc.client-id}
# Set client-id
quarkus.oidc.client-id=quarkus-app
# Token audience claim must contain 'quarkus-app'
quarkus.oidc.token.audience=${quarkus.oidc.client-id}
如果您设置了 quarkus.oidc.client-id,但您的端点不需要远程访问 OIDC 供应商端点之一(整数、令牌获取等),请不要使用 quarkus.oidc.credentials 或类似属性设置客户端 secret,因为它不会被使用。
Quarkus web-app 应用程序总是需要 quarkus.oidc.client-id 属性。
1.2. HTTP 请求完成后进行身份验证 复制链接链接已复制到粘贴板!
有时,如果没有活跃的 HTTP 请求上下文时,必须创建给定令牌的 SecurityIdentity。quarkus-oidc 扩展提供 io.quarkus.oidc.TenantIdentityProvider,将令牌转换为 SecurityIdentity 实例。例如,在 HTTP 请求完成后必须验证令牌时,其中一个情况是在您使用 Vert.x 事件总线 处理消息时。以下示例在不同的 CDI 请求上下文中使用"product-order"消息。因此,注入的 SecurityIdentity 无法正确代表验证的身份,并且是匿名的。
- 1
- 此时,在禁用主动身份验证时,不会验证令牌。
在 HTTP 请求过程中使用供应商时,可以解析租户配置,如 使用 OpenID Connect Multi-Tenancy 指南中所述。但是,如果没有活跃的 HTTP 请求时,您必须明确选择带有 io.quarkus.oidc.TenantFeature qualifier 的租户。
目前不支持 动态租户配置解析。需要动态租户的身份验证将失败。
1.3. OIDC 请求过滤器 复制链接链接已复制到粘贴板!
您可以通过注册一个或多个 OidcRequestFilter 实现(可以更新或添加新的请求标头)来过滤 Quarkus 向 OIDC 供应商发出的 OIDC 请求,以及日志请求。如需更多信息,请参阅 OIDC 请求过滤器。
1.4. 参考 复制链接链接已复制到粘贴板!
第 2 章 使用 OpenID Connect (OIDC) Bearer 令牌身份验证来保护服务应用程序 复制链接链接已复制到粘贴板!
使用 Quarkus OpenID Connect (OIDC)扩展来保护带有 Bearer 令牌身份验证的 Jakarta REST 应用。bearer 令牌由 OIDC 和 OAuth 2.0 兼容授权服务器发布,如 Keycloak。
有关 OIDC Bearer 令牌身份验证的更多信息,请参阅 Quarkus OpenID Connect (OIDC) Bearer 令牌身份验证 指南。
如果要使用 OIDC 授权代码流身份验证保护 Web 应用程序,请参阅 OpenID Connect 授权代码流机制来保护 Web 应用程序 指南。
2.1. 先决条件 复制链接链接已复制到粘贴板!
要完成本指南,您需要:
- 大约 15 分钟
- IDE
-
正确配置了
JAVA_HOME的 JDK 17+ - Apache Maven 3.9.6
- 正常工作的容器运行时(Docker 或 Podman)
- 如果要使用 Quarkus CLI,可选
- 如果要构建原生可执行文件(或者使用原生容器构建,则可选的 Mandrel 或 GraalVM) https://quarkus.io/version/3.8/guides/building-native-image#configuring-graalvm
- jq 命令行处理器工具
2.2. 架构 复制链接链接已复制到粘贴板!
本例演示了如何构建提供两个端点的简单微服务:
-
/api/users/me -
/api/admin
这些端点受到保护,只有在客户端发送 bearer 令牌与请求时才能访问,该令牌必须有效(如签名、到期和受众)并由微服务信任。
Keycloak 服务器发出 bearer 令牌,并代表签发令牌的主题。由于它是 OAuth 2.0 授权服务器,因此令牌也会代表用户引用客户端。
具有有效令牌的任何用户都可以访问 /api/users/me 端点。作为响应,它会返回一个 JSON 文档,其中包含从令牌中信息中获取的用户详细信息。
/api/admin 端点通过 RBAC 进行保护(Role-Based Access Control),只有具有 admin 角色的用户才能访问。在这个端点中,@RolesAllowed 注释用于声明性地强制实施访问约束。
2.3. 解决方案 复制链接链接已复制到粘贴板!
按照下一小节中的说明,并逐步创建应用程序步骤。您也可以直接转至完整的示例。
您可以通过运行命令 git clone https://github.com/quarkusio/quarkus-quickstarts.git -b 3.8 来克隆 Git 存储库,也可以下载 归档。
解决方案位于 security-openid-connect-quickstart 目录中。
2.4. 创建 Maven 项目 复制链接链接已复制到粘贴板!
您可以使用 oidc 扩展创建新的 Maven 项目,也可以将扩展添加到现有的 Maven 项目中。完成以下任一命令:
要创建新的 Maven 项目,请使用以下命令:
使用 Quarkus CLI:
quarkus create app org.acme:security-openid-connect-quickstart \ --extension='oidc,resteasy-reactive-jackson' \ --no-code cd security-openid-connect-quickstartquarkus create app org.acme:security-openid-connect-quickstart \ --extension='oidc,resteasy-reactive-jackson' \ --no-code cd security-openid-connect-quickstartCopy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加--
gradle or--gradle-kotlin-dsl选项。有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。
使用 Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加
-DbuildTool=gradleor-DbuildTool=gradle-kotlin-dsl选项。
对于 Windows 用户:
-
如果使用 cmd,(不要使用反向斜杠
\并将所有内容放在同一行中) -
如果使用 Powershell,则双引号中的 wrap
-D参数,如"-DprojectArtifactId=security-openid-connect-quickstart"
如果您已经配置了 Quarkus 项目,您可以通过在项目基本目录中运行以下命令来将 oidc 扩展添加到项目中:
使用 Quarkus CLI:
quarkus extension add oidc
quarkus extension add oidcCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:add-extension -Dextensions='oidc'
./mvnw quarkus:add-extension -Dextensions='oidc'Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew addExtension --extensions='oidc'
./gradlew addExtension --extensions='oidc'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
这将在您的构建文件中添加以下内容:
使用 Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency>
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
implementation("io.quarkus:quarkus-oidc")implementation("io.quarkus:quarkus-oidc")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.5. 编写应用程序 复制链接链接已复制到粘贴板!
按照以下示例所示,实现
/api/users/me端点,它是一个常规 Jakarta REST 资源:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 实现
/api/admin端点,如下例所示:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意本例中的主要区别在于,
@RolesAllowed注释仅用于验证仅授予admin角色的用户才能访问端点。
@RequestScoped 和 @ApplicationScoped 上下文都支持 SecurityIdentity 注入。
2.6. 配置应用程序 复制链接链接已复制到粘贴板!
通过在
src/main/resources/application.properties文件中设置以下配置属性来配置 Quarkus OpenID Connect (OIDC)扩展。Copy to Clipboard Copied! Toggle word wrap Toggle overflow
其中:
-
%prod.quarkus.oidc.auth-server-url设置 OpenID Connect (OIDC)服务器的基本 URL。%prod.配置集前缀可确保Keycloak 的 Dev Services在开发(dev)模式下运行应用程序时启动容器。有关更多信息,请参阅 在 dev mode 部分中运行应用。 -
quarkus.oidc.client-id设置用于标识应用程序的客户端 ID。 -
quarkus.oidc.credentials.secret设置客户端 secret,该 secret 由client_secret_basic身份验证方法使用。
如需更多信息,请参阅 Quarkus OpenID Connect (OIDC)配置属性 指南。
2.7. 启动并启用 Keycloak 服务器 复制链接链接已复制到粘贴板!
将 realm 配置文件放在 classpath (
target/classes目录)上,以便在 dev 模式中运行时自动导入。如果您已构建了 完整的解决方案,则不需要执行此操作,在这种情况下,此域文件会添加到构建期间的 classpath 中。注意当您以 dev 模式运行应用程序时,不要启动 Keycloak 服务器 ;
Keycloak 的 Dev Services将启动一个容器。有关更多信息,请参阅 在 dev mode 部分中运行应用。要启动 Keycloak 服务器,您可以使用 Docker 运行以下命令:
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-devdocker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-devCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
其中
keycloak.version设置为24.0.0或更高版本。
-
其中
- 您可以在 localhost:8180 访问您的 Keycloak 服务器。
要访问 Keycloak 管理控制台,请使用以下登录凭证以
admin用户身份登录:-
用户名:
admin -
Password:
admin
-
用户名:
- 从上游 community 存储库导入 realm 配置文件,以创建新域。
如需更多信息,请参阅关于 创建和配置新域的 Keycloak 文档。
2.8. 在 dev 模式下运行应用程序 复制链接链接已复制到粘贴板!
要在 dev 模式下运行应用程序,请运行以下命令:
使用 Quarkus CLI:
quarkus dev
quarkus devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:dev
./mvnw quarkus:devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew --console=plain quarkusDev
./gradlew --console=plain quarkusDevCopy to Clipboard Copied! Toggle word wrap Toggle overflow
-
Keycloak 的 dev Services 将启动一个 Keycloak 容器,并导入
quarkus-realm.json。
-
打开 Dev UI,您可以在 /q/dev-ui 中找到。然后,在
OpenID Connect卡中,点Keycloak 供应商链接。 当提示登录到
OpenID Connect Dev UI提供的单个页面应用程序时,请执行以下步骤:以
alice身份(密码:alice)登录,其具有用户角色。-
访问
/api/admin会返回403状态代码。 -
访问
/api/users/me会返回200状态代码。
-
访问
注销,然后重新以
admin身份(密码:admin)登录,其具有admin和用户角色。-
访问
/api/admin会返回200状态代码。 -
访问
/api/users/me会返回200状态代码。
-
访问
2.9. 在 JVM 模式下运行应用程序 复制链接链接已复制到粘贴板!
使用 dev 模式时,您可以将应用作为标准 Java 应用运行。
编译应用程序:
使用 Quarkus CLI:
quarkus build
quarkus buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install
./mvnw installCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build
./gradlew buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow
运行应用程序:
java -jar target/quarkus-app/quarkus-run.jar
java -jar target/quarkus-app/quarkus-run.jarCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.10. 以原生模式运行应用程序 复制链接链接已复制到粘贴板!
您可以在不进行任何修改的情况下,将此演示编译为原生模式。这意味着您不再需要在生产环境中安装 JVM。运行时技术包含在生成的二进制中,并经过优化,以便以最少的资源运行。
编译时间需要一些时间,因此默认禁用此步骤。
通过启用
原生配置集来再次构建应用程序:使用 Quarkus CLI:
quarkus build --native
quarkus build --nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install -Dnative
./mvnw install -DnativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build -Dquarkus.package.type=native
./gradlew build -Dquarkus.package.type=nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow
等待一段时间后,您直接运行以下二进制文件:
./target/security-openid-connect-quickstart-1.0.0-SNAPSHOT-runner
./target/security-openid-connect-quickstart-1.0.0-SNAPSHOT-runnerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
2.11. 测试应用 复制链接链接已复制到粘贴板!
有关以 dev 模式测试应用程序的信息,请参阅前面的在 dev mode 部分中运行该应用。
您可以使用 curl 来测试以 JVM 或原生模式启动的应用程序。
- 因为应用程序使用 Bearer 令牌身份验证,您必须首先从 Keycloak 服务器获取访问令牌来访问应用程序资源:
前面的示例获取用户 alice 的访问令牌。
-
任何用户都可以访问
http://localhost:8080/api/users/me端点,该端点会返回一个 JSON 有效负载,其中包含该用户的详细信息。
curl -v -X GET \ http://localhost:8080/api/users/me \ -H "Authorization: Bearer "$access_token
curl -v -X GET \
http://localhost:8080/api/users/me \
-H "Authorization: Bearer "$access_token
-
只有具有
admin角色的用户才能访问http://localhost:8080/api/admin端点。如果您尝试使用之前发布的访问令牌访问此端点,您可以从服务器获得403响应。
curl -v -X GET \ http://localhost:8080/api/admin \ -H "Authorization: Bearer "$access_token
curl -v -X GET \
http://localhost:8080/api/admin \
-H "Authorization: Bearer "$access_token
-
要访问 admin 端点,获取
admin用户的令牌:
有关编写依赖于 Keycloak 的 Dev 服务 的集成测试的详情,请参考 "OpenID Connect (OIDC) Bearer 令牌身份验证" 指南中的 Dev Services for Keycloak 部分。
2.12. 参考 复制链接链接已复制到粘贴板!
第 3 章 用于保护 Web 应用程序的 OpenID Connect 授权代码流机制 复制链接链接已复制到粘贴板!
要保护 Web 应用程序,您可以使用 Quarkus OIDC 扩展提供的行业标准 OpenID Connect (OIDC)授权代码流机制。
3.1. OIDC 授权代码流机制概述 复制链接链接已复制到粘贴板!
Quarkus OpenID Connect (OIDC)扩展可以使用 OIDC 兼容授权服务器支持的 OIDC 授权代码流机制(如 Keycloak )来保护应用程序 HTTP 端点。
授权代码流机制通过将 Web 应用程序重定向到 OIDC 供应商(如 Keycloak)来验证用户,以登录。身份验证后,OIDC 供应商将使用授权代码将用户重新重定向到应用程序,确认身份验证是否成功。然后,应用程序使用 ID 令牌的 OIDC 供应商(代表经过身份验证的用户)、访问令牌和刷新令牌交换此代码,以授权用户访问应用程序。
下图显示了 Quarkus 中的授权代码流机制。
图 3.1. Quarkus 中的授权代码流机制
-
Quarkus 用户请求访问 Quarkus
web-app应用程序。 - Quarkus web-app 将用户重定向到授权端点,即用于身份验证的 OIDC 供应商。
- OIDC 供应商将用户重定向到登录和验证提示。
- 在提示符处,用户输入其用户凭据。
- OIDC 供应商验证输入的用户凭证,如果成功,请发出授权代码,并使用作为查询参数包括的代码重定向到 Quarkus web-app。
- Quarkus web-app 使用 ID、访问和刷新令牌的 OIDC 供应商交换此授权代码。
授权代码流已完成,Quarkus web-app 使用发布的令牌来访问用户的信息,并为该用户授予相关基于角色的访问控制。发布以下令牌:
-
ID 令牌 : Quarkus
web-app应用使用 ID 令牌中的用户信息,使经过身份验证的用户能够安全地登录,并提供对 Web 应用程序的基于角色的访问控制。 - 访问令牌 : Quarkus web-app 可以使用访问令牌访问 UserInfo API 来获取有关经过身份验证的用户的附加信息,或将其传播到另一个端点。
- 刷新令牌:(可选)如果 ID 和访问令牌过期,则 Quarkus web-app 可以使用刷新令牌获取新的 ID 和访问令牌。
另请参阅 OIDC 配置属性 参考指南。
要了解如何使用 OIDC 授权代码流机制保护 Web 应用程序,请参阅使用 OIDC 授权代码流保护 Web 应用程序。
如果要使用 OIDC Bearer 令牌身份验证来保护服务应用程序,请参阅 OIDC Bearer 令牌身份验证。
有关如何支持多个租户的详情,请参考 使用 OpenID Connect Multi-Tenancy。
3.2. 使用授权代码流机制 复制链接链接已复制到粘贴板!
3.2.1. 配置对 OIDC 供应商端点的访问 复制链接链接已复制到粘贴板!
OIDC web-app 应用需要 OIDC 供应商的授权、令牌、JsonWebKey (JWK)集的 URL,以及 UserInfo、introspection 和 end-session (RP-initiated logout)端点。
按照惯例,通过将 /.well-known/openid-configuration 路径添加到配置的 quarkus.oidc.auth-server-url 来发现它们。
或者,如果发现端点不可用,或者您希望减少发现端点往返,您可以禁用端点发现并配置相对路径值。例如:
有些 OIDC 供应商支持元数据发现,但不要返回授权代码流完成或支持应用程序功能所需的所有端点 URL 值,如用户注销。要临时解决这个问题,您可以在本地配置缺少的端点 URL 值,如下例所示:
如果 URL 无法用于本地 Quarkus 端点,并且需要更具体的值,则可以使用同样的配置来覆盖发现的端点 URL。例如,支持全局和特定于应用程序的最终用户会话端点的供应商会返回一个全局最终用户会话 URL,如 http://localhost:8180/oidcprovider/account/global-logout。此 URL 将从当前登录的用户的所有应用中注销用户。但是,如果要求是当前应用程序只将用户从特定应用程序注销,您可以通过设置 quarkus.oidc.end-session=logout 参数来覆盖全局 end-session URL。
3.2.1.1. OIDC 供应商客户端身份验证 复制链接链接已复制到粘贴板!
OIDC 供应商通常需要在与 OIDC 端点交互时识别和验证应用程序。quarkus OIDC,特别是 quarkus.oidc.runtime.OidcProviderClient 类,当必须刷新或内省授权代码时,向 OIDC 供应商进行身份验证。
通常,当授权到 OIDC 供应商时,为给定应用程序定义客户端 ID 和客户端 secret。所有 OIDC 客户端身份验证 选项都被支持。例如:
client_secret_basic 示例:
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/ quarkus.oidc.client-id=quarkus-app quarkus.oidc.credentials.secret=mysecret
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/
quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.secret=mysecret
或者:
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/ quarkus.oidc.client-id=quarkus-app quarkus.oidc.credentials.client-secret.value=mysecret
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/
quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.client-secret.value=mysecret
以下示例显示了从 凭证供应商 检索的 secret:
client_secret_post示例
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/ quarkus.oidc.client-id=quarkus-app quarkus.oidc.credentials.client-secret.value=mysecret quarkus.oidc.credentials.client-secret.method=post
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/
quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.client-secret.value=mysecret
quarkus.oidc.credentials.client-secret.method=post
client_secret_jwt 示例,其签名算法是 HS256:
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/ quarkus.oidc.client-id=quarkus-app quarkus.oidc.credentials.jwt.secret=AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/
quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.jwt.secret=AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow
client_secret_jwt 示例,其中 secret 从 凭证提供程序 检索:
使用 PEM 密钥文件的 private_key_jwt 示例,签名算法为 RS256:。
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/ quarkus.oidc.client-id=quarkus-app quarkus.oidc.credentials.jwt.key-file=privateKey.pem
quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/
quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.jwt.key-file=privateKey.pem
使用密钥存储文件的 private_key_jwt 示例,签名算法为 RS256:
使用 client_secret_jwt 或 private_key_jwt 身份验证方法可确保客户端 secret 没有发送到 OIDC 供应商,因此避免了被 'man-in-the-middle' 攻击所截获的 secret 的风险。
3.2.1.1.1. 其他 JWT 身份验证选项 复制链接链接已复制到粘贴板!
如果使用 client_secret_jwt、private_key_jwt 或 Apple post_jwt 身份验证方法,您可以自定义 JWT 签名算法、密钥标识符、使用者、主题和签发者。例如:
3.2.1.1.2. Apple POST JWT 复制链接链接已复制到粘贴板!
Apple OIDC 供应商使用 client_secret_post 方法,其中 secret 是使用 private_key_jwt 身份验证方法生成的 JWT,但使用 Apple 帐户特定的签发者和主题声明。
在 Quarkus Security 中,quarkus-oidc 支持非标准 client_secret_post_jwt 身份验证方法,如下所示:
3.2.1.1.3. Mutual TLS (mTLS) 复制链接链接已复制到粘贴板!
有些 OIDC 供应商可能需要客户端作为 mutual TLS 身份验证过程的一部分进行身份验证。
以下示例演示了如何配置 quarkus-oidc 以支持 mTLS :
3.2.1.1.4. POST 查询 复制链接链接已复制到粘贴板!
有些供应商(如 Strava OAuth2 供应商 )需要发布客户端凭证作为 HTTP POST 查询参数:
quarkus.oidc.provider=strava quarkus.oidc.client-id=quarkus-app quarkus.oidc.credentials.client-secret.value=mysecret quarkus.oidc.credentials.client-secret.method=query
quarkus.oidc.provider=strava
quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.client-secret.value=mysecret
quarkus.oidc.credentials.client-secret.method=query
3.2.1.2. 内省端点身份验证 复制链接链接已复制到粘贴板!
有些 OIDC 供应商需要使用基本身份验证以及与 client_id 和 client_secret 不同的凭证进行身份验证。如果您之前已将安全身份验证配置为支持 client_secret_basic 或 client_secret_post 客户端身份验证方法,如 OIDC 供应商 客户端身份验证部分中所述,您可能需要应用额外的配置,如下所示。
如果必须内省令牌,并且需要内省特定于内省端点的身份验证机制,您可以配置 quarkus-oidc,如下所示:
quarkus.oidc.introspection-credentials.name=introspection-user-name quarkus.oidc.introspection-credentials.secret=introspection-user-secret
quarkus.oidc.introspection-credentials.name=introspection-user-name
quarkus.oidc.introspection-credentials.secret=introspection-user-secret
3.2.1.3. OIDC 请求过滤器 复制链接链接已复制到粘贴板!
您可以通过注册一个或多个 OidcRequestFilter 实现(可以更新或添加新的请求标头)来过滤 Quarkus 向 OIDC 供应商发出的 OIDC 请求,也可以记录请求。
例如:
或者,您可以使用 OidcRequestFilter.Endpoint enum 将此过滤器仅应用到令牌端点请求:
- 1
- 将这个过滤器限制为只针对 OIDC 发现端点的请求。
3.2.1.4. 重定向至 OIDC 供应商 复制链接链接已复制到粘贴板!
当用户重定向到 OIDC 供应商以进行身份验证时,重定向 URL 包含一个 redirect_uri 查询参数,该参数表示在身份验证完成后必须重定向到的供应商。在我们的情形中,这是 Quarkus 应用程序。
默认情况下,quarkus 将此参数设置为当前应用程序请求 URL。例如,如果用户试图访问 http://localhost:8080/service/1 上的 Quarkus 服务端点,则 redirect_uri 参数被设置为 http://localhost:8080/service/1。同样,如果请求 URL 是 http://localhost:8080/service/2,则 redirect_uri 参数被设置为 http://localhost:8080/service/2。
有些 OIDC 供应商要求将 redirect_uri 的值与给定应用程序的值相同,例如 http://localhost:8080/service/callback,用于所有重定向 URL。在这种情况下,必须设置 quarkus.oidc.authentication.redirect-path 属性。例如,quarkus.oidc.authentication.redirect-path=/service/callback,Quarkus 会将 redirect_uri 参数设置为绝对 URL,如 http://localhost:8080/service/callback,它都相同,无论当前请求 URL 都相同。
如果设置了 quarkus.oidc.authentication.redirect-path,但您需要在用户重定向到唯一回调 URL 后恢复原始请求 URL,例如 http://localhost:8080/service/callback,将 quarkus.oidc.authentication.restore-path-after-redirect 属性设置为 true。这将恢复请求 URL,如 http://localhost:8080/service/1。
3.2.1.5. 自定义身份验证请求 复制链接链接已复制到粘贴板!
默认情况下,只有 response_type (设置为 代码)、scope (设置为 openid)、client_id、redirect_uri、以及 status 属性在用户重定向到时传递给 OIDC 供应商的授权端点。
您可以使用 quarkus.oidc.authentication.extra-params 添加更多属性。例如,有些 OIDC 供应商可能会选择返回授权代码作为重定向 URI 片段的一部分,这会中断身份验证过程。以下示例演示了如何解决这个问题:
quarkus.oidc.authentication.extra-params.response_mode=query
quarkus.oidc.authentication.extra-params.response_mode=query
3.2.1.6. 自定义身份验证错误响应 复制链接链接已复制到粘贴板!
当用户重定向到 OIDC 授权端点以进行身份验证时,如果需要,授权 Quarkus 应用程序,这个重定向请求可能会失败,例如,当重定向 URI 中包含无效的范围时。在这种情况下,供应商会将用户重新重定向到 Quarkus,并带有 error 和 error_description 参数,而不是预期的 代码 参数。
例如,当重定向到提供程序的无效范围或其他无效参数时,可能会发生这种情况。
在这种情况下,默认会返回 HTTP 401 错误。但是,您可以请求调用自定义公共错误端点,以返回更用户友好的 HTML 错误页面。要做到这一点,请设置 quarkus.oidc.authentication.error-path 属性,如下例所示:
quarkus.oidc.authentication.error-path=/error
quarkus.oidc.authentication.error-path=/error
确保属性以正斜杠(/)字符开头,并且路径相对于当前端点的基本 URI。例如,如果设为 '/error',并且当前请求 URI 为 https://localhost:8080/callback?error=invalid_scope,则向 https://localhost:8080/error?error=invalid_scope 发出最终重定向。
若要防止用户重定向到此页面,需要重新验证,请确保此错误端点为公共资源。
3.2.2. 访问授权数据 复制链接链接已复制到粘贴板!
您可以通过不同的方式访问授权信息。
3.2.2.1. 访问 ID 和访问令牌 复制链接链接已复制到粘贴板!
OIDC 代码身份验证机制在授权代码流期间获取三个令牌: ID 令牌、访问令牌和刷新令牌。
ID 令牌始终是一个 JWT 令牌,代表使用 JWT 声明进行用户身份验证。您可以使用它来发出 OIDC 端点、用户名以及名为 声明 的其他信息。您可以使用 IdToken qualifier 注入 JsonWebToken 来访问 ID 令牌声明:
OIDC web-app 应用程序通常使用访问令牌代表当前登录的用户访问其他端点。您可以访问原始访问令牌,如下所示:
如果发布到 Quarkus web-app 应用的访问令牌是不透明的,并且无法解析到 JsonWebToken,或者应用程序需要内内容,则使用 AccessTokenCredential。
@RequestScoped 和 @ApplicationScoped 上下文都支持 JsonWebToken 和 AccessTokenCredential 注入。
quarkus OIDC 使用刷新令牌来刷新当前的 ID 和访问令牌,作为其 会话管理 过程的一部分。
3.2.2.2. 用户信息 复制链接链接已复制到粘贴板!
如果 ID 令牌没有提供有关当前经过身份验证的用户的足够信息,您可以从 UserInfo 端点获取更多信息。设置 quarkus.oidc.authentication.user-info-required=true 属性,从 OIDC UserInfo 端点请求 UserInfo JSON 对象。
使用通过授权代码授权响应返回的访问令牌将向 OIDC 提供程序 UserInfo 端点发送请求,以及一个 io.quarkus.oidc.UserInfo (一个简单的 jakarta.json.JsonObject wrapper)对象被创建。io.quarkus.oidc.UserInfo 可以作为 SecurityIdentity userinfo 属性注入或访问。
3.2.2.3. 访问 OIDC 配置信息 复制链接链接已复制到粘贴板!
当前租户的发现的 OpenID Connect 配置元数据 由 io.quarkus.oidc.OidcConfigurationMetadata 表示,并可作为 SecurityIdentity configuration-metadata 属性注入或访问。
如果端点是 public,则默认租户的 OidcConfigurationMetadata 会被注入。
3.2.2.4. 映射令牌声明和 SecurityIdentity 角色 复制链接链接已复制到粘贴板!
角色从验证令牌映射到 SecurityIdentity 角色的方式与为 Bearer 令牌 的方式相同。唯一的区别是 ID 令牌 默认用作角色的来源。
如果使用 Keycloak,请为 ID 令牌设置 microprofile-jwt 客户端范围,使其包含 组 声明。如需更多信息,请参阅 Keycloak 服务器管理指南。
但是,根据您的 OIDC 供应商,角色可能会存储在访问令牌或用户信息中。
如果访问令牌包含角色,并且此访问令牌不应传播到下游端点,则设置 quarkus.oidc.roles.source=accesstoken。
如果 UserInfo 是角色的来源,则设置 quarkus.oidc.roles.source=userinfo,如果需要,quarkus.oidc.roles.role-claim-path。
另外,您还可以使用自定义 SecurityIdentityAugmentor 来添加角色。如需更多信息,请参阅安全身份管理 自定义。您还可以使用 HTTP 安全策略 将创建从令牌声明创建的 SecurityIdentity 角色映射到特定于部署的角色。
3.2.3. 确保令牌和身份验证数据的有效性 复制链接链接已复制到粘贴板!
身份验证过程的一个核心部分是确保信息的信任链和有效性。这可以通过确保令牌可以被信任来实现。
3.2.3.1. 令牌验证和内省 复制链接链接已复制到粘贴板!
OIDC 授权代码流令牌的验证过程遵循 Bearer 令牌身份验证令牌验证和内省逻辑。如需更多信息,请参阅"Quarkus OpenID Connect (OIDC) Bearer 令牌身份验证"指南中的令牌验证和内省部分。https://docs.redhat.com/en/documentation/red_hat_build_of_quarkus/3.8/html/openid_connect_oidc_authentication/security-oidc-bearer-token-authentication#bearer-token-token-verification-introspection
使用 Quarkus web-app 应用程序时,默认只验证 IdToken,因为访问令牌没有用于访问当前的 Quarkus web-app 端点,并旨在传播到预期此访问令牌的服务。如果您希望访问令牌包含访问当前 Quarkus 端点所需的角色(quarkus.oidc.roles.source=accesstoken),则会验证它。
3.2.3.2. 令牌内省和 UserInfo 缓存 复制链接链接已复制到粘贴板!
代码流访问令牌不会被内省,除非它们应当是角色的来源。但是,它们将用于获取 UserInfo。如果令牌内省、UserInfo 或两者都需要,则需要一个或多个带有代码流访问令牌的远程调用。
有关使用默认令牌缓存或注册自定义缓存实现的更多信息,请参阅 令牌内省和用户Info 缓存。
3.2.3.3. JSON Web 令牌声明验证 复制链接链接已复制到粘贴板!
有关声明验证的详情,包括 iss (issuer)声明,请参阅 JSON Web 令牌声明验证 部分。如果 web-app 应用请求访问令牌验证,它适用于 ID 令牌以及 JWT 格式的访问令牌验证。
3.2.3.4. 进一步安全性,包括代码交换的证明密钥(PKCE) 复制链接链接已复制到粘贴板!
代码 交换的证明密钥 (PKCE)可最大程度降低授权代码拦截器的风险。
虽然 PKCE 是公共 OIDC 客户端的主要重要性,如在浏览器中运行的 SPA 脚本,但它还可以提供对 Quarkus OIDC web-app 应用程序的额外保护。使用 PKCE 时,Quarkus OIDC web-app 应用程序充当机密 OIDC 客户端,这些客户端可以安全地存储客户端 secret,并使用它来交换令牌的代码。
您可以使用 quarkus.oidc.authentication.pkce-required 属性和 32 个字符的 secret 为 OIDC web-app 端点启用 PKCE 代码验证器,如下例所示:
quarkus.oidc.authentication.pkce-required=true quarkus.oidc.authentication.state-secret=eUk1p7UB3nFiXZGUXi0uph1Y9p34YhBU
quarkus.oidc.authentication.pkce-required=true
quarkus.oidc.authentication.state-secret=eUk1p7UB3nFiXZGUXi0uph1Y9p34YhBU
如果您已有 32 个字符的客户端 secret,则不需要设置 quarkus.oidc.authentication.pkce-secret 属性,除非您更喜欢使用不同的 secret 密钥。如果没有配置此 secret,且在客户端 secret 小于 16 个字符时,无法自动生成此 secret。
当用户使用 code_challenge 查询参数重定向到 OIDC 供应商时,需要加密随机生成的 PKCE code_verifier。当用户重定向到 Quarkus 时,code_verifier 会解密,并发送到令牌端点,代码、客户端 secret 和其他参数来完成代码交换。如果 code_verifier 的 SHA256 摘要与身份验证请求过程中提供的 code_challenge 不匹配,则供应商将失败。
3.2.4. 处理和控制身份验证生命周期 复制链接链接已复制到粘贴板!
身份验证的另一个重要要求是确保会话基于的数据是最新的,而不需要用户为每个请求进行身份验证。在有些情况下,明确请求 logout 事件。使用以下关键点查找保护 Quarkus 应用程序的正确平衡:
3.2.4.1. Cookie 复制链接链接已复制到粘贴板!
OIDC 适配器使用 Cookie 来保留会话、代码流和超时状态。这个状态是控制身份验证数据生命周期的关键元素。
使用 quarkus.oidc.authentication.cookie-path 属性来确保当您访问具有重叠或不同根的受保护的资源时,可以看到相同的 Cookie。例如:
-
/index.htmland/web-app/service -
/web-app/service1and/web-app/service2 -
/web-app1/serviceand/web-app2/service
默认情况下,quarkus.oidc.authentication.cookie-path 被设置为 /,但如果需要,您可以将它改为更具体的路径,例如 /web-app。
要动态设置 Cookie 路径,请配置 quarkus.oidc.authentication.cookie-path-header 属性。设置 quarkus.oidc.authentication.cookie-path-header 属性。例如,要使用 'X-Forwarded-Prefix' HTTP 标头的值动态设置 Cookie 路径,请将 属性配置为 quarkus.oidc.authentication.cookie-path-header=X-Forwarded-Prefix。
如果设置了 quarkus.oidc.authentication.cookie-path-header,但当前请求中没有配置的 HTTP 标头,则会检查 quarkus.oidc.authentication.cookie-path。
如果您的应用程序在多个域中部署,请设置 quarkus.oidc.authentication.cookie-domain 属性,以便会话 Cookie 对所有受保护的 Quarkus 服务可见。例如,如果您在以下两个域中部署了 Quarkus 服务,您必须将 quarkus.oidc.authentication.cookie-domain 属性设置为 company.net :
- https://whatever.wherever.company.net/
- https://another.address.company.net/
3.2.4.2. 会话 Cookie 和默认 TokenStateManager 复制链接链接已复制到粘贴板!
OIDC CodeAuthenticationMechanism 使用默认的 io.quarkus.oidc.TokenStateManager 接口实现,以保留授权代码中返回的 ID、访问和刷新令牌,或在加密会话 Cookie 中刷新授权响应。
它使 Quarkus OIDC 端点完全无状态,建议遵循此策略来实现最佳的可扩展性结果。
有关令牌存储的替代方法,请参阅 Session cookie 和 custom TokenStateManager 部分。这对于那些希望自定义解决方案进行令牌状态管理的理想选择,特别是当标准服务器端存储不符合您的特定要求时。
您可以配置默认的 TokenStateManager,以避免在会话 Cookie 中保存访问令牌,并只保留 ID 和刷新令牌或单个 ID 令牌。
只有在端点需要执行以下操作时才需要访问令牌:
-
检索
UserInfo - 使用这个访问令牌访问下游服务
- 使用与访问令牌关联的角色,这些角色会被默认检查
在这种情况下,使用 quarkus.oidc.token-state-manager.strategy 属性来配置令牌状态策略,如下所示:
| to… | 将属性设置为 … |
|---|---|
| 只保留 ID 和刷新令牌 |
|
| 仅保留 ID 令牌 |
|
如果您所选的会话 Cookie 策略组合了令牌并生成大于 4KB 的大型会话 Cookie 值,则一些浏览器可能无法处理此类 Cookie 大小。当 ID、访问和刷新令牌是 JWT 令牌且所选策略为 keep-all-tokens 时,或者在策略 id-refresh-token 时使用 ID 和刷新令牌会出现这种情况。要临时解决这个问题,您可以设置 quarkus.oidc.token-state-manager.split-tokens=true 来为每个令牌创建一个唯一的会话令牌。
默认 TokenStateManager 会加密令牌,然后再将其存储在会话 Cookie 中。以下示例演示了如何将其配置为分割令牌并加密它们:
令牌加密 secret 必须至少为 32 个字符。如果没有配置此密钥,则 quarkus.oidc.credentials.secret 或 quarkus.oidc.credentials.jwt.secret 将会被哈希来创建加密密钥。
如果 Quarkus 使用以下身份验证方法之一向 OIDC 供应商进行身份验证,请配置 quarkus.oidc.token-state-manager.encryption-secret 属性:
- mTLS
-
private_key_jwt,其中使用私有 RSA 或 EC 密钥为 JWT 令牌签名
否则,会生成一个随机密钥,如果 Quarkus 应用程序在管理请求的多个 pod 在云中运行,则可能会造成问题。
您可以通过设置 quarkus.oidc.token-state-manager.encryption-required=false 来禁用会话 Cookie 中的令牌加密。
3.2.4.3. 会话 Cookie 和自定义 TokenStateManager 复制链接链接已复制到粘贴板!
如果要自定义令牌与会话 Cookie 关联的方式,请将自定义 io.quarkus.oidc.TokenStateManager 实现注册为 @ApplicationScoped CDI bean。
例如,您可能想要将令牌保留在缓存集群中,且只有一个密钥存储在会话 Cookie 中。请注意,如果您需要在多个微服务节点上提供令牌,这种方法可能会带来一些挑战。
以下是一个简单的示例:
有关将令牌存储在加密会话 Cookie 中的默认 TokenStateManager 的详情,请参考 Session cookie 和 default TokenStateManager。
3.2.4.4. 退出和过期 复制链接链接已复制到粘贴板!
身份验证信息过期的方法有两种:令牌过期且没有续订或显式退出操作。
我们从明确注销操作开始。
3.2.4.4.1. user-initiated logout 复制链接链接已复制到粘贴板!
用户可以通过向 Quarkus 端点注销路径发送请求,该路径使用 quarkus.oidc.logout.path 属性来请求注销。例如,如果端点地址为 https://application.com/webapp,并且 quarkus.oidc.logout.path 设置为 /logout,则必须将 logout 请求发送到 https://application.com/webapp/logout。
此注销请求将启动一个 RP-initiated logout。用户将被重定向到 OIDC 供应商以注销,并要求他们确认注销是否确实是正常的。
在注销完成后,用户将返回到端点 post-logout 页面,并且设置了 quarkus.oidc.logout.post-logout-path 属性。例如,如果端点地址为 https://application.com/webapp,并且 quarkus.oidc.logout.post-logout-path 设置为 /signin,则用户将返回到 https://application.com/webapp/signin。https://application.com/webapp/signin 请注意,此 URI 必须注册为 OIDC 供应商中的有效的 post_logout_redirect_uri。
如果设置了 quarkus.oidc.logout.post-logout-path,则会创建一个 q_post_logout cookie,并将匹配的 查询参数添加到注销重定向 URI 中,OIDC 供应商会在注销完成后返回此状态。建议 Quarkus state web-app 应用程序检查 state 查询参数是否与 q_post_logout cookie 的值匹配,例如在 Jakarta REST 过滤器中。
请注意,在使用 OpenID Connect Multi-Tenancy 时,cookie 名称会有所不同。例如,它将被命名为 q_post_logout_tenant_1,用于具有 tenant_1 ID 的租户,以此类推。
以下是如何配置 Quarkus 应用程序以启动注销流程的示例:
您可能还希望将 quarkus.oidc.authentication.cookie-path 设置为对所有应用程序资源通用的路径值,本例中为 /。如需更多信息,请参阅 Cookies 部分。
有些 OIDC 供应商不支持 RP-initiated logout 规格,且不会返回 OpenID Connect 已知的 end_session_endpoint 元数据属性。但是,这不是 Quarkus 的问题,因为此类 OIDC 供应商的特定注销机制仅在如何命名 logout URL 查询参数时有所不同。
根据 RP-initiated logout 规格,quarkus.oidc.logout.post-logout-path 属性表示为 post_logout_redirect_uri 查询参数,它不被不支持此规格的供应商识别。
您可以使用 quarkus.oidc.logout.post-logout-url-param 来临时解决这个问题。您还可以使用 quarkus.oidc.logout.extra-params 添加请求更多注销查询参数。例如,以下是如何使用 Auth0 支持注销:
3.2.4.4.2. back-channel logout 复制链接链接已复制到粘贴板!
OIDC 供应商可以使用身份验证数据强制注销所有应用程序。这称为 back-channel logout。在这种情况下,OIDC 将调用每个应用程序中的一个特定 URL 来触发该退出。
OIDC 供应商使用 Back-channel logout 从当前用户登录的所有应用程序注销,绕过用户代理。
您可以将 Quarkus 配置为支持 Back-channel logout,如下所示:
absolute back-channel logout URL 通过向当前端点 URL 添加 quarkus.oidc.back-channel-logout.path 来计算,例如 http://localhost:8080/back-channel-logout。您需要在 OIDC 供应商的管理控制台中配置此 URL。
如果您的 OIDC 供应商没有在当前注销令牌中设置到期声明,您还需要为退出令牌验证配置令牌 age 属性。例如,设置 quarkus.oidc.token.age=10S,以确保自注销令牌的 iat (在)时间后没有超过 10 秒。
3.2.4.4.3. front-channel logout 复制链接链接已复制到粘贴板!
您可以使用 Front-channel logout 直接从用户代理注销当前用户,例如其浏览器。它与 Back-channel logout 类似,但注销步骤由用户代理(如浏览器)执行,而不是在 OIDC 供应商在后台执行。这个选项很少被使用。
您可以配置 Quarkus 以支持 Front-channel logout,如下所示:
此路径将与当前请求的路径进行比较,如果这些路径匹配,用户将被注销。
3.2.4.4.4. 本地退出 复制链接链接已复制到粘贴板!
User-initiated logout 将从 OIDC 供应商注销用户。如果将其用作单点登录,这可能不是您需要的。例如,如果您的 OIDC 供应商是 Google,您将从 Google 及其服务中登出。相反,用户可能只希望退出该特定应用程序。另一个用例可能是 OIDC 供应商没有注销端点。
通过使用 OidcSession,您可以支持本地注销,这意味着只清除本地会话 cookie,如下例所示:
3.2.4.4.4.1. 使用 OidcSession 进行本地注销 复制链接链接已复制到粘贴板!
io.quarkus.oidc.OidcSession 是当前 IdToken 的打包程序,可帮助执行 本地注销,检索当前会话的租户标识符,并检查会话何时过期。随着时间的推移,将向它添加更有用的方法。
3.2.4.5. 会话管理 复制链接链接已复制到粘贴板!
默认情况下,注销基于 OIDC 供应商发布的 ID 令牌的过期时间。当 ID 令牌过期时,Quarkus 端点中的当前用户会话无效,用户会被重新重定向到 OIDC 供应商以进行身份验证。如果 OIDC 供应商中的会话仍然处于活跃状态,则用户会自动重新验证,而无需再次提供其凭证。
通过启用 quarkus.oidc.token.refresh-expired 属性,可以自动扩展当前用户会话。如果设置为 true,当当前 ID 令牌过期时,将使用刷新令牌授权来刷新 ID 令牌,以及访问和刷新令牌。
如果您有一个 用于服务应用程序的单个页面应用程序,您的 OIDC 供应商脚本(如 keycloak.js )正在管理授权代码流,则该脚本也会控制 SPA 身份验证会话生命周期。
如果您使用 Quarkus OIDC web-app 应用程序,则 Quarkus OIDC 代码身份验证机制管理用户会话生命周期。
要使用刷新令牌,您应该仔细配置会话 Cookie 年龄。会话年龄应超过 ID 令牌寿命,并且接近或等于刷新令牌生命周期。
您可以通过添加当前 ID 令牌的 lifespan 值以及 quarkus.oidc. authentication.session-age-extension 和 属性的值来计算会话年龄。
quarkus.oidc.token.lifespan-grace
如果需要,只使用 quarkus.oidc.authentication.session-age-extension 属性来显著扩展会话生命周期。您可以使用 quarkus.oidc.token.lifespan-grace 属性来考虑一些小时钟偏移。
当当前经过身份验证的用户返回到受保护的 Quarkus 端点并且与会话 Cookie 关联的 ID 令牌已过期时,默认情况下,用户会自动重定向到 OIDC Authorization 端点来重新验证。如果用户和此 OIDC 供应商间的会话仍然活跃,OIDC 供应商可能会再次挑战用户,如果会话配置为最后的时间超过 ID 令牌,则可能会出现这种情况。
如果 quarkus.oidc.token.refresh-expired 设为 true,则使用返回初始授权代码的刷新令牌刷新过期的 ID 令牌(和访问令牌)。此刷新令牌也可能被回收(刷新)本身作为此过程的一部分。因此,会创建新的会话 Cookie,会话会被扩展。
在用户未激活的情况下,您可以使用 quarkus.oidc.authentication.session-age-extension 属性来帮助处理过期的 ID 令牌。如果 ID 令牌过期,则会话 Cookie 可能不会在下一个用户请求期间返回到 Quarkus 端点,因为 Cookie 生命周期已过。Quarkus 假设此请求是第一个身份验证请求。将 quarkus.oidc.authentication.session-age-extension 设置为您的裸机用户,并根据您的安全策略。
您可以进一步进入一个步骤,并主动刷新 ID 令牌或访问令牌过期。将 quarkus.oidc.token.refresh-token-time-skew 设置为您要预计刷新的值。如果在当前用户请求过程中,计算当前 ID 令牌将在此 quarkus.oidc.token.refresh-token-time-skew 中过期,然后被刷新,并创建新的会话 cookie。此属性应设置为小于 ID 令牌生命周期的值;更接近这个生命周期值,ID 令牌会被刷新的频率。
您可以通过具有简单的 JavaScript 功能定期 ping Quarkus 端点来进一步优化这个过程,以模拟用户活动,从而减少用户必须重新验证的时间框架。
您无法无限期扩展用户会话。当刷新令牌已过期后,在 OIDC 供应商端点中的返回用户必须在 OIDC 供应商端点中重新进行身份验证。
3.2.5. 与 GitHub 和非OIDC OAuth2 供应商集成 复制链接链接已复制到粘贴板!
GitHub 或 LinkedIn 等一些已知的供应商不是 OpenID Connect 供应商,但支持 授权代码流的 OAuth2 供应商。例如,GitHub OAuth2 和 LinkedIn OAuth2。请记住,OIDC 基于 OAuth2 构建。
OIDC 和 OAuth2 供应商的主要区别在于,除了标准授权代码流 访问和 刷新 OAuth2 供应商返回的令牌外,OIDC 供应商还会返回一个代表用户身份验证的 ID 令牌。
GitHub 等 OAuth2 提供程序不返回 IdToken,用户身份验证是隐式的,间接由 访问令牌 表示。此 访问令牌 代表了一个经过身份验证的用户,授权当前的 Quarkus web-app 应用代表经过身份验证的用户访问某些数据。
对于 OIDC,您可以将 ID 令牌验证为身份验证的有效性,而在 OAuth2 时验证访问令牌。这随后通过调用需要访问令牌的端点,并且通常会返回用户信息来完成。这个方法与 OIDC UserInfo 方法类似,代表 Quarkus OIDC 获取的 UserInfo。
例如,在使用 GitHub 时,Quarkus 端点可以 获取访问令牌,它允许 Quarkus 端点为当前用户请求 GitHub 配置集。
要支持与这样的 OAuth2 服务器的集成,quarkus-oidc 需要以不同的方式配置,以允许在没有 IdToken:quarkus.oidc.authentication.id-token-required=false 的情况下配置授权代码流响应。
虽然您要将扩展配置为支持没有 IdToken 的授权代码流,但会生成内部 IdToken 来标准化 quarkus-oidc 操作的方式。您可以使用 IdToken 支持身份验证会话,并避免在每个请求上将用户重定向到供应商,如 GitHub。在这种情况下,会话寿命被设置为 5 分钟,您可以进一步进行扩展,如 会话管理 部分中所述。
这简化了如何处理支持多个 OIDC 供应商的应用程序。
下一步是确保返回的访问令牌很有用,并且对当前 Quarkus 端点有效。第一种方法是,如果提供商提供了这样的端点,则通过配置 quarkus.oidc.introspection-path 来调用 OAuth2 提供程序内省端点。在这种情况下,您可以使用 quarkus.oidc.roles.source=accesstoken 将访问令牌用作角色源。如果没有内省端点,您可以尝试从提供程序请求 UserInfo,因为它至少将验证访问令牌。为此,请指定 quarkus.oidc.token.verify-access-token-with-user-info=true。您还需要将 quarkus.oidc.user-info-path 属性设置为 URL 端点,该端点获取用户信息(或访问令牌保护的端点)。对于 GitHub,因为它没有内省端点,需要请求 UserInfo。
需要 UserInfo 涉及在每个请求上进行远程调用。因此,您可能需要考虑缓存 UserInfo 数据。如需更多信息,请参阅"OpenID Connect (OIDC) Bearer 令牌身份验证"指南中的 Token Introspection 和 UserInfo 缓存 部分。
或者,您可能希望请求将 UserInfo 嵌入到内部生成的 IdToken 中,并带有 quarkus.oidc.cache-user-info-in-idtoken=true 属性。这种方法的优点是,默认情况下,不会保留缓存的用户 Info 状态与端点 - 相反,它将存储在会话 Cookie 中。如果 UserInfo 包含敏感数据,您可能还需要考虑加密 IdToken。如需更多信息,请参阅使用 TokenStateManager 加密令牌。
OAuth2 服务器可能不支持已知的配置端点。在这种情况下,您必须禁用发现并配置授权、令牌和内省和 UserInfo 端点路径。
对于知名的 OIDC 或 OAuth2 供应商,如 Apple、Facebook、GitHub、Google、Microsoft、Spotify 和 Artistic,Quarkus 可使用 quarkus.oidc.provider 属性简化应用程序的配置。以下是您可以在创建 GitHub OAuth 应用程序后将 quarkus-oidc 与 GitHub 集成。配置 Quarkus 端点,如下所示:
有关配置其他已知的供应商的更多信息,请参阅 OpenID Connect 供应商。
这是端点所需要的,如这个端点使用 GET http://localhost:8080/github/userinfo 返回当前验证的用户配置集,并将其作为单独的 UserInfo 属性访问:
如果您支持多个社交供应商,它带有 OpenID Connect Multi-Tenancy 的帮助,例如 Google,它是一个 OIDC 供应商,返回 IdToken 和 GitHub,它是一个 OAuth2 供应商,它没有返回 IdToken,只允许访问 UserInfo,然后您可以让端点与 Google 和 GitHub 流注入的 SecurityIdentity 工作。当 GitHub 流处于活跃状态时,需要一个简单的 SecurityIdentity,其中使用内部生成的 IdToken 创建的主体将替换为基于 UserInfo的主体:
现在,当用户使用 Google 或 GitHub 登录应用程序时,以下代码将可以正常工作:
可能更为简单的替代方案是注入 @IdToken JsonWebToken 和 UserInfo,并在处理返回 IdToken 的提供程序时使用 JsonWebToken,并将 UserInfo 与不返回 IdToken 的提供程序一起使用。
您必须确保您在 GitHub OAuth 应用程序配置中输入的回调路径与希望在 GitHub 身份验证和应用程序授权成功后重定向用户的端点路径匹配。在这种情况下,它必须设置为 http:localhost:8080/github/userinfo。
3.2.6. 侦听重要的身份验证事件 复制链接链接已复制到粘贴板!
您可以注册 @ApplicationScoped bean,它将观察重要的 OIDC 身份验证事件。当用户第一次登录时,重新验证或刷新会话时,会更新监听程序。未来可能会报告更多事件。例如:
您可以侦听其他安全事件,如 Security Tips and Tricks 指南中的 Observe security events 部分所述。
3.2.7. 将令牌传播到下游服务 复制链接链接已复制到粘贴板!
有关授权代码流访问令牌传播到下游服务的详情,请参考 Token Propagation 部分。
3.3. 集成注意事项 复制链接链接已复制到粘贴板!
您的应用程序由 OIDC 集成在一个环境中,可以从单页应用程序调用。它必须与已知的 OIDC 供应商一起工作,在 HTTP Reverse Proxy 后面运行,需要外部和内部访问,等等。
本节讨论这些注意事项。
3.3.1. 单页应用程序 复制链接链接已复制到粘贴板!
您可以检查在"OpenID Connect (OIDC) Bearer 令牌身份验证"指南的 单页应用程序 部分中建议采用单页应用程序(SPAs)是否满足您的要求。
如果您希望使用带有 Quarkus Web 应用程序的 SPAs 和 JavaScript API,如 Fetch 或 XMLHttpRequest(XHR),请注意 OIDC 供应商可能不支持跨原始资源共享(CORS)进行授权端点,其中用户会在来自 Quarkus 的重定向后进行身份验证。如果 Quarkus 应用程序和 OIDC 供应商托管在不同的 HTTP 域、端口或两者上,则会导致身份验证失败。
在这种情况下,将 quarkus.oidc.authentication.java-script-auto-redirect 属性设置为 false,这将指示 Quarkus 返回 499 状态代码和带有 OIDC 值的 WWW-Authenticate 标头。
浏览器脚本必须设置标头,将当前请求标识为当 quarkus.oidc.authentication.java-script-auto-redirect 属性设置为 false 时返回的 499 状态代码的 JavaScript 请求。
如果脚本引擎设置特定于引擎的请求标头本身,您可以注册自定义 quarkus.oidc.JavaScriptRequestChecker bean,它将告知 Quarkus 如果当前请求是 JavaScript 请求。例如,如果 JavaScript 引擎设置标头,如 HX-Request: true,则可以进行检查,如下所示:
在 499 状态代码中,重新加载最后请求页面。
否则,还必须更新浏览器脚本,以使用 JavaScript 值设置 X-Requested-With 标头,并在 499 状态代码时重新加载最后一个请求页面。
例如:
3.3.2. 跨原始资源共享 复制链接链接已复制到粘贴板!
如果您计划从在不同域上运行的单页应用消耗此应用,则需要配置跨原始资源共享(CORS)。如需更多信息,请参阅"Cross-origin 资源共享"指南中的 CORS 过滤器 部分。
3.3.3. 在反向代理后面运行 Quarkus 应用程序 复制链接链接已复制到粘贴板!
如果您的 Quarkus 应用程序在反向代理、网关或防火墙后面运行,则 OIDC 身份验证机制可能会受到影响,当 HTTP 主机标头 可能会重置为内部 IP 地址,HTTPS 连接可能会被终止,以此类推。例如,授权代码流 redirect_uri 参数可能会设置为内部主机,而不是预期的外部。
在这种情况下,需要将 Quarkus 配置为识别代理转发的原始标头。如需更多信息,请参阅 反向代理 Vert.x 文档部分的运行。
例如,如果您的 Quarkus 端点在 Kubernetes Ingress 后面的集群中运行,则从 OIDC 供应商重新指向此端点的重定向可能无法正常工作,因为计算的 redirect_uri 参数可能指向内部端点地址。您可以使用以下配置来解决这个问题,其中 Kubernetes Ingress 设置 X-ORIGINAL-HOST 来代表外部端点地址:
quarkus.http.proxy.proxy-address-forwarding=true quarkus.http.proxy.allow-forwarded=false quarkus.http.proxy.enable-forwarded-host=true quarkus.http.proxy.forwarded-host-header=X-ORIGINAL-HOST
quarkus.http.proxy.proxy-address-forwarding=true
quarkus.http.proxy.allow-forwarded=false
quarkus.http.proxy.enable-forwarded-host=true
quarkus.http.proxy.forwarded-host-header=X-ORIGINAL-HOST
当 Quarkus 应用程序在 SSL 终止反向代理后面运行时,也可以使用 quarkus.oidc.authentication.force-redirect-https-scheme 属性。
3.3.4. 对 OIDC 供应商的外部和内部访问 复制链接链接已复制到粘贴板!
与 URL 自动发现或配置相对于 quarkus.oidc.auth-server-url 内部 URL 相比,OIDC 供应商外部可访问的授权、注销和其他端点可以有不同的 HTTP (S) URL。在这种情况下,端点可能会报告签发者验证失败,并重定向到外部访问的 OIDC 供应商端点可能会失败。
如果您使用 Keycloak,那么使用 KEYCLOAK_FRONTEND_URL 系统属性将其启动,设置为外部可访问的基本 URL。如果使用其他 OIDC 供应商,请查看您的供应商文档。
3.4. OIDC SAML 身份代理 复制链接链接已复制到粘贴板!
如果您的身份提供程序没有实现 OpenID Connect,而只有旧的基于 XML 的 SAML2.0 SSO 协议,则无法将 Quarkus 用作 SAML 2.0 适配器,类似于 quarkus-oidc 如何用作 OIDC 适配器。
但是,许多 OIDC 供应商,如 Keycloak、Okta、Auth0 和 Microsoft ADFS 为 SAML 2.0 网桥提供 OIDC。您可以在 OIDC 供应商中创建到 SAML 2.0 供应商的身份代理连接,并使用 quarkus-oidc 验证您的用户到此 SAML 2.0 供应商,并具有 OIDC 供应商协调 OIDC 和 SAML 2.0 通信。至于 Quarkus 端点,他们可以继续使用相同的 Quarkus Security、OIDC API、注释,如 @Authenticated、SecurityIdentity 等。
例如,假设 Okta 是您的 SAML 2.0 供应商,Keycloak 是您的 OIDC 供应商。以下是如何使用 Okta SAML 2.0 供应商将 Keycloak 配置为代理的典型序列。
首先,在 Okta Dashboard/Applications 中创建一个新的 SAML2 集成:
例如,将其命名为 OktaSaml :
接下来,将其配置为指向 Keycloak SAML 代理端点。此时,您需要知道 Keycloak 域的名称,如 quarkus,并假定 Keycloak SAML 代理别名为 saml,输入端点地址 http:localhost:8081/realms/quarkus/broker/saml/endpoint。输入服务供应商(SP)实体 ID 作为 http:localhost:8081/realms/quarkus,其中 http://localhost:8081 是 Keycloak 基础地址,saml 是代理别名:
接下来,保存此 SAML 集成并记录其元数据 URL:
接下来,在 Keycloak 中添加 SAML 供应商:
首先,照常创建新域或将现有域导入到 Keycloak。在这种情况下,域名必须是 quarkus。
现在,在 quarkus 域属性中,导航到 Identity Providers 并添加新的 SAML 供应商:
请注意,别名被设为 saml,Redirect URI 为 http:localhost:8081/realms/quarkus/broker/saml/endpoint,服务供应商实体 ID 为 http:localhost:8081/realms/quarkus - 与您在上一步中创建 Okta SAML 集成时输入的值相同。
最后,设置 Service entity descriptor 以指向上一步末尾的 Okta SAML 集成元数据 URL。
接下来,您可以导航到 Authentication/browser/Identity Provider Redirector config,将 Alias 和 Default Identity Provider 属性注册为默认提供程序,并将 Alias 和 Default Identity Provider 属性设为 saml。如果您没有将其配置为默认供应商,在身份验证时提供 2 个选项:
- 使用 SAML 供应商进行身份验证
- 直接使用名称和密码向 Keycloak 进行身份验证
现在,将 Quarkus OIDC web-app 应用程序配置为指向 Keycloak quarkus realm quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus。然后,您已准备好使用 OIDC 到 SAML 网桥(由 Keycloak OIDC 和 Okta SAML 2.0 供应商)向 Okta SAML 2.0 供应商验证 Quarkus 用户。
您可以配置其他 OIDC 供应商,以提供与为 Keycloak 执行的方式相似的 SAML 网桥。
3.5. 测试 复制链接链接已复制到粘贴板!
当测试涉及向独立的 OIDC 服务器进行身份验证时,测试通常很复杂。Quarkus 提供多个选项,从模拟到 OIDC 供应商的本地运行。
首先,将以下依赖项添加到 test 项目中:
使用 Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
testImplementation("net.sourceforge.htmlunit:htmlunit") testImplementation("io.quarkus:quarkus-junit5")testImplementation("net.sourceforge.htmlunit:htmlunit") testImplementation("io.quarkus:quarkus-junit5")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
3.5.1. Wiremock 复制链接链接已复制到粘贴板!
添加以下依赖项:
使用 Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-oidc-server</artifactId> <scope>test</scope> </dependency><dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-oidc-server</artifactId> <scope>test</scope> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
testImplementation("io.quarkus:quarkus-test-oidc-server")testImplementation("io.quarkus:quarkus-test-oidc-server")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
准备 REST 测试端点并设置 application.properties。例如:
keycloak.url is set by OidcWiremockTestResource
quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus/
quarkus.oidc.client-id=quarkus-web-app
quarkus.oidc.credentials.secret=secret
quarkus.oidc.application-type=web-app
# keycloak.url is set by OidcWiremockTestResource
quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus/
quarkus.oidc.client-id=quarkus-web-app
quarkus.oidc.credentials.secret=secret
quarkus.oidc.application-type=web-app
最后,编写测试代码,例如:
OidcWiremockTestResource 可识别 alice 和 admin 用户。用户 alice 默认具有用户角色 - 它可以通过 quarkus.test.oidc.token. 系统属性进行自定义。用户 user -rolesadmin 默认具有 用户和 admin 角色 - 它可以通过 quarkus.test.oidc.token.admin-roles 系统属性进行自定义。
另外,OidcWiremockTestResource 将令牌签发者和 audience 设置为 https://service.example.com,它可以通过 quarkus.test.oidc.token.issuer 和 quarkus.test.oidc.token.audience 系统属性进行自定义。
OidcWiremockTestResource 可用于模拟所有 OIDC 供应商。
3.5.2. Keycloak 的 dev Services 复制链接链接已复制到粘贴板!
建议对 Keycloak 使用 Dev Services 进行 集成测试。用于 Keycloak 的 dev Services 将启动并初始化测试容器:它将创建一个 quarkus 域、quarkus-app 客户端(secret secret),并添加 alice (admin 和 roles)和 user bob (用户角色)用户,您可以在其中自定义所有这些属性。
首先,准备 application.properties。您可以从完全空的 application.properties 文件作为 Keycloak 的 Dev Services 开始,注册指向正在运行的测试容器的 quarkus.oidc.auth-server-url,以及 quarkus.oidc.client-id=quarkus-app 和 quarkus.oidc.credentials.secret=secret。
但是,如果您已经配置了所有必需的 quarkus-oidc 属性,则您只需要将 quarkus.oidc.auth-server-url 与 Keycloak 的 Dev Services 的 prod 配置集关联,才能启动容器。例如:
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
如果在运行测试前必须将自定义域文件导入到 Keycloak 中,您可以为 Keycloak 配置 Dev Services,如下所示:
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus quarkus.keycloak.devservices.realm-path=quarkus-realm.json
%prod.quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus
quarkus.keycloak.devservices.realm-path=quarkus-realm.json
最后,按照与 Wiremock 部分相同的方式编写测试代码。唯一的区别是 @QuarkusTestResource 不再需要:
@QuarkusTest
public class CodeFlowAuthorizationTest {
}
@QuarkusTest
public class CodeFlowAuthorizationTest {
}
3.5.3. TestSecurity 注解 复制链接链接已复制到粘贴板!
您可以使用 @TestSecurity 和 @OidcSecurity 注释来测试 web-app 应用端点代码,这取决于以下注入之一,或者全部四个:
-
ID
JsonWebToken -
Access
JsonWebToken -
UserInfo -
OidcConfigurationMetadata
有关更多信息,请参阅将 TestingSecurity 与注入的 JsonWebToken 搭配使用。
3.5.4. 检查日志中的错误 复制链接链接已复制到粘贴板!
要查看有关令牌验证错误的详情,您必须启用 io.quarkus.oidc.runtime.OidcProvider TRACE 级别日志记录:
quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".level=TRACE quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".min-level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcProvider".min-level=TRACE
要查看有关 OidcProvider 客户端初始化错误的详细信息,请启用 io.quarkus.oidc.runtime.OidcRecorder TRACE 级别日志记录:
quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".level=TRACE quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".min-level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".level=TRACE
quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".min-level=TRACE
从 quarkus dev 控制台,键入 j 以更改应用全局日志级别。
3.6. 参考 复制链接链接已复制到粘贴板!
第 4 章 使用 OpenID Connect (OIDC)授权代码流保护 Web 应用程序 复制链接链接已复制到粘贴板!
探索如何使用 Quarkus OpenID Connect (OIDC)授权代码流机制以及 Quarkus OIDC 扩展来保护应用程序 HTTP 端点,从而提供强大的身份验证和授权。
如需更多信息,请参阅 用于保护 Web 应用程序的 OIDC 代码流机制。
要了解知名的社交提供商(如 Apple、Facebook、GitHub、Google、Maasy、Microsoft、Twitch、Twitch、Twitch、Twitch 和 Spotify 如何与 Quarkus OIDC 一起使用,请参阅配置已知的 OpenID Connect 供应商。请参阅 Quarkus 中的验证机制。
如果要使用 OIDC Bearer 令牌身份验证来保护服务应用程序,请参阅 OIDC Bearer 令牌身份验证。
4.1. 先决条件 复制链接链接已复制到粘贴板!
要完成本指南,您需要:
- 大约 15 分钟
- IDE
-
正确配置了
JAVA_HOME的 JDK 17+ - Apache Maven 3.9.6
- 正常工作的容器运行时(Docker 或 Podman)
- 如果要使用 Quarkus CLI,可选
- 如果要构建原生可执行文件(或者使用原生容器构建,则可选的 Mandrel 或 GraalVM) https://quarkus.io/version/3.8/guides/building-native-image#configuring-graalvm
4.2. 架构 复制链接链接已复制到粘贴板!
在这个示例中,我们使用单个页面构建一个简单的 Web 应用程序:
-
/index.html
此页面受到保护,只有经过身份验证的用户才能访问它。
4.3. 解决方案 复制链接链接已复制到粘贴板!
按照下一小节中的说明,并逐步创建应用程序步骤。或者,您可以右到已完成的示例。
运行 git clone https://github.com/quarkusio/quarkus-quickstarts.git -b 3.8 命令克隆 Git 存储库。或者,下载 存档。
解决方案位于 security-openid-connect-web-authentication-quickstart 目录中。
4.4. 创建 Maven 项目 复制链接链接已复制到粘贴板!
首先,我们需要新的项目。运行以下命令创建新项目:
使用 Quarkus CLI:
quarkus create app org.acme:security-openid-connect-web-authentication-quickstart \ --extension='resteasy-reactive,oidc' \ --no-code cd security-openid-connect-web-authentication-quickstartquarkus create app org.acme:security-openid-connect-web-authentication-quickstart \ --extension='resteasy-reactive,oidc' \ --no-code cd security-openid-connect-web-authentication-quickstartCopy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加--
gradle or--gradle-kotlin-dsl选项。有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。
使用 Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加
-DbuildTool=gradleor-DbuildTool=gradle-kotlin-dsl选项。
对于 Windows 用户:
-
如果使用 cmd,(不要使用反向斜杠
\并将所有内容放在同一行中) -
如果使用 Powershell,则双引号中的 wrap
-D参数,如"-DprojectArtifactId=security-openid-connect-web-authentication-quickstart"
如果您已经配置了 Quarkus 项目,您可以通过在项目基本目录中运行以下命令来将 oidc 扩展添加到项目中:
使用 Quarkus CLI:
quarkus extension add oidc
quarkus extension add oidcCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:add-extension -Dextensions='oidc'
./mvnw quarkus:add-extension -Dextensions='oidc'Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew addExtension --extensions='oidc'
./gradlew addExtension --extensions='oidc'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
这会在您的构建文件中添加以下依赖项:
使用 Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency>
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
implementation("io.quarkus:quarkus-oidc")implementation("io.quarkus:quarkus-oidc")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
4.5. 编写应用程序 复制链接链接已复制到粘贴板!
我们编写一个简单的 Jakarta REST 资源,该资源在授权代码授予响应中返回的所有令牌:
此端点注入了 ID、访问和刷新令牌。它从 ID 令牌、访问令牌中的 范围 声明和刷新令牌可用性状态返回 preferred_username 声明。
只有在端点需要使用 ID 令牌与当前经过身份验证的用户交互时,您只需要注入令牌,或使用访问令牌代表此用户访问下游服务。
如需更多信息,请参阅参考指南中的 访问 ID 和访问令牌 部分。
4.6. 配置应用程序 复制链接链接已复制到粘贴板!
OIDC 扩展允许您使用 src/main/resources 目录中的 application.properties 文件来定义配置。
这是在为应用程序启用身份验证时可以拥有的最简单配置。
quarkus.oidc.client-id 属性引用 OIDC 供应商发布的 client_id,quarkus.oidc.credentials.secret 属性设置客户端 secret。
quarkus.oidc.application-type 属性被设置为 web-app 告知 Quarkus 您要启用 OIDC 授权代码流,以便您的用户重定向到 OIDC 供应商进行验证。
最后,quarkus.http.auth.permission.authenticated 权限被设置为告诉 Quarkus 您要保护的路径。在这种情况下,所有路径都由策略保护,以确保只有 经过身份验证的用户 可以访问它们。有关更多信息,请参阅 安全授权指南。
4.7. 启动并启用 Keycloak 服务器 复制链接链接已复制到粘贴板!
要启动 Keycloak 服务器,请使用 Docker 并运行以下命令:
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
其中 keycloak.version 设置为 24.0.0 或更高版本。
您可以在 localhost:8180 访问您的 Keycloak 服务器。
要访问 Keycloak 管理控制台,请以 admin 用户身份登录。用户名和密码都是 admin。
要创建新域,请导入 realm 配置文件。如需更多信息,请参阅关于如何 创建和配置新域的 Keycloak 文档。
4.8. 在 dev 和 JVM 模式下运行应用程序 复制链接链接已复制到粘贴板!
要在 dev 模式下运行应用程序,请使用:
使用 Quarkus CLI:
quarkus dev
quarkus devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:dev
./mvnw quarkus:devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew --console=plain quarkusDev
./gradlew --console=plain quarkusDevCopy to Clipboard Copied! Toggle word wrap Toggle overflow
在以 dev 模式探索应用后,您可以将其作为标准 Java 应用运行。
首先,编译它:
使用 Quarkus CLI:
quarkus build
quarkus buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install
./mvnw installCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build
./gradlew buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow
然后运行它:
java -jar target/quarkus-app/quarkus-run.jar
java -jar target/quarkus-app/quarkus-run.jar
4.9. 以原生模式运行应用程序 复制链接链接已复制到粘贴板!
相同的演示可编译到原生代码中。不需要修改。
这意味着,您不再需要在生产环境中安装 JVM,因为运行时技术包含在生成的二进制中,并优化以最小资源运行。
编译需要更长的时间,因此默认关闭此步骤。您可以通过启用原生构建来再次构建:
使用 Quarkus CLI:
quarkus build --native
quarkus build --nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install -Dnative
./mvnw install -DnativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build -Dquarkus.package.type=native
./gradlew build -Dquarkus.package.type=nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow
在一段时间后,您可以直接运行这个二进制文件:
./target/security-openid-connect-web-authentication-quickstart-runner
./target/security-openid-connect-web-authentication-quickstart-runner
4.10. 测试应用 复制链接链接已复制到粘贴板!
要测试应用程序,请打开浏览器并访问以下 URL:
如果所有内容都按预期工作,您会被重定向到 Keycloak 服务器以进行身份验证。
要向应用程序进行身份验证,请在 Keycloak 登录页面中输入以下凭证:
- 用户名: alice
- 密码 : alice
点 Login 按钮后,您将重新重定向到应用程序,并创建一个会话 Cookie。
此演示的会话在短时间内有效,每次页面刷新时,将要求您重新验证。有关如何增加会话超时的详情,请参考 Keycloak 会话超时 文档。例如,如果您在 dev 模式下使用 Dev Services for Keycloak Admin 链接,您可以从 dev UI 直接访问 Keycloak Admin 控制台:
有关编写依赖于 Keycloak 的 Dev Services 的集成测试的更多信息,请参阅 Keycloak 的 Dev Services 部分。
4.11. 概述 复制链接链接已复制到粘贴板!
您已了解如何设置和使用 OIDC 授权代码流机制来保护和测试应用程序 HTTP 端点。完成本教程后,探索 OIDC Bearer 令牌身份验证 和其他身份验证机制。
4.12. 参考 复制链接链接已复制到粘贴板!
第 5 章 使用 OpenID Connect (OIDC)多租户 复制链接链接已复制到粘贴板!
本指南演示了您的 OpenID Connect (OIDC)应用程序如何支持多租户,以从单个应用程序提供多个租户。这些租户可以是同一 OIDC 供应商中的不同域或安全域,甚至不同的 OIDC 供应商。
在为来自同一应用程序的多个客户(如在 SaaS 环境中)提供服务时,每个客户都可以作为不同的租户。通过启用对应用程序的多租户支持,您可以支持每个租户的不同身份验证策略,甚至针对不同的 OIDC 供应商(如 Keycloak 和 Google)进行身份验证。
要使用 Bearer Token Authorization 授权租户,请参阅 OpenID Connect (OIDC) Bearer 令牌身份验证 指南。
要使用 OIDC 授权代码流验证和授权租户,请阅读 用于保护 Web 应用程序指南的 OpenID Connect 授权代码流机制。
另外,请参阅 OpenID Connect (OIDC)配置属性 参考指南。
5.1. 先决条件 复制链接链接已复制到粘贴板!
要完成本指南,您需要:
- 大约 15 分钟
- IDE
-
正确配置了
JAVA_HOME的 JDK 17+ - Apache Maven 3.9.6
- 正常工作的容器运行时(Docker 或 Podman)
- 如果要使用 Quarkus CLI,可选
- 如果要构建原生可执行文件(或者使用原生容器构建,则可选的 Mandrel 或 GraalVM) https://quarkus.io/version/3.8/guides/building-native-image#configuring-graalvm
- jq 工具
5.2. 架构 复制链接链接已复制到粘贴板!
在这个示例中,我们构建一个支持两种资源方法的简单应用程序:
-
/{tenant}
此资源返回从 OIDC 供应商发布的有关经过身份验证的用户和当前租户发布的 ID 令牌获取的信息。
-
/{tenant}/bearer
此资源返回从 OIDC 供应商发布的有关经过身份验证的用户和当前租户发布的访问令牌获取的信息。
5.3. 解决方案 复制链接链接已复制到粘贴板!
为了充分理解,我们建议您按照接下来的逐步说明来构建应用程序。
或者,如果您想从已完成的示例开始,克隆 Git 存储库: git clone https://github.com/quarkusio/quarkus-quickstarts.git -b 3.8 或下载 归档。
该解决方案位于 security-openid-connect-multi-tenancy-quickstart 目录中。
5.4. 创建 Maven 项目 复制链接链接已复制到粘贴板!
首先,我们需要新的项目。使用以下命令创建新项目:
使用 Quarkus CLI:
quarkus create app org.acme:security-openid-connect-multi-tenancy-quickstart \ --extension='oidc,resteasy-reactive-jackson' \ --no-code cd security-openid-connect-multi-tenancy-quickstartquarkus create app org.acme:security-openid-connect-multi-tenancy-quickstart \ --extension='oidc,resteasy-reactive-jackson' \ --no-code cd security-openid-connect-multi-tenancy-quickstartCopy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加--
gradle or--gradle-kotlin-dsl选项。有关如何安装和使用 Quarkus CLI 的更多信息,请参阅 Quarkus CLI 指南。
使用 Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要创建 Gradle 项目,请添加
-DbuildTool=gradleor-DbuildTool=gradle-kotlin-dsl选项。
对于 Windows 用户:
-
如果使用 cmd,(不要使用反向斜杠
\并将所有内容放在同一行中) -
如果使用 Powershell,则双引号中的 wrap
-D参数,如"-DprojectArtifactId=security-openid-connect-multi-tenancy-quickstart"
如果您已经配置了 Quarkus 项目,请在项目基本目录中运行以下命令来将 oidc 扩展添加到项目中:
使用 Quarkus CLI:
quarkus extension add oidc
quarkus extension add oidcCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:add-extension -Dextensions='oidc'
./mvnw quarkus:add-extension -Dextensions='oidc'Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew addExtension --extensions='oidc'
./gradlew addExtension --extensions='oidc'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
这会在构建文件中添加以下内容:
使用 Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency><dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
implementation("io.quarkus:quarkus-oidc")implementation("io.quarkus:quarkus-oidc")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
5.5. 编写应用程序 复制链接链接已复制到粘贴板!
首先实施 /{tenant} 端点。正如您在以下源代码中看到的那样,它只是常规 Jakarta REST 资源:
要从传入请求解析租户并将其映射到 application.properties 中的特定 quarkus-oidc 租户配置,请为 io.quarkus.oidc.TenantConfigResolver 接口创建一个实现,它可以动态解析租户配置:
在前面的实现中,租户是从请求路径解析的。如果没有租户推断出来,则返回 null 以指示应使用默认租户配置。
tenant-a 应用类型是 hybrid ;如果提供,它可以接受 HTTP bearer 令牌。否则,它会在需要身份验证时启动授权代码流。
5.6. 配置应用程序 复制链接链接已复制到粘贴板!
第一个配置是默认租户配置,应在无法从请求中推断租户时使用。请注意,%prod 配置集前缀与 quarkus.oidc.auth-server-url 一起使用,以支持使用 Dev Services for Keycloak 测试多租户应用程序。此配置使用 Keycloak 实例来验证用户。
当传入请求映射到 tenant-a 租户时,会使用由 TenantConfigResolver 提供的第二个配置。
这两个配置都会映射到同一 Keycloak 服务器实例,同时使用 不同的域。
或者,您可以在 application.properties 中直接配置 tenant-a :
在这种情况下,也使用自定义 TenantConfigResolver 来解析它:
您可以在 配置文件中定义多个租户。要在从 TenantResolver 实现解析租户时正确映射它们,请确保每个租户都有唯一的别名。
但是,使用静态租户解析(涉及在 application.properties 中配置租户)并使用 TenantResolver 解析它们以使用 Keycloak 的 Dev Services 测试端点,因为它不知道请求如何映射到单独的租户,且无法动态提供租户特定的 quarkus.oidc.<tenant-id>.auth-server-url 值。因此,在 application.properties 中使用 %prod 前缀和特定于租户的 URL 都无法在测试和开发模式下工作。
当当前租户代表 OIDC web-app 应用程序时,当前的 io.vertx.ext.web.RoutingContext 包含 tenant-id 属性,只要为完成代码身份验证流的所有请求以及已验证的、已验证的状态或会话 Cookie 都会调用 tenant-id 属性。因此,在使用多个 OIDC 供应商时,您只需要特定于路径的检查来解析租户 ID (如果 RoutingContext 没有设置 tenant-id 属性),例如:
如果没有注册自定义 TenantResolver,这是 Quarkus OIDC 如何解析静态自定义租户。
类似的技术可与 TenantConfigResolver 一起使用,其中上下文中提供的 tenant-id 可以返回 OidcTenantConfig 已在上一个请求中准备。
如果您也 使用带有 Panache 多租户的 Hibernate ORM 多租户 或 MongoDB,并且租户 ID 相同,且必须从 Vert.x RoutingContext 中提取,您可以从 OIDC Tenant Resolver 将租户 ID 传给 Hibernate ORM Tenant Resolver 或带有 Panache Mongo Database Resolver 作为 RoutingContext 属性的 MongoDB,例如:
5.7. 启动并配置 Keycloak 服务器 复制链接链接已复制到粘贴板!
要启动 Keycloak 服务器,您可以使用 Docker 并运行以下命令:
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
docker run --name keycloak -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -p 8180:8080 quay.io/keycloak/keycloak:{keycloak.version} start-dev
其中 keycloak.version 设置为 24.0.0 或更高版本。
在 localhost:8180 访问您的 Keycloak 服务器。
以 admin 用户身份登录,以访问 Keycloak 管理控制台。用户名和密码都是 admin。
现在,导入两个租户的域:
- 导入 default-tenant-realm.json 以创建默认域。
-
导入 tenant-a-realm.json,为租户
tenant-a创建域。
如需更多信息,请参阅关于如何创建新域的 Keycloak 文档。https://www.keycloak.org/docs/latest/server_admin/index.html#_create-realm
5.8. 运行并使用应用程序 复制链接链接已复制到粘贴板!
5.8.1. 在开发人员模式下运行 复制链接链接已复制到粘贴板!
要在 dev 模式下运行微服务,请使用:
使用 Quarkus CLI:
quarkus dev
quarkus devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw quarkus:dev
./mvnw quarkus:devCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew --console=plain quarkusDev
./gradlew --console=plain quarkusDevCopy to Clipboard Copied! Toggle word wrap Toggle overflow
5.8.2. 在 JVM 模式下运行 复制链接链接已复制到粘贴板!
在以 dev 模式探索应用后,您可以将其作为标准 Java 应用运行。
首先,编译它:
使用 Quarkus CLI:
quarkus build
quarkus buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install
./mvnw installCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build
./gradlew buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow
然后运行它:
java -jar target/quarkus-app/quarkus-run.jar
java -jar target/quarkus-app/quarkus-run.jar
5.8.3. 在原生模式下运行 复制链接链接已复制到粘贴板!
相同的演示可以编译到原生代码中,不需要修改。
这意味着,您不再需要在生产环境中安装 JVM,因为运行时技术包含在生成的二进制文件中,并优化以最小资源运行。
编译时间会比较较长,因此默认关闭此步骤;通过启用原生构建来再次进行构建:
使用 Quarkus CLI:
quarkus build --native
quarkus build --nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Maven:
./mvnw install -Dnative
./mvnw install -DnativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Gradle:
./gradlew build -Dquarkus.package.type=native
./gradlew build -Dquarkus.package.type=nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow
片刻后,您可以直接运行此二进制文件:
./target/security-openid-connect-multi-tenancy-quickstart-runner
./target/security-openid-connect-multi-tenancy-quickstart-runner
5.9. 测试应用 复制链接链接已复制到粘贴板!
5.9.1. 使用浏览器 复制链接链接已复制到粘贴板!
要测试应用程序,请打开浏览器并访问以下 URL:
如果所有内容都按预期工作,您会被重定向到 Keycloak 服务器以进行身份验证。请注意,请求的路径定义了一个 默认租户,我们没有在配置文件中映射该租户。在这种情况下,会使用默认配置。
要向应用程序进行身份验证,请在 Keycloak 登录页面中输入以下凭证:
-
用户名:
alice -
密码 :
alice
点 Login 按钮后,您将重新重定向到应用程序。
如果您现在尝试通过以下 URL 访问应用程序:
您再次重定向到 Keycloak 登录页面。但是,这次您要使用不同的域进行身份验证。
在这两种情况下,如果用户成功通过身份验证,则登录页面会显示用户的名称和电子邮件。虽然 alice 在两个租户中存在,但应用会将它们视为单独的域中的不同用户。
5.10. 静态租户配置解析 复制链接链接已复制到粘贴板!
当您在 application.properties 文件中设置多个租户配置时,您只需要指定租户标识符的解析方式。要配置租户标识符的解析,请使用以下选项之一:
这些租户解析选项会按照列出的顺序尝试,直到租户 id 被解决为止。如果租户 id 仍然未解析(null),则会选择默认(未命名)租户配置。
5.10.1. 使用 TenantResolver解析 复制链接链接已复制到粘贴板!
以下 application.properties 示例演示了如何使用 TenantResolver 方法解析名为 a 和 b 的两个租户的租户标识符:
您可以从 quarkus.oidc.TenantResolver 返回 a 或 b 的租户 ID:
在本例中,最后一个请求路径片段的值是一个租户 id,但如果需要,您可以实施更复杂的租户标识符解析逻辑。
5.10.2. 默认解析 复制链接链接已复制到粘贴板!
租户标识符的默认解析基于惯例,身份验证请求必须在请求路径的最后片段中包含租户标识符。
以下 application.properties 示例演示了如何配置名为 google 和 github 的两个租户:
在提供的示例中,两个租户都将 OIDC web-app 应用程序配置为使用授权代码流来验证用户,并在身份验证后生成会话 Cookie。在 Google 或 GitHub 验证当前用户后,用户将返回到经过身份验证的用户的 /signed-in 区域,如 JAX-RS 端点上的安全资源路径。
最后,要完成默认租户解析,请设置以下配置属性:
quarkus.http.auth.permission.login.paths=/google,/github quarkus.http.auth.permission.login.policy=authenticated
quarkus.http.auth.permission.login.paths=/google,/github
quarkus.http.auth.permission.login.policy=authenticated
如果端点在 http://localhost:8080 上运行,您也可以为用户提供登录到 http://localhost:8080/google 或 http://localhost:8080/github 的 UI 选项,而无需添加特定的 /google 或 /github JAX-RS 资源路径。身份验证完成后,租户标识符也会记录在会话 Cookie 名称中。因此,经过身份验证的用户可以访问安全应用程序区域,而无需将 google 或 github 路径值包含在安全 URL 中。
默认解析也可以用于 Bearer 令牌身份验证。仍然可能不太实际,因为租户标识符必须始终设置为最后一个路径片段值。
5.10.3. 使用注解解析 复制链接链接已复制到粘贴板!
您可以使用 io.quarkus.oidc.Tenant 注解来解析租户标识符,作为使用 io.quarkus.oidc.TenantResolver 的替代选择。
必须禁用主动 HTTP 身份验证(quarkus.http.auth.proactive=false)才能使它正常工作。如需更多信息,请参阅 主动身份验证 指南。
假设应用程序支持两个 OIDC 租户( hr 和 default 租户),所有带 @Tenant ("hr") 的资源方法和类都通过使用 quarkus.oidc.hr.auth-server-url 配置的 OIDC 供应商进行身份验证。相反,所有其他类和方法仍然通过使用默认 OIDC 供应商进行身份验证。
- 1
io.quarkus.oidc.Tenant注解必须放在资源类或资源方法上。
5.11. 动态租户配置解析 复制链接链接已复制到粘贴板!
如果您需要为需要支持的不同租户进行更多动态配置,且不想与配置文件中的多个条目结束,您可以使用 io.quarkus.oidc.TenantConfigResolver。
此接口允许您在运行时动态创建租户配置:
此方法返回的 OidcTenantConfig 与从 application.properties 解析 oidc 命名空间配置的方式相同。您可以使用 quarkus-oidc 扩展支持的任何设置来填充它。
如果动态租户解析器返回 null,则下一步会尝试 静态租户配置解析。
5.11.1. OIDC web-app 应用程序的租户解析 复制链接链接已复制到粘贴板!
解析 OIDC web-app 应用程序配置的最简单选项是按照 Default resolution 部分中描述的步骤进行操作。
如果默认解析策略不适用于应用程序设置,请尝试以下其中一个选项。
有几个选项可用于选择租户配置,这些配置应该用来保护 服务和 web-app OIDC 应用程序的当前 HTTP 请求,例如:
-
检查 URL 路径。例如,
tenant-service配置必须用于/service路径,而tenant-manage配置必须用于/management路径。 -
检查 HTTP 标头。例如,如果 URL 路径始终为
/service,一个标头(如Realm: service或Realm: 管理)可帮助选择tenant-service和tenant-manage配置。 - 检查 URL 查询参数。它的工作方式与标头用于选择租户配置的方式类似。
所有这些选项都可以使用 OIDC 服务 应用程序的 custom TenantResolver 和 TenantConfigResolver 实现轻松实现。
但是,由于 HTTP 重定向需要完成 OIDC web-app 应用程序的代码身份验证流,可能需要自定义 HTTP cookie 以在此重定向请求前后选择相同的租户配置,因为:
- 如果在 OIDC 供应商中注册了单个重定向 URL,在重定向请求后 URL 路径可能不同。在租户配置解决后,可以恢复原始请求路径。
- 重定向后,原始请求中使用的 HTTP 标头不可用。
- 自定义 URL 查询参数在重定向后恢复,但仅在租户配置解决后恢复。
其中一个选项是确保解析 web-app 应用程序的租户配置的信息在重定向之前和之后可用,例如:
5.12. 禁用租户配置 复制链接链接已复制到粘贴板!
如果没有可以从当前请求中推断租户,并且需要回退到默认租户配置,则自定义 TenantResolver 和 TenantConfigResolver 实现可能会返回 null。
如果您期望自定义解析器始终解析租户,则不需要配置默认租户解析。
-
要关闭默认租户配置,请设置
quarkus.oidc.tenant-enabled=false。
当 quarkus.oidc.auth-server-url 没有配置时,默认的租户配置会被自动禁用,但自定义租户配置可用,或者为 TenantConfigResolver 注册。
请注意,特定于租户的配置也可以禁用,例如: quarkus.oidc.tenant-a.tenant-enabled=false。
5.13. 参考 复制链接链接已复制到粘贴板!
第 6 章 OpenID Connect (OIDC)配置属性 复制链接链接已复制到粘贴板!
作为 Quarkus 开发人员,您可以通过在 src/main/resources/application.properties 文件中设置以下属性来配置 Quarkus OpenID Connect (OIDC)扩展。
构建时修复的配置属性 - 所有其他配置属性可在运行时覆盖
|
| 类型 | default |
|
用于启用(默认)或禁用 Dev 服务的标志。启用后,Keycloak 的 Dev Services 会在 Dev 或 Test 模式中自动配置并启动 Keycloak,以及 Docker 运行时。
环境变量: | 布尔值 |
|
|
Dev Services 供应商的容器镜像名称。默认为基于 Quarkus 的 Keycloak 镜像。对于基于 WildFly 的发布,请使用
环境变量: | string |
|
|
指明是否使用 Keycloak-X 镜像。默认情况下,镜像由镜像名称中的
环境变量: | 布尔值 | |
|
确定 Keycloak 容器是否已共享。共享时,Quarkus 使用基于标签的服务发现来查找和重复使用正在运行的 Keycloak 容器,因此没有启动第二个容器。否则,如果没有找到匹配的容器,则会启动一个新容器。服务发现使用
环境变量: | 布尔值 |
|
|
环境变量: | string |
|
|
以逗号分隔的到 Keycloak 域文件的类或文件系统路径列表。此列表用于初始化 Keycloak。此列表中的第一个值用于初始化默认租户连接属性。
环境变量: | 字符串列表 | |
|
传递给 keycloak JVM 的
环境变量: | string | |
|
显示带有 "Keycloak:" 前缀的 Keycloak 日志消息。
环境变量: | 布尔值 |
|
|
Keycloak start 命令。使用此属性试验 Keycloak 启动选项,请参阅
环境变量: | string | |
|
Keycloak 域的名称。如果
环境变量: | string | |
|
指定是否在
环境变量: | 布尔值 |
|
|
要侦听的 dev 服务的具体端口。 如果没有指定,则会选择一个随机端口。
环境变量: | int | |
|
用于初始化 Keycloak 的额外类或文件系统资源的别名。每个映射条目代表别名和类或文件系统资源路径之间的映射。
环境变量: |
| |
|
用于初始化 Keycloak 的其他类或文件系统资源。每个映射条目代表类或文件系统资源路径别名和 Keycloak 容器位置之间的映射。
环境变量: |
| |
|
Keycloak 用户名与密码映射。如果为空,则创建默认用户
环境变量: |
| |
|
Keycloak 用户的角色映射。如果为空,则分配默认角色:
环境变量: |
| |
|
要传递给容器的环境变量。
环境变量: |
| |
|
如果启用了 OIDC 扩展。
环境变量: | 布尔值 |
|
|
授权类型,用于获取令牌来测试 OIDC 'service' 应用程序
环境变量: | 工具提示:client['client_credentials' grant], tooltip:password['password' grant], tooltip:code['authorization_code' grant], tooltip:implicit['implicit' grant] | |
|
WebClient 超时。使用此属性配置 Dev UI 处理程序使用的 HTTP 客户端在从 OpenId Connect Provider 请求令牌并将其发送到服务端点时,将等待响应。OIDC dev 服务管理客户端也使用此超时。
环境变量: |
| |
|
启用注册 Default TokenIntrospection 和 UserInfo Cache 实现 bean。注: 这仅启用默认的实施。它需要激活配置。请参阅
环境变量: | 布尔值 |
|
|
OpenID Connect (OIDC)服务器的基本 URL,例如
环境变量: | string | |
|
发现 OIDC 端点。如果没有启用,您必须单独配置 OIDC 端点 URL。
环境变量: | 布尔值 |
|
|
签发访问和刷新令牌的 OIDC 令牌端点;指定为相对路径或绝对 URL。如果
环境变量: | string | |
|
OIDC 令牌撤销端点的相对路径或绝对路径 URL。
环境变量: | string | |
|
应用程序的客户端 ID。每个应用都有一个客户端 ID,用于标识应用程序。如果
环境变量: | string | |
|
尝试初始连接到 OIDC 服务器的持续时间。例如,将持续时间设置为
环境变量: | ||
|
如果临时丢失,重试重新建立现有 OIDC 连接的次数。与
环境变量: | int |
|
|
当前 OIDC 连接请求超时的秒数。
环境变量: |
| |
|
是否应该在 worker 线程上执行 DNS 查找。当您可以参阅 HTTP 请求到 OIDC 服务器来记录有关阻止的 Vert.x 事件循环的日志记录警告时,请使用这个选项。
环境变量: | 布尔值 |
|
|
WebClient 使用的连接池的最大大小。
环境变量: | int | |
|
环境变量: | string | |
|
客户端机密值。如果设置了
环境变量: | string | |
|
CredentialsProvider 名称,只有在注册了多个 CredentialsProvider 时才应设置
环境变量: | string | |
|
CredentialsProvider 客户端 secret 密钥
环境变量: | string | |
|
身份验证方法。如果设置了
环境变量: |
工具提示:basic[ | |
|
如果提供,则表示 JWT 使用 secret 密钥进行了签名。
环境变量: | string | |
|
CredentialsProvider 名称,只有在注册了多个 CredentialsProvider 时才应设置
环境变量: | string | |
|
CredentialsProvider 客户端 secret 密钥
环境变量: | string | |
|
如果提供,则表示 JWT 是使用 PEM 或 JWK 格式的私钥签名的。您可以使用
环境变量: | string | |
|
如果提供,则表示 JWT 使用密钥存储中的私钥签名。
环境变量: | string | |
|
指定密钥存储文件的密码的参数。
环境变量: | string | |
|
私钥 ID 或别名。
环境变量: | string | |
|
私钥密码。
环境变量: | string | |
|
JWT 受众(u
环境变量: | string | |
|
添加为 JWT
环境变量: | string | |
|
添加为 JWT 的签名密钥的签发者
环境变量: | string | |
|
添加为 JWT
环境变量: | string | |
|
用于
环境变量: | string | |
|
JWT 生命周期(以秒为单位)。这个值添加到发出 JWT 的时间,以计算过期时间。
环境变量: | int |
|
|
代理的主机名或 IP 地址。
环境变量: | string | |
|
代理的端口号。默认值为
环境变量: | int |
|
|
如果代理需要身份验证,则用户名。
环境变量: | string | |
|
如果代理需要身份验证,则密码。
环境变量: | string | |
|
证书验证和主机名验证,可以是以下
环境变量: | 工具提示:required[Certificates 被验证,并且启用了主机名验证。这是默认的 value.],工具提示:certificate-validation[Certificates 被验证,但主机名验证为 disabled.],提示提示:none[All 证书是可信的,主机名验证被禁用。] | |
|
保存证书信息的可选密钥存储,而不是指定单独的文件。
环境变量: | path | |
|
密钥存储文件的类型。如果未指定,则根据文件名自动检测到类型。
环境变量: | string | |
|
密钥存储文件的提供程序。如果未指定,则根据密钥存储文件类型自动检测到该提供程序。
环境变量: | string | |
|
密钥存储文件的密码。如果未指定,则使用默认值,即
环境变量: | string | |
|
密钥存储中特定密钥的别名。禁用 SNI 时,如果密钥存储包含多个密钥且没有指定别名,则行为未定义。
环境变量: | string | |
|
密钥的密码(如果与
环境变量: | string | |
|
保存要信任的证书信息的信任存储。
环境变量: | path | |
|
truststore 文件的密码。
环境变量: | string | |
|
信任存储证书的别名。
环境变量: | string | |
|
truststore 文件的类型。如果未指定,则根据文件名自动检测到类型。
环境变量: | string | |
|
truststore 文件的供应商。如果没有提供,则会根据信任存储文件类型自动检测到供应商。
环境变量: | string | |
|
唯一的租户标识符。它可以由
环境变量: | string | |
|
如果启用了此租户配置。如果没有配置,但支持租户配置的
环境变量: | 布尔值 |
|
|
应用程序类型,可以是以下
环境变量: |
工具提示:web-app[A |
|
|
OpenID Connect (OIDC)授权端点的相对路径或绝对 URL,用于验证用户。如果 OIDC 发现被禁用,则必须为
环境变量: | string | |
|
OIDC UserInfo 端点的相对路径或绝对路径 URL。如果 OIDC 发现被禁用并且启用了
环境变量: | string | |
|
OIDC RFC7662 内省端点的相对路径或绝对路径 URL,这些端点可以内省不透明和 JSON Web 令牌(JWT)令牌。如果禁用了 OIDC 发现,并且必须验证不透明 bearer 访问令牌,或 2)当缓存的 JWK 验证集没有匹配的 JWK 验证集时,必须设置此属性。如果启用了发现,则忽略此属性。
环境变量: | string | |
|
返回 JSON Web 密钥验证集的 OIDC JSON Web Key Set (JWKS)端点的相对路径或绝对路径。如果禁用了 OIDC 发现且需要本地 JWT 验证,则应设置此属性。如果启用了发现,则忽略此属性。
环境变量: | string | |
|
OIDC end_session_endpoint 的相对路径或绝对路径 URL。如果禁用了 OIDC 发现,并且需要对
环境变量: | string | |
|
本地 JWT 令牌验证的公钥。当设置此属性时,不会创建 OIDC 服务器连接。
环境变量: | string | |
|
Name
环境变量: | string | |
|
Secret
环境变量: | string | |
|
包含使用
环境变量: | 布尔值 |
|
|
包含组数组的声明的路径列表。每个路径从顶级 JWT JSON 对象开始,并可以包含多个片段。每个片段仅代表一个 JSON 对象名称,例如:"realm/groups"。使用带命名空间限定声明名称的双引号。如果令牌没有
环境变量: | 字符串列表 | |
|
包含多个组值的字符串的分隔符。只有在 "role-claim-path" 属性指向值为字符串的一个或多个自定义声明时才使用它。默认情况下会使用单个空格,因为标准
环境变量: | string | |
|
主体角色的源。
环境变量: |
工具提示:idtoken[ID Token - | |
|
预期的签发者
环境变量: | string | |
|
预期
环境变量: | 字符串列表 | |
|
要求令牌包含
环境变量: | 布尔值 |
|
|
预期的令牌类型
环境变量: | string | |
|
生命周期跨宽限期(以秒为单位)。在检查令牌到期时,允许当前的时间超过令牌过期时间(最多配置的秒数)。在检查令牌颁发时,当前时间最多允许于令牌问题时间超过配置的秒数。
环境变量: | int | |
|
令牌期限.它可指定自
环境变量: | ||
|
包含主体名称的声明的名称。默认情况下,会检查
环境变量: | string | |
|
刷新已过期的授权代码流 ID 或访问令牌。如果启用了此属性,如果授权代码 ID 或访问令牌已过期,则会执行刷新令牌请求,如果成功,本地会话会使用新的令牌集合更新。否则,本地会话将无效,用户重定向到 OpenID 提供程序以重新进行身份验证。在这种情况下,如果 OIDC 供应商会话仍然活跃,用户可能无法再次挑战。对于此选项,password
环境变量: | 布尔值 |
|
|
刷新令牌时间偏移(以秒为单位)。如果启用了此属性,在检查授权代码 ID 或访问令牌是否应刷新时,配置的秒数会添加到当前时间。如果总和大于授权代码 ID 或访问令牌的过期时间,则会进行刷新。
环境变量: | ||
|
强制 JWK 设置刷新间隔(以分钟为单位)。
环境变量: |
| |
|
包含 bearer 令牌的自定义 HTTP 标头。只有在应用程序类型为
环境变量: | string | |
|
HTTP 授权标头方案.
环境变量: | string |
|
|
所需的签名算法。OIDC 供应商支持许多签名算法,但如果需要,您可以限制 Quarkus 应用程序来接受仅使用此属性配置的算法签名的令牌。
环境变量: |
| |
|
解密密钥位置.JWT 令牌可由 OpenId Connect 提供程序进行内部签名和加密。但是,并不总是能够远程内省此类令牌,因为提供程序可能无法控制私钥。在这种情况下,将此属性设置为指向包含 PEM 或 JSON Web 密钥(JWK)格式的解密私钥的文件。如果没有设置此属性,并且使用了
环境变量: | string | |
|
当没有匹配的 JWK 密钥时,允许远程内省 JWT 令牌。出于向后兼容性的原因,此属性默认设置为
环境变量: | 布尔值 |
|
|
要求仅远程内省 JWT 令牌。
环境变量: | 布尔值 |
|
|
允许远程内省不透明令牌。如果只有 JWT 令牌,则将此属性设置为
环境变量: | 布尔值 |
|
|
令牌自定义器名称。允许选择特定于租户的令牌自定义器作为命名 Bean。在注册自定义令牌时,首选使用
环境变量: | string | |
|
间接验证不透明(二进制)访问令牌是否有效,方法是请求 UserInfo。如果提供商接受此令牌并返回有效的 UserInfo,则不透明访问令牌被视为有效。只有在必须接受不透明访问令牌但 OpenId Connect 供应商没有令牌内省端点时,才应启用此选项。当必须验证 JWT 令牌时,此属性无效。
环境变量: | 布尔值 |
|
|
应用程序上 logout 端点的相对路径。如果提供,应用程序可以通过此端点启动注销,并符合 OpenID Connect RP-Initiated Logout 规格。
环境变量: | string | |
|
从 OpenID Connect 提供程序注销后,用户应重定向到的应用程序端点的相对路径。此端点 URI 必须在 OpenID Connect Provider 上正确注册,作为有效的重定向 URI。
环境变量: | string | |
|
post logout URI 参数的名称,作为查询参数添加到 logout 重定向 URI。
环境变量: | string |
|
|
应用程序中 Back-Channel Logout 端点的相对路径。
环境变量: | string | |
|
在与会话 Cookie 中存储的 ID 令牌匹配之前可以缓存的最大注销令牌数。
环境变量: | int |
|
|
可以缓存注销令牌的分钟数。
环境变量: |
| |
|
令牌缓存计时器间隔。如果设置了此属性,则计时器会定期检查并删除过时的条目。
环境变量: | ||
|
注销令牌声明,其值用作缓存令牌的密钥。只有
环境变量: | string |
|
|
应用程序中 Front-Channel Logout 端点的相对路径。
环境变量: | string | |
|
leaf 证书的通用名称。如果
环境变量: | string | |
|
truststore 文件,用于保留可信证书的指纹。
环境变量: | path | |
|
如果使用
环境变量: | string | |
|
指定信任存储证书的别名的参数。
环境变量: | string | |
|
指定信任存储文件类型的可选参数。如果未指定,则根据文件名自动检测到类型。
环境变量: | string | |
|
授权代码流响应模式。
环境变量: |
工具提示:query[Authorization 响应参数以添加到 |
|
|
计算
环境变量: | string | |
|
如果此属性设为
环境变量: | 布尔值 |
|
|
在用户通过将用户重定向到同一 URI 后,在重定向 URI 上删除由 OIDC 服务器设置
环境变量: | 布尔值 |
|
|
指向处理 OIDC 授权端点错误响应的公共端点的相对路径。如果用户身份验证失败,OIDC 供应商会返回一个错误和可选的
环境变量: | string | |
|
作为授权代码流的一部分,从 OIDC 供应商获取 ID 和访问令牌。ID 令牌始终在每个用户请求上验证,作为主令牌,用于代表主体并提取角色。默认情况下,不会验证访问令牌,因为它旨在传播到下游服务。如果访问令牌被注入为 JWT 令牌,则应启用访问令牌验证。如果
环境变量: | 布尔值 |
|
|
在 SSL/TLS 终止反向代理后面运行时,强制
环境变量: | 布尔值 |
|
|
范围列表
环境变量: | 字符串列表 | |
|
要求 ID 令牌包含非
环境变量: | 布尔值 |
|
|
将
环境变量: | 布尔值 |
|
|
请求 URL 查询参数(如果存在)添加到身份验证重定向 URI 中。
环境变量: | 字符串列表 | |
|
如果启用了 state、session 和 post logout cookies,则在使用 HTTP 时将其
环境变量: | 布尔值 |
|
|
Cookie 名称后缀。例如,默认 OIDC 租户的会话 Cookie 名称为
环境变量: | string | |
|
Cookie path 参数值(如果设置了)用于为会话设置 path 参数,state 和 post logout cookies。如果设置,则
环境变量: | string |
|
|
Cookie path header 参数值(如果设置)标识传入的 HTTP 标头,其值用于为会话、状态和发布 logout cookie 设置 path 参数。如果缺少标头,则会检查
环境变量: | string | |
|
Cookie 域参数值(如果设置了)用于会话,state 和 post logout cookies。
环境变量: | string | |
|
会话 Cookie 的 SameSite 属性。
环境变量: |
|
|
|
如果存在状态 Cookie,则
环境变量: | 布尔值 |
|
|
如果 state cookie 存在但没有状态查询参数,则失败并显示 HTTP 401 错误。 当禁用多个身份验证或者重定向 URL 与原始请求 URL 匹配时,过时的状态 Cookie 可能会保留在之前失败的浏览器缓存中,并可在当前请求中可见。例如,如果 Single-page 应用(SPA)使用 XHR 处理重定向到不支持其授权端点的 CORS 的提供程序,浏览器会阻止它,并且 Quarkus 创建的状态 Cookie 保留在浏览器缓存中。当检测到旧的状态 cookie 时,quarkus 会报告身份验证失败,但找不到匹配的状态查询参数。
报告 HTTP 401 错误通常是在这种情况下执行的正确操作,它会最小化浏览器重定向循环的风险,但还可以 SPA 或 Quarkus 应用程序管理重定向方式识别问题。例如,可能需要启用
但是,如果上述选项不合适,则将此属性设置为
环境变量: | 布尔值 |
|
|
如果此属性设为
环境变量: | 布尔值 |
|
|
会话期限扩展(以分钟为单位)。默认情况下,用户会话年龄属性被设置为 ID 令牌生命周期的值,用户会被重定向到 OIDC 供应商,以在会话过期后重新验证。如果此属性设置为非零值,则在会话过期前可以刷新过期的 ID 令牌。如果没有启用
环境变量: |
| |
|
如果此属性设为
如果此属性设为
环境变量: | 布尔值 |
|
|
当授权代码流完成后,要求 ID 令牌可用。仅在您需要将授权代码流与 OAuth2 供应商(没有返回 ID 令牌)搭配使用时禁用此属性 - 在这种情况下会生成内部 IdToken。
环境变量: | 布尔值 |
|
|
内部 ID 令牌寿命.只有在 Oauth2 供应商没有返回 IdToken 时,才会检查此属性。
环境变量: |
| |
|
要求使用代码交换证明密钥(PKCE)。
环境变量: | 布尔值 |
|
|
用于为代码交换(PKCE)代码验证器(PKCE)代码验证器和/或非代码流状态加密概念验证的 secret。此 secret 应该至少为 32 个字符。
如果没有设置此 secret,则会检查使用 如果在检查所有这些属性后仍然未初始化,则自动生成该 secret。 如果 secret 长度小于 16 个字符,则报告错误。
环境变量: | string | |
|
默认 TokenStateManager 策略。
环境变量: | 工具提示:keep-all-tokens[Keep ID, access and refresh token.], tooltip:id-token[Keep ID token only], tooltip:id-refresh-tokens[Keep ID and refresh token only] |
|
|
默认 TokenStateManager 会保留在授权代码中返回的所有令牌(ID、访问和刷新)默认授予单个会话 Cookie 的响应。启用此属性最小化会话 Cookie 大小
环境变量: | 布尔值 |
|
|
强制 Default TokenStateManager 加密存储令牌的会话 Cookie。
环境变量: | 布尔值 |
|
|
Default TokenStateManager 用来加密在启用
如果没有设置此 secret,则会检查使用 用于加密令牌的 secret 的长度应至少为 32 个字符。如果 secret 长度小于 16 个字符,则会记录警告信息。
环境变量: | string | |
|
允许缓存令牌内省数据。请注意,启用此属性不启用缓存本身,但仅允许缓存给定租户的令牌内省。如果可以使用默认令牌缓存,请参阅
环境变量: | 布尔值 |
|
|
允许缓存用户信息数据。请注意,启用此属性不启用缓存本身,但只允许缓存给定租户的用户信息数据。如果可以使用默认令牌缓存,请参阅
环境变量: | 布尔值 |
|
|
允许在 IdToken 中简化 UserInfo,而不是将其缓存在令牌缓存中。只有在 Oauth2 供应商没有返回 IdToken 时,才会检查此属性。在生成的 IdToken 中,Inlining UserInfo 允许将其存储在会话 Cookie 中,并避免引入缓存的状态。
环境变量: | 布尔值 |
|
|
如果在连接到 OIDC 供应商时,应该获取 JWK 验证密钥。 禁用此属性会延迟密钥获取,直到必须验证当前令牌的时间。通常,只有在令牌或其他 telated 请求属性提供正确解析密钥所需的额外上下文时,才能需要它。
环境变量: | 布尔值 |
|
|
可以缓存的最大 JWK 密钥数。如果
环境变量: | int |
|
|
可以缓存 JWK 密钥的分钟数。如果
环境变量: |
| |
|
缓存计时器间隔。如果设置了此属性,则计时器会定期检查并删除过时的条目。如果
环境变量: | ||
|
已知的 OpenId Connect 供应商标识符
环境变量: |
| |
|
最大缓存条目数。如果需要启用缓存,则将其设置为正值。
环境变量: | int |
|
|
给定缓存条目有效的最大时间量。
环境变量: |
| |
|
清理计时器间隔。如果设置了此属性,则计时器将定期检查并删除过时的条目。
环境变量: | ||
|
授权选项
环境变量: |
| |
|
其他声明.
环境变量: |
| |
|
所需的声明及其预期值的映射。例如,
环境变量: |
| |
|
添加作为查询参数到 logout 重定向 URI 的额外属性。
环境变量: |
| |
|
添加作为查询参数到身份验证重定向 URI 的额外属性。
环境变量: |
| |
|
除了所需的
环境变量: |
| |
|
必须发送自定义 HTTP 标头来完成授权代码授权请求。
环境变量: |
| |
| 类型 | default | |
|
OpenID Connect (OIDC)服务器的基本 URL,例如
环境变量: | string | |
|
发现 OIDC 端点。如果没有启用,您必须单独配置 OIDC 端点 URL。
环境变量: | 布尔值 |
|
|
签发访问和刷新令牌的 OIDC 令牌端点;指定为相对路径或绝对 URL。如果
环境变量: | string | |
|
OIDC 令牌撤销端点的相对路径或绝对路径 URL。
环境变量: | string | |
|
应用程序的客户端 ID。每个应用都有一个客户端 ID,用于标识应用程序。如果
环境变量: | string | |
|
尝试初始连接到 OIDC 服务器的持续时间。例如,将持续时间设置为
环境变量: | ||
|
如果临时丢失,重试重新建立现有 OIDC 连接的次数。与
环境变量: | int |
|
|
当前 OIDC 连接请求超时的秒数。
环境变量: |
| |
|
是否应该在 worker 线程上执行 DNS 查找。当您可以参阅 HTTP 请求到 OIDC 服务器来记录有关阻止的 Vert.x 事件循环的日志记录警告时,请使用这个选项。
环境变量: | 布尔值 |
|
|
WebClient 使用的连接池的最大大小。
环境变量: | int | |
|
环境变量: | string | |
|
客户端机密值。如果设置了
环境变量: | string | |
|
CredentialsProvider 名称,只有在注册了多个 CredentialsProvider 时才应设置
环境变量: | string | |
|
CredentialsProvider 客户端 secret 密钥
环境变量: | string | |
|
身份验证方法。如果设置了
环境变量: |
工具提示:basic[ | |
|
如果提供,则表示 JWT 使用 secret 密钥进行了签名。
环境变量: | string | |
|
CredentialsProvider 名称,只有在注册了多个 CredentialsProvider 时才应设置
环境变量: | string | |
|
CredentialsProvider 客户端 secret 密钥
环境变量: | string | |
|
如果提供,则表示 JWT 是使用 PEM 或 JWK 格式的私钥签名的。您可以使用
环境变量: | string | |
|
如果提供,则表示 JWT 使用密钥存储中的私钥签名。
环境变量: | string | |
|
指定密钥存储文件的密码的参数。
环境变量: | string | |
|
私钥 ID 或别名。
环境变量: | string | |
|
私钥密码。
环境变量: | string | |
|
JWT 受众(u
环境变量: | string | |
|
添加为 JWT
环境变量: | string | |
|
添加为 JWT 的签名密钥的签发者
环境变量: | string | |
|
添加为 JWT
环境变量: | string | |
|
其他声明.
环境变量: |
| |
|
用于
环境变量: | string | |
|
JWT 生命周期(以秒为单位)。这个值添加到发出 JWT 的时间,以计算过期时间。
环境变量: | int |
|
|
代理的主机名或 IP 地址。
环境变量: | string | |
|
代理的端口号。默认值为
环境变量: | int |
|
|
如果代理需要身份验证,则用户名。
环境变量: | string | |
|
如果代理需要身份验证,则密码。
环境变量: | string | |
|
证书验证和主机名验证,可以是以下
环境变量: | 工具提示:required[Certificates 被验证,并且启用了主机名验证。这是默认的 value.],工具提示:certificate-validation[Certificates 被验证,但主机名验证为 disabled.],提示提示:none[All 证书是可信的,主机名验证被禁用。] | |
|
保存证书信息的可选密钥存储,而不是指定单独的文件。
环境变量: | path | |
|
密钥存储文件的类型。如果未指定,则根据文件名自动检测到类型。
环境变量: | string | |
|
密钥存储文件的提供程序。如果未指定,则根据密钥存储文件类型自动检测到该提供程序。
环境变量: | string | |
|
密钥存储文件的密码。如果未指定,则使用默认值,即
环境变量: | string | |
|
密钥存储中特定密钥的别名。禁用 SNI 时,如果密钥存储包含多个密钥且没有指定别名,则行为未定义。
环境变量: | string | |
|
密钥的密码(如果与
环境变量: | string | |
|
保存要信任的证书信息的信任存储。
环境变量: | path | |
|
truststore 文件的密码。
环境变量: | string | |
|
信任存储证书的别名。
环境变量: | string | |
|
truststore 文件的类型。如果未指定,则根据文件名自动检测到类型。
环境变量: | string | |
|
truststore 文件的供应商。如果没有提供,则会根据信任存储文件类型自动检测到供应商。
环境变量: | string | |
|
唯一的租户标识符。它可以由
环境变量: | string | |
|
如果启用了此租户配置。如果没有配置,但支持租户配置的
环境变量: | 布尔值 |
|
|
应用程序类型,可以是以下
环境变量: |
工具提示:web-app[A |
|
|
OpenID Connect (OIDC)授权端点的相对路径或绝对 URL,用于验证用户。如果 OIDC 发现被禁用,则必须为
环境变量: | string | |
|
OIDC UserInfo 端点的相对路径或绝对路径 URL。如果 OIDC 发现被禁用并且启用了
环境变量: | string | |
|
OIDC RFC7662 内省端点的相对路径或绝对路径 URL,这些端点可以内省不透明和 JSON Web 令牌(JWT)令牌。如果禁用了 OIDC 发现,并且必须验证不透明 bearer 访问令牌,或 2)当缓存的 JWK 验证集没有匹配的 JWK 验证集时,必须设置此属性。如果启用了发现,则忽略此属性。
环境变量: | string | |
|
返回 JSON Web 密钥验证集的 OIDC JSON Web Key Set (JWKS)端点的相对路径或绝对路径。如果禁用了 OIDC 发现且需要本地 JWT 验证,则应设置此属性。如果启用了发现,则忽略此属性。
环境变量: | string | |
|
OIDC end_session_endpoint 的相对路径或绝对路径 URL。如果禁用了 OIDC 发现,并且需要对
环境变量: | string | |
|
本地 JWT 令牌验证的公钥。当设置此属性时,不会创建 OIDC 服务器连接。
环境变量: | string | |
|
Name
环境变量: | string | |
|
Secret
环境变量: | string | |
|
包含使用
环境变量: | 布尔值 |
|
|
包含组数组的声明的路径列表。每个路径从顶级 JWT JSON 对象开始,并可以包含多个片段。每个片段仅代表一个 JSON 对象名称,例如:"realm/groups"。使用带命名空间限定声明名称的双引号。如果令牌没有
环境变量: | 字符串列表 | |
|
包含多个组值的字符串的分隔符。只有在 "role-claim-path" 属性指向值为字符串的一个或多个自定义声明时才使用它。默认情况下会使用单个空格,因为标准
环境变量: | string | |
|
主体角色的源。
环境变量: |
工具提示:idtoken[ID Token - | |
|
预期的签发者
环境变量: | string | |
|
预期
环境变量: | 字符串列表 | |
|
要求令牌包含
环境变量: | 布尔值 |
|
|
所需的声明及其预期值的映射。例如,
环境变量: |
| |
|
预期的令牌类型
环境变量: | string | |
|
生命周期跨宽限期(以秒为单位)。在检查令牌到期时,允许当前的时间超过令牌过期时间(最多配置的秒数)。在检查令牌颁发时,当前时间最多允许于令牌问题时间超过配置的秒数。
环境变量: | int | |
|
令牌期限.它可指定自
环境变量: | ||
|
包含主体名称的声明的名称。默认情况下,会检查
环境变量: | string | |
|
刷新已过期的授权代码流 ID 或访问令牌。如果启用了此属性,如果授权代码 ID 或访问令牌已过期,则会执行刷新令牌请求,如果成功,本地会话会使用新的令牌集合更新。否则,本地会话将无效,用户重定向到 OpenID 提供程序以重新进行身份验证。在这种情况下,如果 OIDC 供应商会话仍然活跃,用户可能无法再次挑战。对于此选项,password
环境变量: | 布尔值 |
|
|
刷新令牌时间偏移(以秒为单位)。如果启用了此属性,在检查授权代码 ID 或访问令牌是否应刷新时,配置的秒数会添加到当前时间。如果总和大于授权代码 ID 或访问令牌的过期时间,则会进行刷新。
环境变量: | ||
|
强制 JWK 设置刷新间隔(以分钟为单位)。
环境变量: |
| |
|
包含 bearer 令牌的自定义 HTTP 标头。只有在应用程序类型为
环境变量: | string | |
|
HTTP 授权标头方案.
环境变量: | string |
|
|
所需的签名算法。OIDC 供应商支持许多签名算法,但如果需要,您可以限制 Quarkus 应用程序来接受仅使用此属性配置的算法签名的令牌。
环境变量: |
| |
|
解密密钥位置.JWT 令牌可由 OpenId Connect 提供程序进行内部签名和加密。但是,并不总是能够远程内省此类令牌,因为提供程序可能无法控制私钥。在这种情况下,将此属性设置为指向包含 PEM 或 JSON Web 密钥(JWK)格式的解密私钥的文件。如果没有设置此属性,并且使用了
环境变量: | string | |
|
当没有匹配的 JWK 密钥时,允许远程内省 JWT 令牌。出于向后兼容性的原因,此属性默认设置为
环境变量: | 布尔值 |
|
|
要求仅远程内省 JWT 令牌。
环境变量: | 布尔值 |
|
|
允许远程内省不透明令牌。如果只有 JWT 令牌,则将此属性设置为
环境变量: | 布尔值 |
|
|
令牌自定义器名称。允许选择特定于租户的令牌自定义器作为命名 Bean。在注册自定义令牌时,首选使用
环境变量: | string | |
|
间接验证不透明(二进制)访问令牌是否有效,方法是请求 UserInfo。如果提供商接受此令牌并返回有效的 UserInfo,则不透明访问令牌被视为有效。只有在必须接受不透明访问令牌但 OpenId Connect 供应商没有令牌内省端点时,才应启用此选项。当必须验证 JWT 令牌时,此属性无效。
环境变量: | 布尔值 |
|
|
应用程序上 logout 端点的相对路径。如果提供,应用程序可以通过此端点启动注销,并符合 OpenID Connect RP-Initiated Logout 规格。
环境变量: | string | |
|
从 OpenID Connect 提供程序注销后,用户应重定向到的应用程序端点的相对路径。此端点 URI 必须在 OpenID Connect Provider 上正确注册,作为有效的重定向 URI。
环境变量: | string | |
|
post logout URI 参数的名称,作为查询参数添加到 logout 重定向 URI。
环境变量: | string |
|
|
添加作为查询参数到 logout 重定向 URI 的额外属性。
环境变量: |
| |
|
应用程序中 Back-Channel Logout 端点的相对路径。
环境变量: | string | |
|
在与会话 Cookie 中存储的 ID 令牌匹配之前可以缓存的最大注销令牌数。
环境变量: | int |
|
|
可以缓存注销令牌的分钟数。
环境变量: |
| |
|
令牌缓存计时器间隔。如果设置了此属性,则计时器会定期检查并删除过时的条目。
环境变量: | ||
|
注销令牌声明,其值用作缓存令牌的密钥。只有
环境变量: | string |
|
|
应用程序中 Front-Channel Logout 端点的相对路径。
环境变量: | string | |
|
leaf 证书的通用名称。如果
环境变量: | string | |
|
truststore 文件,用于保留可信证书的指纹。
环境变量: | path | |
|
如果使用
环境变量: | string | |
|
指定信任存储证书的别名的参数。
环境变量: | string | |
|
指定信任存储文件类型的可选参数。如果未指定,则根据文件名自动检测到类型。
环境变量: | string | |
|
授权代码流响应模式。
环境变量: |
工具提示:query[Authorization 响应参数以添加到 |
|
|
计算
环境变量: | string | |
|
如果此属性设为
环境变量: | 布尔值 |
|
|
在用户通过将用户重定向到同一 URI 后,在重定向 URI 上删除由 OIDC 服务器设置
环境变量: | 布尔值 |
|
|
指向处理 OIDC 授权端点错误响应的公共端点的相对路径。如果用户身份验证失败,OIDC 供应商会返回一个错误和可选的
环境变量: | string | |
|
作为授权代码流的一部分,从 OIDC 供应商获取 ID 和访问令牌。ID 令牌始终在每个用户请求上验证,作为主令牌,用于代表主体并提取角色。默认情况下,不会验证访问令牌,因为它旨在传播到下游服务。如果访问令牌被注入为 JWT 令牌,则应启用访问令牌验证。如果
环境变量: | 布尔值 |
|
|
在 SSL/TLS 终止反向代理后面运行时,强制
环境变量: | 布尔值 |
|
|
范围列表
环境变量: | 字符串列表 | |
|
要求 ID 令牌包含非
环境变量: | 布尔值 |
|
|
将
环境变量: | 布尔值 |
|
|
添加作为查询参数到身份验证重定向 URI 的额外属性。
环境变量: |
| |
|
请求 URL 查询参数(如果存在)添加到身份验证重定向 URI 中。
环境变量: | 字符串列表 | |
|
如果启用了 state、session 和 post logout cookies,则在使用 HTTP 时将其
环境变量: | 布尔值 |
|
|
Cookie 名称后缀。例如,默认 OIDC 租户的会话 Cookie 名称为
环境变量: | string | |
|
Cookie path 参数值(如果设置了)用于为会话设置 path 参数,state 和 post logout cookies。如果设置,则
环境变量: | string |
|
|
Cookie path header 参数值(如果设置)标识传入的 HTTP 标头,其值用于为会话、状态和发布 logout cookie 设置 path 参数。如果缺少标头,则会检查
环境变量: | string | |
|
Cookie 域参数值(如果设置了)用于会话,state 和 post logout cookies。
环境变量: | string | |
|
会话 Cookie 的 SameSite 属性。
环境变量: |
|
|
|
如果存在状态 Cookie,则
环境变量: | 布尔值 |
|
|
如果 state cookie 存在但没有状态查询参数,则失败并显示 HTTP 401 错误。 当禁用多个身份验证或者重定向 URL 与原始请求 URL 匹配时,过时的状态 Cookie 可能会保留在之前失败的浏览器缓存中,并可在当前请求中可见。例如,如果 Single-page 应用(SPA)使用 XHR 处理重定向到不支持其授权端点的 CORS 的提供程序,浏览器会阻止它,并且 Quarkus 创建的状态 Cookie 保留在浏览器缓存中。当检测到旧的状态 cookie 时,quarkus 会报告身份验证失败,但找不到匹配的状态查询参数。
报告 HTTP 401 错误通常是在这种情况下执行的正确操作,它会最小化浏览器重定向循环的风险,但还可以 SPA 或 Quarkus 应用程序管理重定向方式识别问题。例如,可能需要启用
但是,如果上述选项不合适,则将此属性设置为
环境变量: | 布尔值 |
|
|
如果此属性设为
环境变量: | 布尔值 |
|
|
会话期限扩展(以分钟为单位)。默认情况下,用户会话年龄属性被设置为 ID 令牌生命周期的值,用户会被重定向到 OIDC 供应商,以在会话过期后重新验证。如果此属性设置为非零值,则在会话过期前可以刷新过期的 ID 令牌。如果没有启用
环境变量: |
| |
|
如果此属性设为
如果此属性设为
环境变量: | 布尔值 |
|
|
当授权代码流完成后,要求 ID 令牌可用。仅在您需要将授权代码流与 OAuth2 供应商(没有返回 ID 令牌)搭配使用时禁用此属性 - 在这种情况下会生成内部 IdToken。
环境变量: | 布尔值 |
|
|
内部 ID 令牌寿命.只有在 Oauth2 供应商没有返回 IdToken 时,才会检查此属性。
环境变量: |
| |
|
要求使用代码交换证明密钥(PKCE)。
环境变量: | 布尔值 |
|
|
用于为代码交换(PKCE)代码验证器(PKCE)代码验证器和/或非代码流状态加密概念验证的 secret。此 secret 应该至少为 32 个字符。
如果没有设置此 secret,则会检查使用 如果在检查所有这些属性后仍然未初始化,则自动生成该 secret。 如果 secret 长度小于 16 个字符,则报告错误。
环境变量: | string | |
|
除了所需的
环境变量: |
| |
|
必须发送自定义 HTTP 标头来完成授权代码授权请求。
环境变量: |
| |
|
默认 TokenStateManager 策略。
环境变量: | 工具提示:keep-all-tokens[Keep ID, access and refresh token.], tooltip:id-token[Keep ID token only], tooltip:id-refresh-tokens[Keep ID and refresh token only] |
|
|
默认 TokenStateManager 会保留在授权代码中返回的所有令牌(ID、访问和刷新)默认授予单个会话 Cookie 的响应。启用此属性最小化会话 Cookie 大小
环境变量: | 布尔值 |
|
|
强制 Default TokenStateManager 加密存储令牌的会话 Cookie。
环境变量: | 布尔值 |
|
|
Default TokenStateManager 用来加密在启用
如果没有设置此 secret,则会检查使用 用于加密令牌的 secret 的长度应至少为 32 个字符。如果 secret 长度小于 16 个字符,则会记录警告信息。
环境变量: | string | |
|
允许缓存令牌内省数据。请注意,启用此属性不启用缓存本身,但仅允许缓存给定租户的令牌内省。如果可以使用默认令牌缓存,请参阅
环境变量: | 布尔值 |
|
|
允许缓存用户信息数据。请注意,启用此属性不启用缓存本身,但只允许缓存给定租户的用户信息数据。如果可以使用默认令牌缓存,请参阅
环境变量: | 布尔值 |
|
|
允许在 IdToken 中简化 UserInfo,而不是将其缓存在令牌缓存中。只有在 Oauth2 供应商没有返回 IdToken 时,才会检查此属性。在生成的 IdToken 中,Inlining UserInfo 允许将其存储在会话 Cookie 中,并避免引入缓存的状态。
环境变量: | 布尔值 |
|
|
如果在连接到 OIDC 供应商时,应该获取 JWK 验证密钥。 禁用此属性会延迟密钥获取,直到必须验证当前令牌的时间。通常,只有在令牌或其他 telated 请求属性提供正确解析密钥所需的额外上下文时,才能需要它。
环境变量: | 布尔值 |
|
|
可以缓存的最大 JWK 密钥数。如果
环境变量: | int |
|
|
可以缓存 JWK 密钥的分钟数。如果
环境变量: |
| |
|
缓存计时器间隔。如果设置了此属性,则计时器会定期检查并删除过时的条目。如果
环境变量: | ||
|
已知的 OpenId Connect 供应商标识符
环境变量: |
|
要写入持续时间值,请使用标准 java.time.Duration 格式。如需更多信息,请参阅 Duration#parse ()Java API 文档。
您还可以使用简化的格式,从数字开始:
- 如果值只是一个数字,它代表时间(以秒为单位)。
-
如果值为数字,后跟
ms,代表时间(毫秒)。
在其他情况下,简化的格式被转换为 java.time.Duration 格式以进行解析:
-
如果该值是一个数字,后跟
h、m或s,则前缀为PT。 -
如果值为数字,后跟
d,则会以P为前缀。
