2

我正在使用谷歌云功能,无法让默认服务帐户正常工作。如果我传入 JSON 凭据文件,服务帐户可以正常工作。但是,如果我将相同的服务帐户设置为该功能的默认帐户,则会出现错误。此外,如果我在本地运行并使用也设置为同一帐户的默认服务帐户,则代码可以正常工作。当函数在云中运行时我得到的错误是:

该用户不属于 G Suite 客户。

这通常意味着服务帐户未获得域范围委派的授权,或者没有指定 G-Suite 用户进行模拟。来自云控制台的使用指标表明正确的服务帐户用于运行该功能。此帐户也按预期出现在函数的运行配置部分中。我同时使用 G-suite 功能(保险柜)和谷歌云功能(存储)。该服务帐户是为域范围的委派设置的,我正在设置一个 Gsuite 用户来模拟。

总之,相同的服务帐户和用户:

  • 如果我传入 JSON 凭据文件,则可以在云或桌面上工作,
  • 无法在云中使用相同的服务帐户设置为默认值,
  • 在我的笔记本电脑上使用与默认服务帐户设置相同的服务帐户。

功能上的运行选项卡显示正确的服务帐户,使用统计数据还表明正在使用正确的服务帐户。我想使用默认服务帐户,因此我不必管理存储和检索凭据。

相关代码如下:

public HttpRequestInitializer buildInitializer() throws Exception {
    if (VaultConfig.isApplicationRunMode())
        return new HttpCredentialsAdapter(buildDefaultCredentials());
    else if (VaultConfig.isServiceRunMode())                    
        return new HttpCredentialsAdapter(buildServiceCredentials());
    else throw new Exception("Request initializer only supports service account or application default");
}

private GoogleCredentials buildServiceCredentials() throws Exception {
    String credentialsPath = VaultConfig.getServiceCredentials();
    logger.info("Credentials path " + credentialsPath);
    InputStream is=GetRequestInitializer.class.getResourceAsStream(credentialsPath);
    if (is == null) {
        throw new FileNotFoundException("Resource not found: " + credentialsPath);
    }
    GoogleCredentials credentials = GoogleCredentials.fromStream(is)
            .createScoped(VaultConfig.getScopes()).createDelegated(VaultConfig.getUserToImpersonate());
    logger.debug("Credentials created.  Scopes " + VaultConfig.getScopes());
    logger.debug(credentials.toString());
    return credentials;
}

private GoogleCredentials buildDefaultCredentials() throws Exception {
    logger.info("Using application default credentials");
            GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
            .createScoped(VaultConfig.getScopes())
            .createDelegated(VaultConfig.getUserToImpersonate());
    logger.debug("Credentials created.  Scopes " + VaultConfig.getScopes());
    logger.debug(credentials.toString());
    return credentials;
}

该错误稍后发生在我实际调用 Vault 服务的代码中,并且服务器返回 400 响应并指示错误。请注意调试语句logger.debug(credentials.toString())。在函数工作的所有情况下,credentials.toString() 返回预期结果,如下所示:

ServiceAccountCredentials{clientId=1111111111222233, clientEmail=myfunction@appspot.gserviceaccount.com, privateKeyId=aaaabb12bgbaaaaaaaaaaa, transportFactoryClassName=com.google.auth.oauth2.OAuth2Utils$DefaultHttpTransportFactory, tokenServerUri=https://oauth2.googleapis.com/token, scopes= [https://www.googleapis.com/auth/devstorage.read_write, https://www.googleapis.com/auth/devstorage.full_control, https://www.googleapis.com/auth/ediscovery], defaultScopes= [],serviceAccountUser=my.user.account@mydomain.com,quotaProjectId=null,lifetime=3600,useJwtAccessWithScope=false}

但是,当使用云中的默认服务帐户时credentials.toString()返回

ComputeEngineCredentials{transportFactoryClassName=com.google.auth.oauth2.OAuth2Utils$DefaultHttpTransportFactory}

在我看来,我的问题是GoogleCredentials.getApplicationDefault()在云上运行时没有返回预期的结果。我在https://cloud.google.com/docs/authentication/production之后设置了服务帐户。

还有什么我需要做的吗?有关可能验证问题所在的其他诊断语句的任何提示?功能上的运行选项卡显示正确的帐户,我正在使用项目的默认帐户。

4

0 回答 0