【问题标题】:Your application has authenticated using end user credentials from the Google Cloud SDK which are not supported by the translate.googleapis.com您的应用程序已使用来自 translate.googleapis.com 的 Google Cloud SDK 的最终用户凭据进行身份验证
【发布时间】:2019-06-30 08:12:21
【问题描述】:

看完类似的问题,如:

i am using gcp service account but when calling dialogue flow api its giving error :

Why is Google Cloud API trying to connect as an end-user?

并应用建议的解决方案我仍然收到错误:

    Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "usageLimits",
    "message" : "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the translate.googleapis.com. We recommend that most server applications use service accounts instead. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.",
    "reason" : "rateLimitExceeded"
  } ],
  "message" : "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the translate.googleapis.com. We recommend that most server applications use service accounts instead. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.",
  "status" : "PERMISSION_DENIED"

我的 pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>seller</groupId>
    <artifactId>home.digest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>home.digest Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://maven.apache.org</url>
    <repositories>
        <repository>
            <id>prime-repo</id>
            <name>Prime Repo</name>
            <url>http://repository.primefaces.org</url>
        </repository>
    </repositories>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.10</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>6.2</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.logging</groupId>
            <artifactId>jboss-logging</artifactId>
            <version>3.0.1.GA</version>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.1-api -->
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.2.Final</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.6.Final</version>
             <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <version>2.0.SP1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.as</groupId>
            <artifactId>jboss-as-web</artifactId>
            <version>7.1.1.Final</version>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.ejb/jboss-ejb-api_3.2_spec -->
        <dependency>
            <groupId>org.jboss.spec.javax.ejb</groupId>
            <artifactId>jboss-ejb-api_3.2_spec</artifactId>
            <version>1.0.2.Final</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.cloud/google-cloud-translate -->
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>google-cloud-translate</artifactId>
            <version>1.79.0</version>
        </dependency>
        <dependency>
            <!-- jsoup HTML parser library @ https://jsoup.org/ -->
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>home.digest</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven 
                defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

我的代码:

com.google.cloud.translate.Translate translate = TranslateOptions.getDefaultInstance().getService();
        String translatexText = "EMPTY";
        try {
            Translation translation = translate.translate("Guten Tag", Translate.TranslateOption.sourceLanguage("de"),
                    Translate.TranslateOption.targetLanguage("bg"),
                    // Use "base" for standard edition, "nmt" for the
                    // premium model.
                    Translate.TranslateOption.model("nmt"));

            translatexText = translation.getTranslatedText();
        } catch (Exception e) {
            Logger.getLogger(TestServlet.class).error(e.getMessage(), e);
        }

        System.out.println(translatexText);

【问题讨论】:

    标签: java authentication google-cloud-platform google-translate google-cloud-iam


    【解决方案1】:

    此错误消息是由您在设置 Cloud SDK 时使用用户凭据引起的。通常这是使用命令gcloud auth login 完成的。

    有几种方法可以解决这个问题。每种方法都使用一个服务帐户。

    方法一:

    创建服务帐号并设置 Cloud SDK 以使用该服务帐号。

    示例命令:

    gcloud auth activate-service-account test@development-123456.iam.gserviceaccount.com --key-file=/fullpath/service-account.json
    

    方法二:

    将环境变量 GOOGLE_APPLICATION_CREDENTIALS 设置为指向您的服务帐号 JSON 文件。

    set GOOGLE_APPLICATION_CREDENTIALS=/fullpath/service-account.json

    方法三:

    在创建 Java SDK 客户端时指定服务帐户。

    此链接显示了指定服务帐户文件的示例:

    Setting Up Authentication for Server to Server Production Applications

    【讨论】:

    • 想要按照步骤 3 进行操作,但想要登录 GCP sql 实例?怎么办?
    • @IndrajeetGour 创建一个包含详细信息的新问题。
    • 谢谢!无论如何,方法#1 对我不起作用,方法#2 对我有用。
    • @JohnHanley 这样做意味着对于某些谷歌 API 端点(例如 translate.googleapis.comhttps://www.googleapis.com/auth/drive,我在尝试调用时得到与 OP 相同的响应)是不可能的使用它们而不通过key.json 使用服务帐户进行身份验证? (感谢您分享有关此问题和其他问题的知识 - 非常有帮助!即 stackoverflow.com/questions/53472429/…
    • @DBCerigo - 服务帐户派生自存储在key.json 中的私钥。我不使用翻译或驱动 API,因此无法发表评论。对于云,大多数应用程序应该使用服务帐户而不是 Google 帐户(gmail、gsuite、云身份等)。对于高级用法,用户帐户可以模拟具有正确角色和设置的服务帐户。如果您的应用在 Google 服务(Compute Engine、App Engine、Cloud Run、Functions...)中运行,那么您可以向元数据服务器询问凭据,从而绕过对 key.json 的需求。
    【解决方案2】:

    一般来说,从 GCP 运行代码并使用服务帐号是最佳做法。不导出服务帐户密钥也是一种很好的安全做法。所以问题已经回答了。

    在这个额外的答案中,我想分享我的见解,问题标题中的错误消息发生在哪里,发生了什么,以及如何设置您的机器以在不导出服务帐户密钥的情况下进行一些本地开发(不过,导出短来自测试项目中一次性服务帐户的实时服务帐户密钥对于测试内容可能既简单又更好)。

    我想以sheets API 为例。表格 API 至少需要 oauth2 范围 https://www.googleapis.com/auth/spreadsheets.readonly 从电子表格中读取。

    我的示例 Golang 程序是

    package main
     
    import (
        "context"
        "fmt"
        "log"
     
        "google.golang.org/api/option"
        "google.golang.org/api/sheets/v4"
    )
     
    func main() {
        ctx := context.Background()
     
        // using default authentication, whatever the environment provides. See https://cloud.google.com/docs/authentication#environment-service-accounts
        srv, err := sheets.NewService(ctx, option.WithScopes(sheets.SpreadsheetsReadonlyScope))
        if err != nil {
            log.Fatalf("Unable to retrieve Sheets client: %v", err)
        }
     
        // A sample spreadsheet:
        // https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
        spreadsheetId := "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
        readRange := "Class Data!A2:E"
        resp, err := srv.Spreadsheets.Values.Get(spreadsheetId, readRange).Do()
        if err != nil {
            log.Fatalf("Unable to retrieve data from sheet: %v", err)
        }
     
        if len(resp.Values) == 0 {
            fmt.Println("No data found.")
        } else {
            fmt.Println("got some results, ...")
        }
    }
    

    我试图从 Google Cloud Shell(GCP 内置网络云终端)中读取电子表格,而将我带到这里的完整错误消息是:

    googleapi: Error 403: Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the sheets.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/., accessNotConfigured
    

    要通过 Google Cloud SDK 使用您的用户帐户访问工作表,我们需要具有相应 oauth 范围的应用程序默认凭据。

    $ gcloud auth application-default login --scopes=https://www.googleapis.com/auth/spreadsheets.readonly,openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform
    

    我将范围设置为 default ones 并添加了电子表格范围。在遵循基于浏览器的身份验证流程时,我被要求允许

    Google Auth Library to:
    
    View and manage your data across Google Cloud Platform services
    
    View your Google Spreadsheets
    

    在我的电脑上,代码现在可以运行了。

    默认情况下,当获取应用程序默认凭据而不指定--scopes 时,您将只有View and manage your data across Google Cloud Platform services 的权限,并且不允许与工作表API 对话。在不指定 --scopes 的情况下,与工作表 API 对话时,预期的错误消息是 googleapi: Error 403: Request had insufficient authentication scopes.。这确实是我在电脑上运行代码时可以观察到的。

    然而,在 Google Cloud Shell 上运行代码时,我从问题的标题中收到错误消息,即Your application has authenticated using end user credentials ...。同样运行 gcloud auth application-default login 和相应的 --scopes 不会改变 Google Cloud Shell 上的这种行为。这是因为在 Google Cloud Shell 上运行代码时,不使用应用程序默认凭据。

    我写了一些小调试代码来揭示Google API oauth2 library is finding its default credentials

    package main
     
    import (
        "context"
        "fmt"
     
        "golang.org/x/oauth2/google"
    )
     
    func main() {
        ctx := context.Background()
        creds, err := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/spreadsheets.readonly")
        if err != nil {
            panic(fmt.Sprintf("google.FindDefaultCredentials(): %v", err))
        }
        fmt.Printf("creds uses credentials file? %#v\n", creds.JSON != nil)
        t, err := creds.TokenSource.Token()
        if err != nil {
            panic(fmt.Sprintf("Token(): %v", err))
        }
        fmt.Printf("token: %#v\n", t)
    }
    

    在我的电脑上,运行后

    $ gcloud auth application-default login
    

    我的调试代码打印:

    creds uses credentials file? true
    token: &oauth2.Token{AccessToken:"...", ..., raw:map[string]interface {}{"access_token":"...", "scope":"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/accounts.reauth https://www.googleapis.com/auth/cloud-platform openid", "token_type":"Bearer"}}
    

    在我的电脑上,运行后

    $ gcloud auth application-default login --scopes=https://www.googleapis.com/auth/spreadsheets.readonly,openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform
    

    我的调试代码打印:

    creds uses credentials file? true
    token: &oauth2.Token{AccessToken:"...", ..., raw:map[string]interface {}{"access_token":"...", "scope":"https://www.googleapis.com/auth/spreadsheets.readonly https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/accounts.reauth openid https://www.googleapis.com/auth/userinfo.email", "token_type":"Bearer"}}
    

    我们现在包含了https://www.googleapis.com/auth/spreadsheets.readonly 范围。

    无论我尝试什么,在 Google Cloud Shell 上运行我的调试代码时,我总是得到

    creds uses credentials file? false
    token: &oauth2.Token{AccessToken:"...", ..., raw:map[string]interface {}{"oauth2.google.serviceAccount":"default", "oauth2.google.tokenSource":"compute-metadata"}}
    

    这意味着 Google Cloud Shell 上不使用应用程序默认凭据。这是因为 Google Cloud Shell 上的应用程序默认凭据未写入默认位置 $HOME/.config/gcloud/application_default_credentials.jsongoogle.FindDefaultCredentials() 因此尝试通过 GCP 元数据服务器进行身份验证。

    【讨论】:

      【解决方案3】:

      @John Hanley 的回答很有见地,所以我只想添加另一个可以遇到此错误或类似错误的实例(在我的情况下是这样):Firebase CLI。我没有登录任何帐户。执行firebase login 并选择我想要的 Google 帐户就足以消除错误

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-27
        • 2022-01-27
        • 2020-07-13
        • 2021-10-15
        • 2019-12-31
        相关资源
        最近更新 更多