【问题标题】:ERROR 401 Unauthorized: Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket in spring boot applicationERROR 401 Unauthorized: Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket in spring boot application
【发布时间】:2021-12-29 10:59:48
【问题描述】:

我有一个使用骆驼从对象存储(谷歌云平台)获取数据的 Spring Boot 应用程序。

这是我在 Eclipse 中的代码:

package footballRestAPIs;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

import core.ErrorProcessor;


@Component
public class ListObjFromGCP extends RouteBuilder{
    
    
     @Override
        public void configure() throws Exception {
            
       
            onException(Exception.class).handled(true)
            .process(new ErrorProcessor());
            

            rest("/").produces("application.json") 
            .get("selectPhoto")
            
            .to("direct:selectPhoto");

        from("direct:selectPhoto")
        
          .to("google-storage://sagessapp_test?operation=listObjects")
        
          .log("${body}");
            
            
         
        }

}

这是 application.properties 文件,其中服务帐户密钥的路径是:

spring.cloud.gcp.credentials.location=/Users/User/Downloads/gcp-credentials.json

当我运行 spring boot 应用程序时,我收到以下错误:

Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
GET https://storage.googleapis.com/storage/v1/b/sagessapp_test?projection=full
{
  "code" : 401,
  "errors" : [ {
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket.",
    "reason" : "required"
  } ],
  "message" : "Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket."
}

是否有其他方法可以提供服务帐户密钥的路径,或者存在其他问题。谢谢!

【问题讨论】:

  • 您是否在工作站上运行代码?您是否通过gcloud auth application-default login 进行了身份验证?您是否设置了 GOOGLE_APPLICATION_CREDENTIALS 环境变量?您如何管理运行时环境的身份验证?
  • 您有机会查看我的answer吗?

标签: java spring-boot google-cloud-platform apache-camel cloud-object-storage


【解决方案1】:

TL;DR 创建一个Credentials 实例:

Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("path/to/file")); 

Google Cloud Storage Setup

documentation,除了您已经在使用的方法之外,还有一些方法可以加载凭据*: *请注意,如果未通过属性文件指定凭据,则将使用这些方式

环境变量

您可以设置环境变量GOOGLE_APPLICATION_CREDENTIALS并使用默认实例:

对于 Linux 或 Mac:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/file"

对于 Windows:

set GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\file"

这是加载凭据的最简单方法。

云 SDK

另一种方法是使用 Google Cloud SDK 提供凭据。步骤如下:

  1. 第一个install the Cloud SDK
  2. 然后initialize the Cloud SDK。在第 4 步,选择您正在处理的项目。
  3. 然后你可以运行gcloud auth application-default logincommand。 正如在answer 中发布的那样:

    这将通过网络流获取您的凭据并将它们存储在“应用程序默认凭据的知名位置”。现在,您运行的任何代码/SDK 都将能够自动找到凭据。当您想要在本地测试通常在服务器上运行并使用服务器端凭据文件的代码时,这是一个很好的替代方案。

Connecting to Storage

在我们可以使用 Google Cloud 存储之前,我们必须创建一个服务对象。如果我们已经设置了GOOGLE_APPLICATION_CREDENTIALS 环境变量,我们可以使用默认实例:

Storage storage = StorageOptions.getDefaultInstance().getService();

如果我们不想使用环境变量,我们必须创建一个Credentials 实例并将其传递给Storage 并带有项目名称:

Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("path/to/file"));
// The ID of your GCP project
// String projectId = "your-project-id";
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).setProjectId("your-project-id").build().getService();

Creating a Bucket

桶是存放对象的容器。它们可用于组织和控制数据访问。

创建存储桶需要BucketInfo

Bucket bucket = storage.create(BucketInfo.of("sample-bucket"));

对于这个简单的示例,我们传递一个存储桶名称并接受默认属性。存储桶名称必须是全局唯一的,并且必须遵循some requirements。例如,如果我们选择一个已经使用的名称,create() 将失败。

Reading data

Blob 在创建时被分配一个 BlobId

检索 Blob 的最简单方法是使用 BlobId

Blob blob = storage.get(blobId);
String value = new String(blob.getContent());

我们将 id 传递给 Storage 并获得 Blob 作为回报,getContent() 返回字节。

如果我们没有BlobId,我们可以按名称搜索Bucket:

// The ID of your GCS bucket
// String bucketName = "your-unique-bucket-name";
Page<Blob> blobs = storage.list(bucketName);
for (Blob blob: blobs.getValues()) {
    if (name.equals(blob.getName())) {
        return new String(blob.getContent());
    }
}

Listing Objects

这是列出 Cloud Storage 存储分区中所有对象的函数的代码示例。

import com.google.api.gax.paging.Page;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class ListObjects {
  public static void listObjects(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Page<Blob> blobs = storage.list(bucketName);

    for (Blob blob : blobs.iterateAll()) {
      System.out.println(blob.getName());
    }
  }
}

另见:

【讨论】:

  • 你好@Rogelio Monter,在这段代码中你提供了Page&lt;Blob&gt; blobs = bucket.list();bucket是什么以及如何定义它?谢谢
  • @Jenny Page&lt;Blob&gt; blobs 变量在您创建存储桶时定义,如创建存储桶部分所示。我使用此信息更新了答案,并在最后添加了来自 official documentation 的示例,说明如何列出已创建存储桶的文件。
  • 你还有疑问@Jenny 吗?你有机会测试代码吗?
猜你喜欢
  • 2023-03-16
  • 2022-10-31
  • 2018-08-24
  • 1970-01-01
  • 2021-09-07
  • 2020-11-11
  • 2022-12-09
  • 2020-10-28
  • 1970-01-01
相关资源
最近更新 更多