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

GCP资源访问:ADC每日重认证问题及程序化认证方案咨询

解决ADC每日手动重认证的程序化方案

问题根源

gcloud auth application-default login生成的是用户凭据,这类凭据有短期有效期(通常24小时),且依赖交互式登录,完全不适合生产环境。你遇到的invalid_rapt错误正是因为凭据过期,需要重新完成交互式验证。

生产环境程序化认证方案

生产环境下,应使用服务账号凭据替代用户凭据,以下是两种程序化实现方式:

1. Java SDK 程序化认证

直接在代码中加载服务账号密钥文件,或利用GCP托管环境内置的ADC机制(推荐用于GCE/GKE/Cloud Functions等场景):

方式一:加载本地服务账号密钥文件

import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.io.FileInputStream;
import java.io.IOException;

public class AuthExample {
    public static void main(String[] args) throws IOException {
        // 替换为你的服务账号密钥文件路径
        GoogleCredentials credentials = GoogleCredentials.fromStream(
            new FileInputStream("/path/to/service-account-key.json")
        );
        Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
        // 后续使用storage对象访问GCP资源
    }
}

方式二:依赖环境内置ADC(托管环境首选)

如果应用部署在GCP托管服务(如GKE、Cloud Run),无需手动加载密钥,ADC会自动获取服务账号凭据:

import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class AuthExample {
    public static void main(String[] args) {
        Storage storage = StorageOptions.getDefaultInstance().getService();
        // 直接使用服务访问GCP资源
    }
}

2. REST API 程序化认证

通过服务账号生成短期访问令牌,用于调用GCP REST API:

步骤1:准备服务账号信息

从GCP控制台下载服务账号的JSON密钥文件,提取其中的client_email和private_key字段。

步骤2:生成JWT并请求访问令牌

使用JWT库签名生成断言,再向OAuth2端点请求令牌:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Date;

public class RestAuthExample {
    private static final String TOKEN_URL = "https://oauth2.googleapis.com/token";
    private static final String SCOPE = "https://www.googleapis.com/auth/cloud-platform";

    public static void main(String[] args) throws Exception {
        // 替换为服务账号的client_email和private_key
        String clientEmail = "your-service-account@project-id.iam.gserviceaccount.com";
        String privateKeyPem = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----";

        // 解析私钥
        String privateKeyStr = privateKeyPem.replaceAll("-----BEGIN PRIVATE KEY-----", "")
                                            .replaceAll("-----END PRIVATE KEY-----", "")
                                            .replaceAll("\\s", "");
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKeyBytes);
        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(spec);

        // 生成JWT断言
        long now = System.currentTimeMillis();
        String jwt = Jwts.builder()
                .setIssuer(clientEmail)
                .setAudience(TOKEN_URL)
                .setIssuedAt(new Date(now))
                .setExpiration(new Date(now + 3600 * 1000)) // 有效期1小时
                .setClaim("scope", SCOPE)
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();

        // 请求访问令牌
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType,
                "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + jwt);
        Request request = new Request.Builder()
                .url(TOKEN_URL)
                .post(body)
                .build();

        try (Response response = client.newCall(request).execute()) {
            String responseBody = response.body().string();
            // 解析responseBody获取access_token,后续调用REST API时放在Authorization头中
            System.out.println("Access Token Response: " + responseBody);
        }
    }
}

关键注意事项

  • 服务账号密钥文件需妥善保管,避免泄露,生产环境建议使用GCP密钥管理服务存储密钥。
  • 托管环境优先使用内置ADC,无需手动管理密钥,安全性更高。
  • 禁止在生产环境使用用户凭据(gcloud auth application-default login生成的凭据),这类凭据仅适用于本地开发调试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:12:51