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

启动应用无需ServiceAccount Credentials JSON,如何向Google Pub/Sub发消息?

解决方案:无需本地credentials.json的GCP Pub/Sub认证方式

方案1:从AWS Parameter Store加载凭证字符串构建GoogleCredentials

既然你已经能从AWS Parameter Store获取凭证字符串,直接通过代码自定义GoogleCredentials Bean即可替代配置文件的路径依赖,彻底摆脱本地JSON文件:

  • 先删除application.yaml里的spring.cloud.gcp.credentials.location配置
  • 编写配置类,拉取凭证字符串并解析为GCP认证凭证:
import com.google.auth.oauth2.GoogleCredentials;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.services.ssm.SsmClient;
import software.amazon.awssdk.services.ssm.model.GetParameterRequest;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;

@Configuration
public class GcpPubSubConfig {

    @Bean
    public GoogleCredentials googleCredentials() {
        // 从AWS Parameter Store拉取加密后的凭证JSON
        SsmClient ssmClient = SsmClient.create();
        GetParameterRequest request = GetParameterRequest.builder()
                .name("/your/param/path/gcp-service-account-json")
                .withDecryption(true)
                .build();
        String credentialJson = ssmClient.getParameter(request).parameter().value();

        // 将字符串转为流,构建GCP认证凭证
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(credentialJson.getBytes(StandardCharsets.UTF_8))) {
            return GoogleCredentials.fromStream(inputStream)
                    .createScoped("https://www.googleapis.com/auth/pubsub");
        } catch (Exception e) {
            throw new RuntimeException("Failed to load GCP credentials from AWS Parameter Store", e);
        }
    }
}

Spring Cloud GCP会自动识别并使用这个自定义的GoogleCredentials Bean,无需依赖本地文件。

方案2:ECS任务环境变量传递加密凭证

把GCP服务账号JSON加密后存入AWS Secrets Manager,再通过ECS任务定义的环境变量注入,代码读取环境变量构建凭证:

  • 在ECS任务定义中添加加密的环境变量GCP_SERVICE_ACCOUNT_JSON,值从Secrets Manager拉取
  • 编写配置类读取环境变量:
import com.google.auth.oauth2.GoogleCredentials;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;

@Configuration
public class GcpPubSubConfig {

    @Bean
    public GoogleCredentials googleCredentials() {
        String credentialJson = System.getenv("GCP_SERVICE_ACCOUNT_JSON");
        if (credentialJson == null || credentialJson.isEmpty()) {
            throw new RuntimeException("GCP_SERVICE_ACCOUNT_JSON environment variable not set");
        }
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(credentialJson.getBytes(StandardCharsets.UTF_8))) {
            return GoogleCredentials.fromStream(inputStream)
                    .createScoped("https://www.googleapis.com/auth/pubsub");
        } catch (Exception e) {
            throw new RuntimeException("Failed to load GCP credentials from environment variable", e);
        }
    }
}

方案3:GCP Workload Identity Federation(无密钥跨云认证,推荐)

通过GCP与AWS的身份联合,让ECS任务用自身的IAM角色直接向GCP认证,完全不需要存储GCP服务账号密钥:

  1. 在GCP创建Workload Identity Pool,添加AWS作为身份提供者,配置对应AWS账号ID和区域
  2. 创建身份映射规则,将ECS任务使用的AWS IAM角色关联到GCP的Pub/Sub Editor角色
  3. 代码中通过AWS任务角色凭证交换GCP临时凭证:
import com.google.auth.oauth2.AwsCredentials;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.WorkloadIdentityPoolCredentials;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;

@Configuration
public class GcpPubSubConfig {

    @Bean
    public GoogleCredentials googleCredentials() {
        // 获取ECS任务的AWS本地凭证
        software.amazon.awssdk.auth.credentials.AwsCredentials awsSdkCreds = DefaultCredentialsProvider.create().resolveCredentials();
        AwsCredentials awsCreds = AwsCredentials.newBuilder()
                .setAccessKeyId(awsSdkCreds.accessKeyId())
                .setSecretAccessKey(awsSdkCreds.secretAccessKey())
                .setSessionToken(awsSdkCreds.sessionToken())
                .build();

        // 构建Workload Identity Pool凭证
        return WorkloadIdentityPoolCredentials.newBuilder()
                .setWorkloadIdentityPoolId("projects/[你的GCP项目ID]/locations/global/workloadIdentityPools/[池ID]")
                .setProviderId("aws/[身份提供者ID]")
                .setAwsCredentials(awsCreds)
                .setServiceAccountEmail("[关联的GCP服务账号邮箱]")
                .build();
    }
}

这种方式安全性最高,无需管理任何静态密钥,适合长期生产环境使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 23:30:23