Quarkus OIDC多租户:如何从gRPC调用元数据提取TenantId?
从gRPC元数据提取tenantId实现多租户OIDC配置
要在gRPC服务调用场景下复用相同的多租户策略,核心是从gRPC请求上下文中提取元数据,而非HTTP请求头。Quarkus的OIDC扩展在处理gRPC请求时,OidcRequestContext会实际是GrpcRequestContext类型,可通过它获取gRPC元数据。
修改后的实现代码
@ApplicationScoped public class PartitionTenantResolver implements TenantConfigResolver { // 定义gRPC元数据键,gRPC默认会将键转为小写,建议统一用小写格式 private static final Metadata.Key<String> DATA_PARTITION_ID_KEY = Metadata.Key.of("data-partition-id", Metadata.ASCII_STRING_MARSHALLER); @Override public Uni<OidcTenantConfig> resolve(RoutingContext routingContext, OidcRequestContext<OidcTenantConfig> requestContext) { String dataPartitionId = null; // 处理gRPC请求场景 if (requestContext instanceof GrpcRequestContext grpcContext) { Metadata metadata = grpcContext.getMetadata(); dataPartitionId = metadata.get(DATA_PARTITION_ID_KEY); } // 保留原有HTTP请求场景的处理逻辑,兼容两种请求类型 else if (routingContext != null) { dataPartitionId = routingContext.request().getHeader("DATA_PARTITION_ID"); } String keycloakUrl = ConfigProvider.getConfig().getValue("openid.provider.base-url", String.class); String clientId = ConfigProvider.getConfig().getValue("openid.provider.client-id", String.class); String secret = ConfigProvider.getConfig().getValue("openid.provider.secret", String.class); if (StringUtils.isNotEmpty(dataPartitionId)) { OidcTenantConfig config = new OidcTenantConfig(); config.setAuthServerUrl(keycloakUrl + "/realms/" + dataPartitionId); config.setTenantId(dataPartitionId); config.setClientId(clientId); config.getCredentials().setSecret(secret); config.setApplicationType(OidcTenantConfig.ApplicationType.SERVICE); return Uni.createFrom().item(config); } return Uni.createFrom().nullItem(); } }
关键说明
- 上下文类型判断:通过
instanceof检查requestContext是否为GrpcRequestContext,以此区分gRPC和HTTP请求场景 - gRPC元数据提取:使用
Metadata.Key定义元数据键,遵循gRPC协议要求(键默认转为小写),避免大小写不匹配问题 - 多场景兼容:保留原有HTTP请求头的处理逻辑,让同一个Resolver同时支持HTTP和gRPC两种请求类型
内容的提问来源于stack exchange,提问作者Bd Ghn
相关产品推荐
相关产品推荐

