You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置特定端点时Google Pub/Sub API遇OAuth2认证失败求助

问题原因

当你指定区域Pub/Sub端点(如us-east1-pubsub.googleapis.com:443)时,默认生成的OAuth 2令牌的**受众(Audience)**是全局端点pubsub.googleapis.com,与区域端点不匹配,导致认证被拒绝。而连接全局端点时,令牌受众正好匹配,所以认证正常。

解决方案

你需要在创建GoogleCredentials时,手动指定令牌的受众为区域端点的主机名(不带端口),确保认证令牌与目标端点匹配。

代码修改示例

调整Credentials的创建逻辑,添加受众设置:

final String PROJECT_ID = "...";
final String TOPIC_NAME = "test-20221025-153636-7318";
final String ENDPOINT = "us-east1-pubsub.googleapis.com:443";
// 提取端点主机名用于设置受众
final String AUDIENCE = "https://" + ENDPOINT.split(":")[0];
final String CREDENTIALS = "{\n" //
        + "  \"type\": \"service_account\",\n" //
        + "  \"project_id\": \"" + PROJECT_ID + "\",\n" //
        + "  \"private_key_id\": \"...\",\n" //
        + "  \"private_key\": ...\"" //
        + "  \"client_email\": \"...\",\n" //
        + "  \"client_id\": \"...\",\n" //
        + ...
        + "}\n";

TopicName googleTopicName = ProjectTopicName.of(PROJECT_ID, TOPIC_NAME);

// 修改Credentials创建逻辑,添加受众和权限范围
GoogleCredentials rawCredentials = GoogleCredentials.fromStream(new ByteArrayInputStream(CREDENTIALS.getBytes()));
// 添加Pub/Sub所需的权限范围
GoogleCredentials scopedCredentials = rawCredentials.createScoped(List.of("https://www.googleapis.com/auth/pubsub"));
// 设置令牌受众为区域端点
GoogleCredentials credentialsWithAudience = scopedCredentials.withAudience(AUDIENCE);

CredentialsProvider credentialsProvider = FixedCredentialsProvider.create(credentialsWithAudience);

// 创建publisher的逻辑不变
Publisher.Builder publisherBuilder = Publisher.newBuilder(googleTopicName);
publisherBuilder.setCredentialsProvider(credentialsProvider);
publisherBuilder.setEndpoint(ENDPOINT);
publisherBuilder.setEnableMessageOrdering(true);
Publisher publisher = publisherBuilder.build();

// 发布消息逻辑不变
PubsubMessage message = PubsubMessage.newBuilder().setMessageId("id")
        .setData(ByteString.copyFrom("data", Charset.defaultCharset()))
        .setOrderingKey("foo").build();
ApiFuture<String> future = publisher.publish(message);
System.out.println("Publishing message returned: " + future.get());

额外检查点

  • 确认你的服务账号已被授予roles/pubsub.publisher角色(全局端点正常的话此条件大概率满足)。
  • 如果使用的是较旧版本的Google Cloud Pub/Sub库,withAudience方法可能不可用,此时可以强制转换为ServiceAccountCredentials并通过Builder设置:
ServiceAccountCredentials serviceAccountCreds = (ServiceAccountCredentials) rawCredentials;
ServiceAccountCredentials updatedCreds = serviceAccountCreds.toBuilder()
        .setAudience(AUDIENCE)
        .build()
        .createScoped(List.of("https://www.googleapis.com/auth/pubsub"));
CredentialsProvider credentialsProvider = FixedCredentialsProvider.create(updatedCreds);

内容的提问来源于stack exchange,提问作者Gray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:35:25