ERROR 401 Unauthorized: Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket in spring boot application [英] ERROR 401 Unauthorized: Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket in spring boot application

查看:49
本文介绍了ERROR 401 Unauthorized: Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket in spring boot application的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我在 Eclipse 中的代码:

package footballRestAPIs;导入 org.apache.camel.builder.RouteBuilder;导入 org.springframework.stereotype.Component;导入核心.错误处理器;@零件公共类 ListObjFromGCP 扩展 RouteBuilder{@覆盖公共无效配置()抛出异常{onException(Exception.class).handled(true).process(新的错误处理器());rest("/").produces("application.json").get("选择照片").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 应用程序时,我收到以下错误:

引起:com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized获取 https://storage.googleapis.com/storage/v1/b/sagessapp_test?projection=full{代码": 401,错误": [ {域":全球",位置":授权",位置类型":标题",消息":匿名调用者没有 storage.buckets.get 访问 Google Cloud Storage 存储桶的权限.",理由":必填"}],消息":匿名调用者没有 storage.buckets.get 访问 Google Cloud Storage 存储桶的权限."}

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

解决方案

TL;DR 创建一个 Credentials 实例:

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

Google 云存储设置

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

环境变量

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

<块引用>

对于 Linux 或 Mac:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/file";

<块引用>

对于 Windows:

设置 GOOGLE_APPLICATION_CREDENTIALS=C:path	ofile"

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

云 SDK

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

  1. 首先安装 Cloud SDK.
  2. 然后初始化 Cloud SDK.在第 4 步,选择您正在处理的项目.
  3. 然后你可以运行 gcloud auth application-default login 命令.正如此 answer 中所述:<块引用>

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

连接到存储

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

存储存储 = StorageOptions.getDefaultInstance().getService();

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

Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("path/to/file"));//你的 GCP 项目的 ID//String projectId = "your-project-id";存储存储 = StorageOptions.newBuilder().setCredentials(credentials).setProjectId("your-project-id").build().getService();

创建一个

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

创建一个桶需要一个BucketInfo:

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

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

读取数据

Blob 在创建时被分配一个 BlobId.

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

Blob blob = storage.get(blobId);字符串值 = new String(blob.getContent());

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

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

//你的 GCS 存储桶的 ID//String bucketName = "your-unique-bucket-name";页面<Blob>blobs = storage.list(bucketName);for (Blob blob: blobs.getValues()) {if (name.equals(blob.getName())) {返回新字符串(blob.getContent());}}

列出对象

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

import com.google.api.gax.paging.Page;导入 com.google.cloud.storage.Blob;导入 com.google.cloud.storage.Storage;导入 com.google.cloud.storage.StorageOptions;公共类 ListObjects {public static void listObjects(String projectId, String bucketName) {//你的 GCP 项目的 ID//String projectId = "your-project-id";//你的 GCS 存储桶的 ID//String bucketName = "your-unique-bucket-name";存储存储 = StorageOptions.newBuilder().setProjectId(projectId).build().getService();页面<Blob>blobs = storage.list(bucketName);对于(一滴一滴:blobs.iterateAll()){System.out.println(blob.getName());}}}

另见:

I have a spring boot application that is using camel to get data from object storage (google cloud platform).

This my code in 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}");
            
            
         
        }

}

And this is the application.properties file where the path to the service account key is:

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

when I run the spring boot application I get the following error:

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."
}

Is it possible that there is another way to provide the path to the service account key or there is another issue. Thank you!

解决方案

TL;DR Create a Credentials instance:

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

Google Cloud Storage Setup

From the documentation, there are some ways to load the credentials*, besides the one you are already using: *Notice that these ways will be used if credentials aren’t specified through properties file

Environment variable

You can set up the environment variable GOOGLE_APPLICATION_CREDENTIALS and use the default instance:

For Linux or Mac:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/file"

For Windows:

set GOOGLE_APPLICATION_CREDENTIALS="C:path	ofile"

This is the easiest way to load the credentials.

Cloud SDK

Another way is to provide the credentials using Google Cloud SDK. The steps are as follows:

  1. First install the Cloud SDK.
  2. Then initialize the Cloud SDK. At step 4, select the project you are working on.
  3. Then you can run gcloud auth application-default login command. As posted in this answer:

    This obtains your credentials via a web flow and stores them in 'the well-known location for Application Default Credentials'. Now, any code/SDK you run will be able to find the credentials automatically. This is a good stand-in when you want to locally test code which would normally run on a server and use a server-side credentials file.

Connecting to Storage

Before we can use Google Cloud storage, we have to create a service object. If we've already set up the GOOGLE_APPLICATION_CREDENTIALS environment variable, we can use the default instance:

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

If we don't want to use the environment variable, we have to create a Credentials instance and pass it to Storage with the project name:

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

Buckets are containers that hold objects. They can be used to organize and control data access.

Creating a bucket requires a BucketInfo:

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

For this simple example, we pass a bucket name and accept the default properties. Bucket names must be globally unique and also have to follow some requirements. For example, if we choose a name that is already used, create() will fail.

Reading data

Blobs are assigned a BlobId upon creation.

The easiest way to retrieve a Blob is with BlobId:

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

We pass the id to Storage and get the Blob in return, and getContent() returns the bytes.

If we don't have the BlobId, we can search the Bucket by name:

// 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

This is a code sample of a function that list all the objects in a Cloud Storage bucket.

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());
    }
  }
}

See also:

这篇关于ERROR 401 Unauthorized: Anonymous caller does not have storage.buckets.get access to the Google Cloud Storage bucket in spring boot application的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆