Spring GCP 存储 - 我们计算的请求签名与您提供的签名不匹配。检查您的 Google 密钥和签名方法

问题描述 投票:0回答:1

我正在将文件上传到 Google Storage 并尝试生成公共链接:

    Storage.BlobWriteOption precondition;
    Blob blob = storage.get(bucketName, name);
    if (blob == null) {
      precondition = Storage.BlobWriteOption.doesNotExist();
    } else {
      precondition = Storage.BlobWriteOption.generationMatch(blob.getGeneration());
    }

    Blob rs = storage.createFrom(BlobInfo.newBuilder(BlobId.of(bucket.getName(), name)).setContentType("application/octet-stream").build(), inputStream, precondition)

    BlobId blobId = rs.getBlobId();
    URL url =
        storage.signUrl(
            BlobInfo.newBuilder(blobId).build(),
            Duration.ofHours(1).toMillis() - 10000,
            TimeUnit.MILLISECONDS,
            Storage.SignUrlOption.httpMethod(HttpMethod.GET),
            Storage.SignUrlOption.withExtHeaders(Map.of("Content-Type", "application/octet-stream")));

我有一个类似

https://storage.googleapis.com/vocab-be-local/vocab.zip?GoogleAccessId=my-account@vocab-local.iam.gserviceaccount.com&Expires=1715751607&Signature=Vz2G8qr%2Fy%2BN8vR7yiPIQlnpzyaz2s5qGLcTL4nE7w3B6gXprtODGzz8Dk49v%2BMbrCg6IcHi1ZGN9ZNYVZyM7VW3RUZ6QOOIPbA62AEzM1T9UUYIaxGYkE7xGCFC3a6LBv%2FCnN6F28eau3wdGpldwC5iwccrwSYIpozK43Whklk%2B%2BHekjq%2BgnI%2F%2FnuqBWa1Z9P8RBejlz9ajnaxriaFOUyvlBLQBShnxM4q%2BdAJWeFlocMZIk7ZSiGuh1gTi2HTecxzod9bIRu%2FmhecpMlmPP2PvQSW0dqxMuonfxxxj3Eby7hRXOy6wNKSWU4DqZkUJm29AHOyO1vqgc2KaQevbWdw%3D%3D

的链接

当我通过 Postman 或curl 使用此链接时,我得到:

<?xml version='1.0' encoding='UTF-8'?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>Access denied.</Message>
    <Details>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Details>
    <StringToSign>GET

application/octet-stream
1715751607
/vocab-be-local/vocab.zip</StringToSign>
</Error>

尝试使用 Webflux WebClient,仍然遇到相同的错误:

WebClient.create()
    .get().uri(d.getImageUrl())
    .header("Content-Type", "application/octet-stream")
    .retrieve()
    .toEntity(byte[].class)
    .block()

我已经阅读了很多与此问题相关的问题/答案。他们建议我在上传/签名时需要添加内容类型。我做到了,但没有运气。请帮忙!!

更新:

Spring boot 3.2.0
Spring cloud 2023.0.1
Spring cloud GCP 5.1.2

我的pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-storage</artifactId>
</dependency>

我的应用程序.yml:

spring:
  cloud:
    gcp:
      credentials:
        location: classpath:google/sa/vocab-storage-local.json
      storage:
        project-id: my-project

我的服务帐户 JSON:

{
  "type": "service_account",
  "project_id": "my-project",
  "private_key_id": "***********",
  "private_key": "-----BEGIN PRIVATE KEY-----\n********\n-----END PRIVATE KEY-----\n",
  "client_email": "******@******.iam.gserviceaccount.com",
  "client_id": "*******************",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/********",
  "universe_domain": "googleapis.com"
}
java google-cloud-storage spring-cloud-gcp
1个回答
0
投票

已修复:

  storage.signUrl(BlobInfo.newBuilder(blob.getBlobId())
-> Add this line    .setContentType("application/octet-stream")
                    .build(),
                  32515291723000L - currentTimeMillis(),
                  TimeUnit.MILLISECONDS,
                  Storage.SignUrlOption.httpMethod(HttpMethod.GET),
-> Fix this line  Storage.SignUrlOption.withContentType()))
© www.soinside.com 2019 - 2024. All rights reserved.