Как загрузить объект из Google Cloud Storage через Java Admin SDK?

В настоящее время я разрабатываю Java-приложение, которое использует Admin SDK для хранения и получения данных из Google Firestore, но я также хотел распространить это использование и на Google Cloud Storage. Когда дело доходит до Firestore, очень четко указано, что доступ через Admin SDK игнорирует все правила безопасности Firebase, и в результате создания приложения Firebase с учетными данными моей учетной записи службы достаточно, чтобы предоставить доступ ко всем операциям (если я правильно понял это). до сих пор).

Однако когда я пытаюсь загрузить файлы .png, которые я загрузил в облачное хранилище, через Admin SDK, я получаю следующую ошибку.

{
  "code" : 401,
  "errors" : [ {
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission 'storage.objects.get' denied on resource (or it may not exist).",
    "reason" : "required"
  } ],
  "message" : "Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission 'storage.objects.get' denied on resource (or it may not exist)."
}

Вот код, который выдает эту ошибку.

public void downloadImage() {
        
        firebase.initializeFirebase();

        Storage storage = StorageOptions.newBuilder()
                                  .setProjectId(MY_FIREBASE_ID).build()
                                  .getService();
        
        Blob blob = storage.get(BlobId.of(STORAGE_ID, OBJECT_NAME));
        blob.downloadTo(Paths.get(PATH));
    }

Роли учетной записи службы включают в себя администратора, администратора хранилища, средства просмотра объектов хранилища, администратора объекта хранилища и некоторые другие. Приложение Firebase инициализируется методом firebase.initializeFirebase() с учетными данными, которые я упомянул выше.

Я думал, что Admin SDK предоставляет полный доступ к приложению Firebase только с соответствующими ролями IAM. В поисках этой ошибки я обнаружил несколько способов корректной аутентификации и разрешения доступа, но все они использовали Firebase CLI. Но как я могу сделать то же самое, используя только Admin SDK и код Java?

Как указано выше, я попытался назначить все роли, связанные с хранилищем, моей учетной записи службы и создал новый файл JSON с моими учетными данными. Затем я использовал приведенный выше код, чтобы попытаться загрузить изображение из Cloud Storage, но безуспешно. Я даже дошел до того, что разрешил кому угодно публичный доступ к облачному хранилищу. Я зашел в правила Cloud Storage и включил доступ на чтение и запись без каких-либо условий. Но прогресса по-прежнему нет. Я искал этот конкретный вопрос, который задаю прямо сейчас, но результаты мне не помогли. Возможно я что-то пропустил, в таком случае прошу прощения.

Это сообщение об ошибке не имеет ничего общего с правилами безопасности Firebase. Речь идет о ролях и разрешениях GCP IAM, которые представляют собой совершенно другой тип системы разрешений, применимый только к учетным записям служб.

Doug Stevenson 16.06.2024 14:39

@DougStevenson Извините, если я недостаточно ясно выразился, но я понимаю, что это не связано с правилами безопасности Firebase. В своем вопросе я даже упомянул, что Admin SDK полностью игнорирует правила. Я добавил достаточные разрешения для своей учетной записи службы через консоль IAM, но все еще не могу заставить ее работать.

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

Ответы 1

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

Ошибка говорит о том, что вы не используете какие-либо учетные данные в запросе. Если вы хотите авторизовать запрос с помощью переменных env, ознакомьтесь с документацией чтобы служба хранения могла обнаружить учетные данные (за пределами экземпляра облака Google)

ОБЯЗАТЕЛЬНО добавьте необходимые разрешения для своей учетной записи службы и сегмента.

  1. Для учетной записи службы: перейдите в консоль Google Cloud > IAM и администратор > найдите свою учетную запись службы, которую вы хотите использовать > Изменить принципала > Добавить роль > выберите желаемую роль (я выбрал администратора хранилища, чтобы эта учетная запись службы имела полный доступ к корзинам и предметы внутри них)
  2. Для сегмента: перейдите в Google Cloud Console > Облачное хранилище > Бакеты > Выберите сегмент > Дополнительные действия (3 точки справа) > Редактировать доступ > Добавить принципала > В поле Принципал добавьте имя/адрес электронной почты своей учетной записи службы и роли. , установите то же, что и для своей учетной записи службы (например, администратора хранилища).

Если вы ранее настроили приложение Firebase и загрузили файл JSON со своими учетными данными, вы можете использовать этот файл JSON для авторизации вашего запроса в Cloud Storage, не настраивая переменные env следующим образом:

InputStream serviceAccount = new FileInputStream("your-path-to-json-credentials");

Storage storage = StorageOptions.newBuilder().setProjectId(PROJECT_ID).setCredentials(GoogleCredentials.fromStream(serviceAccount)).build().getService();

С другой стороны, если у вас нет учетных данных в формате JSON и вам просто нужен доступ к облачному хранилищу, перейдите в Google Cloud Console > IAM и администратор > Учетные записи служб > Выберите свою учетную запись службы > Дополнительные параметры (3 точки на справа) > Управление ключами > Добавить ключ > Создать новый ключ > Формат JSON. Теперь загрузите файл JSON и используйте этот путь, как показано выше в коде.

Теперь, когда вы пытаетесь загрузить, создать или удалить объекты из нужного сегмента, Google знает, что запрос поступает от вашего сервисного аккаунта.

Эй, спасибо за ответ. Можете ли вы быть более конкретным, пожалуйста? Чего достигает export GOOGLE_APPLICATION_CREDENTIALS = "/home/user/Downloads/service‌​-account-file.json"? Кроме того, если под добавлением разрешений к проекту вы подразумеваете создание приложения Firebase с моими учетными данными, то я уже делаю это в методе initializeFirebase(). Приложение Firebase с достаточным разрешением уже существует. Я просто не понимаю, как его использовать для получения данных из Cloud Storage.

Phoebus21 16.06.2024 20:27
GOOGLE_APPLICATION_CREDENTIALS — это одно из мест, где службы Google будут пытаться загрузить учетные данные, если они не добавлены явно. newBuilder().setCredentials(...) Использование переменной env позволяет вашему коду работать без изменений в среде Google или на вашем ноутбуке, поскольку учетные данные будут загружаться из разных мест в зависимости от того, где находится код. бежит.
qtxo 18.06.2024 05:58

Если вы инициализируете Firebase с некоторыми учетными данными, вы также можете их использовать StorageOptions.newBuilder().setCredentials(fbCredentials)...‌​build()

qtxo 18.06.2024 06:00

Боже мой... Как я мог быть таким глупым. Я не осознавал, что .setCredentials — это все, что мне нужно для подтверждения моего запроса. Я использовал .setCredentials при настройке приложения Firebase, но мне никогда не приходило в голову, что настройка хранилища также требует этого, потому что он не показан ни в одном из руководств по коду.... Большое спасибо за вашу помощь! 🙏

Phoebus21 18.06.2024 13:53

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