Spring GCP Storage. Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи. Проверьте свой секретный ключ Google и метод подписи

Я загружаю файл в 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"
}

Это также может быть вызвано тем, что пользователь подписывает неправильную каноническую строку . Убедитесь, что у вас в процентах закодированы следующие зарезервированные символы: ?=!\#$&'()\*+,:;@[]" . Также проверьте это Рекомендации по подписанию URL-адресов.

Roopa M 15.05.2024 09:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
147
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Зафиксированный:

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

Другие вопросы по теме