【问题标题】:Bigquery insert job with default service account使用默认服务帐户的 Bigquery 插入作业
【发布时间】:2020-02-04 23:09:18
【问题描述】:

我有一些工作代码可以使用其余 api 将文件加载到 bigquery 中,如所述 https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/insert 在此过程中,我使用 ServiceAccountCredentials 读取私钥并生成 JWT 令牌,然后最终获取插入作业的 OAuth 令牌。 现在,我需要在 gcp 内的 docker 容器中运行相同的进程。我没有找到客户这样做。这就是我一开始就选择 Rest API 的原因。有没有办法可以使用默认服务帐户的凭据生成令牌?如何在 java 代码中访问默认服务帐户?

【问题讨论】:

    标签: java google-cloud-platform google-bigquery google-oauth service-accounts


    【解决方案1】:

    您的问题没有说明容器在哪个服务中运行。某些服务通过元数据服务器或机密使容器可以使用应用程序默认凭据 (ADC),而其他服务则没有。对于不提供 ADC 的服务,您需要指定服务帐号密钥文件。

    对于这个答案,我将向您展示获取 Google OAuth 访问令牌的正确方法。除非您有特定的技术原因,否则不要从 JWT 创建令牌。

    从服务帐号 JSON 密钥文件中获取访问令牌:

    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.auth.oauth2.AccessToken;
    import  com.google.common.collect.Lists;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    
    class Main
    {
        public static void main(String args[])
        {
        String  sa_file = "/fullpath/serviceaccount.json";
        String  scopes = "https://www.googleapis.com/auth/cloud-platform";
    
            GoogleCredentials credentials;
    
            try {
                credentials = GoogleCredentials.fromStream(new FileInputStream(sa_file))
                    .createScoped(Lists.newArrayList(scopes));
            }
            catch (java.io.FileNotFoundException e) {
                System.out.println("FileNotFoundException");
                return;
            }
            catch (IOException e) {
                System.out.println("IOException");
                return;
            }
    
            try {
                AccessToken accessToken;
    
                accessToken = credentials.getAccessToken();
    
                if (accessToken == null) {
                    accessToken = credentials.refreshAccessToken();
                }
    
                if (accessToken != null) {
                    System.out.println("Access Token: " + accessToken.getTokenValue());
                }
            }
            catch (IOException e) {
                System.out.println("IOException");
                return;
            }
        }
    }
    

    如果您的容器中有应用程序默认凭据,您可以通过这种方式获取凭据并使用上述方法提取访问令牌。

    var credential = GoogleCredential.GetApplicationDefault();
    

    如果您在支持元数据服务器(Compute Engine 等)的 Google 服务上运行,您可以通过对这个端点的 HTTP GET 请求获取访问令牌:

    http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
    

    您需要在 GET 请求中包含此 HTTP 标头:

    Metadata-Flavor: Google
    

    【讨论】:

    • 谢谢约翰。这很有帮助
    • 一个问题,从具有 ADC 的容器运行访问令牌或在本地运行代码是否重要。你展示的方式要容易得多。我曾经向googleapis.com/oauth2/v4/token 发送请求以获取访问令牌。那更复杂。那只是因为我当时才发现这种方式。如果没有限制从容器运行此代码,设置了 ADC 或像我的本地机器这样的地方,这将大大简化流程。
    • 您的本地系统将无法访问元数据服务器。如果您在本地系统上设置应用程序默认凭据,则可以在本地访问 ADC。我写了一篇关于 ADC 的文章:jhanley.com/google-cloud-application-default-credentials 另请阅读这篇文章:jhanley.com/… 如果您浏览我的网站,您会发现很多文章可以帮助您了解 Google Cloud。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 2021-08-31
    • 2022-01-17
    • 2018-08-08
    • 2021-12-17
    • 2017-03-15
    相关资源
    最近更新 更多