本文介绍如何在 Quarkus 框架中集成 OIDC 认证和 Hibernate ORM,实现多租户数据源配置和身份认证功能。
参考资料:Quarkus 官方文档
Quarkus 简介
Quarkus 是专为 OpenJDK HotSpot 和 GraalVM 量身定制的 Kubernetes 原生 Java 技术栈,采用最佳 Java 库和标准精心打造。它具有以下特点:
- 快速启动:采用编译时启动技术,实现惊人的快速启动时间
- 低内存占用:极低的 RSS 内存占用(不仅是堆大小)
- 云原生优化:在 Kubernetes 等容器编排平台中提供近乎即时的向上扩展和高密度内存利用率
- 响应式编程:支持 JDK 9+ 的 Publisher/Flow 响应式编程模型
- 开源协议:所有依赖项都基于 Apache Software License 2.0
官方提供了多个性能对比示例:https://quarkus.io/vision/continuum
环境准备
基础要求
- JDK:9 或以上版本
- Maven:3.6.2 或以上版本
- IDE:IntelliJ IDEA(推荐)
IDE 插件安装
在 IDEA 中安装 Quarkus 相关插件:
- 打开 IDEA 的插件市场
- 搜索并安装
Quarkus Tools 和 Quarkus Integration - 重启 IDE 使插件生效
安装完插件后,创建 Quarkus 项目与 Spring Boot 类似。如果创建失败,可以访问 https://code.quarkus.io/ 手动创建项目(类似 Spring Initializr)。

更多使用指南可参考:https://quarkus.io/guides/
OIDC 认证集成
添加依赖
在 pom.xml 中添加 OIDC 扩展:
1 2 3 4
| <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency>
|
自定义认证信息增强器
创建 RolesAugmentor 类,用于在认证过程中增强用户角色和权限信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| import io.quarkus.security.identity.AuthenticationRequestContext; import io.quarkus.security.identity.SecurityIdentity; import io.quarkus.security.identity.SecurityIdentityAugmentor; import io.quarkus.security.runtime.QuarkusSecurityIdentity; import io.smallrye.mutiny.Uni; import lombok.extern.slf4j.Slf4j; import org.eclipse.microprofile.jwt.JsonWebToken;
import javax.enterprise.context.ApplicationScoped; import java.util.*; import java.util.function.Supplier;
@Slf4j @ApplicationScoped public class RolesAugmentor implements SecurityIdentityAugmentor, Supplier<SecurityIdentity> {
SecurityIdentity identity;
@Override public int priority() { return 0; }
@Override public Uni<SecurityIdentity> augment(SecurityIdentity securityIdentity, AuthenticationRequestContext authenticationRequestContext) { this.identity = securityIdentity; return authenticationRequestContext.runBlocking(this::get); }
@Override public SecurityIdentity get() { if (!identity.isAnonymous()) { Set<String> roles = identity.getRoles(); Set<String> permissions = new HashSet<>();
Map<String, Object> clientInfo = ((JsonWebToken) identity.getPrincipal()) .getClaim("client-id");
return QuarkusSecurityIdentity.builder() .setPrincipal(identity.getPrincipal()) .addAttributes(clientInfo == null ? Collections.emptyMap() : clientInfo) .addCredentials(identity.getCredentials()) .addRoles(permissions) .build(); }
return identity; } }
|
实现多租户解析器
创建 CustomTenantResolver 类,根据请求路径动态解析租户信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import io.quarkus.oidc.TenantResolver; import io.vertx.ext.web.RoutingContext;
import javax.enterprise.context.ApplicationScoped;
@ApplicationScoped public class CustomTenantResolver implements TenantResolver {
@Override public String resolve(RoutingContext context) { String path = context.request().path(); String[] parts = path.split("/");
if (parts.length == 0) { return "default"; }
return parts[1]; } }
|
Hibernate ORM 集成
添加依赖
在 pom.xml 中添加 Hibernate ORM 和数据库驱动依赖:
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-orm</artifactId> </dependency>
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-jdbc-postgresql</artifactId> </dependency>
|
实现数据源租户解析器
创建 Hibernate 的租户解析器,实现多数据源切换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import io.quarkus.hibernate.orm.runtime.tenant.TenantResolver; import io.vertx.ext.web.RoutingContext; import org.eclipse.microprofile.config.inject.ConfigProperty;
import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject;
@ApplicationScoped public class CustomTenantResolver implements TenantResolver {
@Inject RoutingContext context;
@ConfigProperty(name = "quarkus.hibernate-orm.datasource") public String defaultTenant;
@Override public String getDefaultTenantId() { return defaultTenant; }
@Override public String resolveTenantId() { String path = context.request().path(); String[] parts = path.split("/"); if (parts.length == 0) { return getDefaultTenantId(); } return parts[1]; } }
|
多数据源配置
Quarkus 支持多数据源配置,但需要注意:编译后的文件不支持二次修改(因为字节码增强)。
详细配置参考:Quarkus Datasource 文档
配置示例
在 application.properties 或 application.yml 中配置多数据源和 OIDC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| quarkus.datasource.db-kind=postgresql quarkus.datasource.username=username quarkus.datasource.password=password quarkus.datasource.jdbc.url=jdbc:postgresql://192.168.56.110:5432/default
quarkus.hibernate-orm.multitenant=DATABASE quarkus.hibernate-orm.dialect=org.hibernate.dialect.PostgreSQL10Dialect quarkus.hibernate-orm.datasource=default quarkus.hibernate-orm.database.generation=none quarkus.hibernate-orm.packages=org.xiaowu
quarkus.oidc.auth-server-url=http://192.168.56.110:8080/auth/realms/default quarkus.oidc.client-id=service quarkus.oidc.credentials.secret=secret
quarkus.datasource.default.db-kind=${quarkus.datasource.db-kind} quarkus.datasource.default.username=${quarkus.datasource.username} quarkus.datasource.default.password=${quarkus.datasource.password} quarkus.datasource.default.jdbc.url=${quarkus.datasource.jdbc.url} quarkus.oidc."default".auth-server-url=${quarkus.oidc.auth-server-url} quarkus.oidc."default".client-id=${quarkus.oidc.client-id} quarkus.oidc."default".credentials.secret=${quarkus.oidc.credentials.secret}
quarkus.datasource.A.db-kind=postgresql quarkus.datasource.A.username=username quarkus.datasource.A.password=password quarkus.datasource.A.jdbc.url=jdbc:postgresql://192.168.56.110:5432/A quarkus.oidc.A.auth-server-url=http://192.168.56.110:8080/auth/realms/A quarkus.oidc.A.client-id=backend-service quarkus.oidc.A.credentials.secret=secret
|
使用建议
- 租户隔离策略:根据业务需求选择数据库级别(DATABASE)或模式级别(SCHEMA)的多租户隔离
- 性能优化:合理配置连接池大小和超时时间
- 安全性:生产环境务必使用环境变量或密钥管理服务存储敏感信息
- 监控告警:集成 Quarkus 的健康检查和指标监控
总结
通过集成 OIDC 和 Hibernate,Quarkus 可以轻松实现:
- 基于标准的身份认证和授权
- 灵活的多租户数据源管理
- 高性能的云原生应用部署
结合 Quarkus 的快速启动和低内存占用特性,非常适合构建现代化的微服务应用。